@@ -1387,7 +1387,8 @@ Z80::CondCode
1387
1387
Z80InstructionSelector::foldCond (Register CondReg, MachineIRBuilder &MIB,
1388
1388
MachineRegisterInfo &MRI,
1389
1389
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" );
1391
1392
1392
1393
bool OppositeCond = false ;
1393
1394
MachineInstr *CondDef = nullptr ;
@@ -1397,7 +1398,7 @@ Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
1397
1398
CondDef = LookthroughDef;
1398
1399
Register LookthroughReg;
1399
1400
auto &&LookthroughRegPattern =
1400
- m_all_of (m_SpecificType (LLT::scalar ( 1 ) ), m_Reg (LookthroughReg));
1401
+ m_all_of (m_SpecificType (s1 ), m_Reg (LookthroughReg));
1401
1402
if (mi_match (*CondDef, MRI, m_Copy (LookthroughRegPattern)) &&
1402
1403
LookthroughReg.isVirtual ()) {
1403
1404
CondReg = LookthroughReg;
@@ -1407,6 +1408,7 @@ Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
1407
1408
m_GTrunc (m_GXor (m_GAnyExt (LookthroughRegPattern),
1408
1409
m_SpecificICst (1 ))))) {
1409
1410
CondReg = LookthroughReg;
1411
+ PreferredCC = Z80::GetOppositeBranchCondition (PreferredCC);
1410
1412
OppositeCond = !OppositeCond;
1411
1413
continue ;
1412
1414
}
@@ -1439,24 +1441,66 @@ Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
1439
1441
}
1440
1442
1441
1443
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;
1449
1495
}
1450
1496
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)) {
1455
1499
MIB.buildInstr (Z80::CCF);
1456
1500
CC = PreferredCC;
1457
1501
}
1458
1502
1459
- return CC;
1503
+ return OppositeCond ? Z80::GetOppositeBranchCondition (CC) : CC;
1460
1504
}
1461
1505
1462
1506
bool Z80InstructionSelector::selectShift (MachineInstr &I,
0 commit comments