@@ -1387,7 +1387,8 @@ Z80::CondCode
13871387Z80InstructionSelector::foldCond (Register CondReg, MachineIRBuilder &MIB,
13881388 MachineRegisterInfo &MRI,
13891389 Z80::CondCode PreferredCC) const {
1390- assert (MRI.getType (CondReg) == LLT::scalar (1 ) && " Expected s1 condition" );
1390+ const LLT s1 = LLT::scalar (1 ), s8 = LLT::scalar (8 );
1391+ assert (MRI.getType (CondReg) == s1 && " Expected s1 condition" );
13911392
13921393 bool OppositeCond = false ;
13931394 MachineInstr *CondDef = nullptr ;
@@ -1397,7 +1398,7 @@ Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
13971398 CondDef = LookthroughDef;
13981399 Register LookthroughReg;
13991400 auto &&LookthroughRegPattern =
1400- m_all_of (m_SpecificType (LLT::scalar ( 1 ) ), m_Reg (LookthroughReg));
1401+ m_all_of (m_SpecificType (s1 ), m_Reg (LookthroughReg));
14011402 if (mi_match (*CondDef, MRI, m_Copy (LookthroughRegPattern)) &&
14021403 LookthroughReg.isVirtual ()) {
14031404 CondReg = LookthroughReg;
@@ -1407,6 +1408,7 @@ Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
14071408 m_GTrunc (m_GXor (m_GAnyExt (LookthroughRegPattern),
14081409 m_SpecificICst (1 ))))) {
14091410 CondReg = LookthroughReg;
1411+ PreferredCC = Z80::GetOppositeBranchCondition (PreferredCC);
14101412 OppositeCond = !OppositeCond;
14111413 continue ;
14121414 }
@@ -1439,24 +1441,66 @@ Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
14391441 }
14401442
14411443 if (CC == Z80::COND_INVALID) {
1442- // Fallback to bit test
1443- const TargetRegisterClass *CondRC = selectGRegClass (CondReg, MRI);
1444- auto BitI = MIB.buildInstr (Z80::BIT8bg, {}, {int64_t (0 ), CondReg});
1445- if (CondRC != &Z80::G8RegClass)
1446- BitI->getOperand (1 ).setSubReg (Z80::sub_low);
1447- if (RBI.constrainGenericRegister (CondReg, *CondRC, MRI))
1448- CC = Z80::COND_NZ;
1444+ // Fallback to rotate/bit test
1445+ const TargetRegisterClass *CondRC;
1446+ switch (PreferredCC) {
1447+ default :
1448+ break ;
1449+ case Z80::COND_Z:
1450+ case Z80::COND_PO:
1451+ case Z80::COND_P: {
1452+ Register RegA = Z80::A;
1453+ CondRC = selectRRegClass (CondReg, MRI);
1454+ auto CopyI = MIB.buildCopy (RegA, CondReg);
1455+ if (CondRC != &Z80::R8RegClass)
1456+ CopyI->getOperand (1 ).setSubReg (Z80::sub_low);
1457+ MIB.buildInstr (Z80::CPL);
1458+ if (!RBI.constrainGenericRegister (CondReg, *CondRC, MRI))
1459+ return Z80::COND_INVALID;
1460+ CondReg = MIB.buildCopy (s8, RegA).getReg (0 );
1461+ PreferredCC = Z80::GetOppositeBranchCondition (PreferredCC);
1462+ OppositeCond = !OppositeCond;
1463+ }
1464+ }
1465+ switch (PreferredCC) {
1466+ default :
1467+ llvm_unreachable (" already handled" );
1468+ case Z80::COND_INVALID:
1469+ case Z80::COND_NZ:
1470+ case Z80::COND_PE: {
1471+ CondRC = selectGRegClass (CondReg, MRI);
1472+ auto BitI = MIB.buildInstr (Z80::BIT8bg, {}, {int64_t (0 ), CondReg});
1473+ if (CondRC != &Z80::G8RegClass)
1474+ BitI->getOperand (1 ).setSubReg (Z80::sub_low);
1475+ if (!constrainSelectedInstRegOperands (*BitI, TII, TRI, RBI))
1476+ return Z80::COND_INVALID;
1477+ CC = PreferredCC != Z80::COND_PE ? Z80::COND_NZ : Z80::COND_PE;
1478+ break ;
1479+ }
1480+ case Z80::COND_NC:
1481+ case Z80::COND_C:
1482+ case Z80::COND_M: {
1483+ CondRC = selectRRegClass (CondReg, MRI);
1484+ auto RotateI = MIB.buildInstr (Z80::RRC8r, {s1}, {CondReg});
1485+ if (CondRC != &Z80::R8RegClass)
1486+ RotateI->getOperand (1 ).setSubReg (Z80::sub_low);
1487+ if (!constrainSelectedInstRegOperands (*RotateI, TII, TRI, RBI))
1488+ return Z80::COND_INVALID;
1489+ CC = PreferredCC != Z80::COND_M ? Z80::COND_C : Z80::COND_M;
1490+ break ;
1491+ }
1492+ }
1493+ if (!RBI.constrainGenericRegister (CondReg, *CondRC, MRI))
1494+ return Z80::COND_INVALID;
14491495 }
14501496
1451- if (OppositeCond)
1452- CC = Z80::GetOppositeBranchCondition (CC);
1453-
1454- if (CC == Z80::GetOppositeBranchCondition (PreferredCC)) {
1497+ if ((PreferredCC == Z80::COND_NC || PreferredCC == Z80::COND_C) &&
1498+ CC == Z80::GetOppositeBranchCondition (PreferredCC)) {
14551499 MIB.buildInstr (Z80::CCF);
14561500 CC = PreferredCC;
14571501 }
14581502
1459- return CC;
1503+ return OppositeCond ? Z80::GetOppositeBranchCondition (CC) : CC;
14601504}
14611505
14621506bool Z80InstructionSelector::selectShift (MachineInstr &I,
0 commit comments