@@ -79,10 +79,17 @@ class Z80InstructionSelector : public InstructionSelector {
7979 Z80::CondCode foldSetCC (MachineInstr &I, MachineIRBuilder &MIB,
8080 MachineRegisterInfo &MRI) const ;
8181 Z80::CondCode foldCond (Register CondReg, MachineIRBuilder &MIB,
82- MachineRegisterInfo &MRI) const ;
82+ MachineRegisterInfo &MRI,
83+ Z80::CondCode PreferredCC = Z80::COND_INVALID) const ;
8384 bool selectShift (MachineInstr &I, MachineRegisterInfo &MRI) const ;
8485 bool selectFunnelShift (MachineInstr &I, MachineRegisterInfo &MRI) const ;
85- bool selectSetCond (MachineInstr &I, MachineRegisterInfo &MRI) const ;
86+ bool selectSetCond (unsigned ExtOpc, Register DstReg, Register CondReg,
87+ MachineInstr &I, MachineRegisterInfo &MRI) const ;
88+ bool selectSetCond (unsigned ExtOpc, MachineInstr &I,
89+ MachineRegisterInfo &MRI) const {
90+ Register CondReg = I.getOperand (I.getNumExplicitDefs () - 1 ).getReg ();
91+ return selectSetCond (ExtOpc, CondReg, CondReg, I, MRI);
92+ }
8693
8794 bool selectSelect (MachineInstr &I, MachineRegisterInfo &MRI) const ;
8895 bool selectBrCond (MachineInstr &I, MachineRegisterInfo &MRI) const ;
@@ -298,7 +305,7 @@ bool Z80InstructionSelector::select(MachineInstr &I) const {
298305 case TargetOpcode::INLINEASM:
299306 return selectInlineAsm (I, MRI);
300307 case Z80::SetCC:
301- return selectSetCond (I, MRI);
308+ return selectSetCond (TargetOpcode::G_ZEXT, I, MRI);
302309 }
303310 return true ;
304311 }
@@ -361,7 +368,7 @@ bool Z80InstructionSelector::select(MachineInstr &I) const {
361368 case TargetOpcode::G_SSUBO:
362369 case TargetOpcode::G_SSUBE:
363370 case TargetOpcode::G_ICMP:
364- return selectSetCond (I, MRI);
371+ return selectSetCond (TargetOpcode::G_ANYEXT, I, MRI);
365372 case TargetOpcode::G_BRCOND:
366373 return selectBrCond (I, MRI);
367374 case TargetOpcode::G_BRINDIRECT:
@@ -443,16 +450,18 @@ bool Z80InstructionSelector::selectSExt(MachineInstr &I,
443450 MachineRegisterInfo &MRI) const {
444451 assert (I.getOpcode () == TargetOpcode::G_SEXT && " unexpected instruction" );
445452
446- const Register DstReg = I.getOperand (0 ).getReg ();
447- const Register SrcReg = I.getOperand (1 ).getReg ();
453+ Register DstReg = I.getOperand (0 ).getReg ();
454+ Register SrcReg = I.getOperand (1 ).getReg ();
448455
449- const LLT DstTy = MRI.getType (DstReg);
450- const LLT SrcTy = MRI.getType (SrcReg);
456+ LLT DstTy = MRI.getType (DstReg);
457+ LLT SrcTy = MRI.getType (SrcReg);
451458
452459 if (SrcTy != LLT::scalar (1 ))
453460 return false ;
454461
455- MachineIRBuilder MIB (I);
462+ if (MRI.hasOneUse (SrcReg) &&
463+ selectSetCond (I.getOpcode (), DstReg, SrcReg, I, MRI))
464+ return true ;
456465
457466 unsigned FillOpc;
458467 Register FillReg;
@@ -477,6 +486,7 @@ bool Z80InstructionSelector::selectSExt(MachineInstr &I,
477486 return false ;
478487 }
479488
489+ MachineIRBuilder MIB (I);
480490 auto Rotate = MIB.buildInstr (Z80::RRC8r, {LLT::scalar (8 )}, {SrcReg});
481491 if (!constrainSelectedInstRegOperands (*Rotate, TII, TRI, RBI))
482492 return false ;
@@ -504,8 +514,11 @@ bool Z80InstructionSelector::selectZExt(MachineInstr &I,
504514 if (MRI.getType (SrcReg) != LLT::scalar (1 ))
505515 return false ;
506516
507- MachineIRBuilder MIB (I);
517+ if (MRI.hasOneUse (SrcReg) &&
518+ selectSetCond (I.getOpcode (), DstReg, SrcReg, I, MRI))
519+ return true ;
508520
521+ MachineIRBuilder MIB (I);
509522 auto CopyToA = MIB.buildCopy (Z80::A, SrcReg);
510523 if (!constrainSelectedInstRegOperands (*CopyToA, TII, TRI, RBI))
511524 return false ;
@@ -527,11 +540,16 @@ bool Z80InstructionSelector::selectAnyExt(MachineInstr &I,
527540 MachineRegisterInfo &MRI) const {
528541 assert (I.getOpcode () == TargetOpcode::G_ANYEXT && " unexpected instruction" );
529542
543+ const Register SrcReg = I.getOperand (1 ).getReg ();
530544 const Register DstReg = I.getOperand (0 ).getReg ();
545+
546+ if (MRI.getType (SrcReg) == LLT::scalar (1 ) && MRI.hasOneUse (SrcReg) &&
547+ selectSetCond (I.getOpcode (), DstReg, SrcReg, I, MRI))
548+ return true ;
549+
531550 const TargetRegisterClass *DstRC = getRegClass (DstReg, MRI);
532551 const unsigned DstSize = RBI.getSizeInBits (DstReg, MRI, TRI);
533552
534- const Register SrcReg = I.getOperand (1 ).getReg ();
535553 const TargetRegisterClass *SrcRC = getRegClass (SrcReg, MRI);
536554 unsigned SrcSize = RBI.getSizeInBits (SrcReg, MRI, TRI);
537555
@@ -1365,9 +1383,10 @@ Z80InstructionSelector::foldSetCC(MachineInstr &I, MachineIRBuilder &MIB,
13651383 return Z80::CondCode (I.getOperand (1 ).getImm ());
13661384}
13671385
1368- Z80::CondCode Z80InstructionSelector::foldCond (Register CondReg,
1369- MachineIRBuilder &MIB,
1370- MachineRegisterInfo &MRI) const {
1386+ Z80::CondCode
1387+ Z80InstructionSelector::foldCond (Register CondReg, MachineIRBuilder &MIB,
1388+ MachineRegisterInfo &MRI,
1389+ Z80::CondCode PreferredCC) const {
13711390 assert (MRI.getType (CondReg) == LLT::scalar (1 ) && " Expected s1 condition" );
13721391
13731392 bool OppositeCond = false ;
@@ -1396,6 +1415,7 @@ Z80::CondCode Z80InstructionSelector::foldCond(Register CondReg,
13961415
13971416 Z80::CondCode CC = Z80::COND_INVALID;
13981417 if (CondDef) {
1418+ // TODO: prefer PreferredCC
13991419 switch (CondDef->getOpcode ()) {
14001420 case TargetOpcode::G_ICMP:
14011421 CC = foldCompare (*CondDef, MIB, MRI);
@@ -1431,6 +1451,11 @@ Z80::CondCode Z80InstructionSelector::foldCond(Register CondReg,
14311451 if (OppositeCond)
14321452 CC = Z80::GetOppositeBranchCondition (CC);
14331453
1454+ if (CC == Z80::GetOppositeBranchCondition (PreferredCC)) {
1455+ MIB.buildInstr (Z80::CCF);
1456+ CC = PreferredCC;
1457+ }
1458+
14341459 return CC;
14351460}
14361461
@@ -1531,27 +1556,97 @@ bool Z80InstructionSelector::selectFunnelShift(MachineInstr &I,
15311556 return true ;
15321557}
15331558
1534- bool Z80InstructionSelector::selectSetCond (MachineInstr &I,
1559+ bool Z80InstructionSelector::selectSetCond (unsigned ExtOpc, Register DstReg,
1560+ Register CondReg, MachineInstr &I,
15351561 MachineRegisterInfo &MRI) const {
1536- Register CondReg = I.getOperand (I.getNumExplicitDefs () - 1 ).getReg ();
1537- assert (MRI.getType (CondReg) == LLT::scalar (1 ) && " Expected s1 condition" );
1562+ LLT DstTy = MRI.getType (DstReg);
1563+
1564+ unsigned SetOpc, SelectOpc, IncOpc, FillOpc;
1565+ Register FillReg;
1566+ const TargetRegisterClass *DstRC;
1567+ switch (DstTy.getSizeInBits ()) {
1568+ case 1 :
1569+ case 8 :
1570+ SetOpc = Z80::LD8ri;
1571+ SelectOpc = Z80::Select8;
1572+ IncOpc = Z80::INC8r;
1573+ FillOpc = Z80::SBC8ar;
1574+ FillReg = Z80::A;
1575+ DstRC = &Z80::R8RegClass;
1576+ break ;
1577+ case 16 :
1578+ SetOpc = Z80::LD16ri;
1579+ SelectOpc = Z80::Select16;
1580+ IncOpc = Z80::INC16r;
1581+ FillOpc = Z80::SBC16aa;
1582+ FillReg = Z80::HL;
1583+ DstRC = &Z80::R16RegClass;
1584+ break ;
1585+ case 24 :
1586+ if (!STI.is24Bit ())
1587+ return false ;
1588+ SetOpc = Z80::LD24ri;
1589+ SelectOpc = Z80::Select24;
1590+ IncOpc = Z80::INC24r;
1591+ FillOpc = Z80::SBC24aa;
1592+ FillReg = Z80::UHL;
1593+ DstRC = &Z80::R24RegClass;
1594+ break ;
1595+ default :
1596+ return false ;
1597+ }
15381598
15391599 MachineIRBuilder MIB (I);
1540- Z80::CondCode CC = foldCond (CondReg, MIB, MRI);
1600+ Z80::CondCode DirectCC =
1601+ ExtOpc == TargetOpcode::G_ZEXT ? Z80::COND_NC : Z80::COND_C;
1602+ Z80::CondCode CC = foldCond (CondReg, MIB, MRI, DirectCC);
15411603 if (CC == Z80::COND_INVALID)
15421604 return false ;
15431605
1544- if (MRI.reg_empty (CondReg))
1606+ if (MRI.reg_empty (DstReg)) {
1607+ I.eraseFromParent ();
15451608 return true ;
1609+ }
1610+
1611+ if (CC != DirectCC) {
1612+ auto TrueI = MIB.buildInstr (
1613+ SetOpc, {DstTy}, {int64_t (ExtOpc == TargetOpcode::G_ZEXT ? 1 : -1 )});
1614+ auto FalseI = MIB.buildInstr (SetOpc, {DstTy}, {int64_t (0 )});
1615+ auto SelectI =
1616+ MIB.buildInstr (SelectOpc, {DstReg}, {TrueI, FalseI, int64_t (CC)});
1617+ if (!constrainSelectedInstRegOperands (*FalseI, TII, TRI, RBI) ||
1618+ !constrainSelectedInstRegOperands (*TrueI, TII, TRI, RBI) ||
1619+ !constrainSelectedInstRegOperands (*SelectI, TII, TRI, RBI))
1620+ return false ;
1621+ } else {
1622+ Register UndefReg = Z80::NoRegister;
1623+ if (FillOpc == Z80::SBC8ar) {
1624+ auto CopyUndefI = MIB.buildCopy (DstTy, FillReg);
1625+ CopyUndefI->findRegisterUseOperand (FillReg)->setIsUndef ();
1626+ UndefReg = CopyUndefI.getReg (0 );
1627+ if (!RBI.constrainGenericRegister (UndefReg, *DstRC, MRI))
1628+ return false ;
1629+ }
1630+ auto FillI = MIB.buildInstr (FillOpc);
1631+ FillI->findRegisterUseOperand (FillReg)->setIsUndef ();
1632+ if (UndefReg)
1633+ FillI.addUse (UndefReg, RegState::Undef);
1634+ if (!constrainSelectedInstRegOperands (*FillI, TII, TRI, RBI))
1635+ return false ;
1636+ if (ExtOpc == TargetOpcode::G_ZEXT) {
1637+ Register TmpReg = MIB.buildCopy (DstTy, FillReg).getReg (0 );
1638+ if (!RBI.constrainGenericRegister (TmpReg, *DstRC, MRI))
1639+ return false ;
1640+ auto IncI = MIB.buildInstr (IncOpc, {DstReg}, {TmpReg});
1641+ if (!constrainSelectedInstRegOperands (*IncI, TII, TRI, RBI))
1642+ return false ;
1643+ } else if (!RBI.constrainGenericRegister (
1644+ MIB.buildCopy (DstReg, FillReg).getReg (0 ), *DstRC, MRI))
1645+ return false ;
1646+ }
15461647
1547- auto TrueI = MIB.buildInstr (Z80::LD8ri, {LLT::scalar (8 )}, {int64_t (1 )});
1548- auto FalseI = MIB.buildInstr (Z80::LD8ri, {LLT::scalar (8 )}, {int64_t (0 )});
1549- auto SelectI =
1550- MIB.buildInstr (Z80::Select8, {CondReg}, {TrueI, FalseI, int64_t (CC)});
15511648 I.eraseFromParent ();
1552- return constrainSelectedInstRegOperands (*FalseI, TII, TRI, RBI) &&
1553- constrainSelectedInstRegOperands (*TrueI, TII, TRI, RBI) &&
1554- constrainSelectedInstRegOperands (*SelectI, TII, TRI, RBI);
1649+ return true ;
15551650}
15561651
15571652bool Z80InstructionSelector::selectSelect (MachineInstr &I,
0 commit comments