@@ -1509,16 +1509,34 @@ bool Z80InstructionSelector::selectFunnelShift(MachineInstr &I,
15091509 auto Amt = getConstantVRegValWithLookThrough (I.getOperand (3 ).getReg (), MRI);
15101510 LLT Ty = MRI.getType (DstReg);
15111511 assert (Ty == LLT::scalar (8 ) && " Illegal type" );
1512- assert (Amt && (Amt->Value == 1 || Amt->Value == 7 ) && " Illegal shift amount" );
1513- IsLeft ^= Amt->Value == 7 ;
1512+ unsigned TySize = Ty.getSizeInBits ();
1513+ unsigned Count = Amt->Value .getZExtValue ();
1514+ if (!IsLeft)
1515+ Count = TySize - Count;
1516+ IsLeft = Count < TySize / 2 ;
1517+ if (IsLeft)
1518+ std::swap (HiReg, LoReg);
1519+ else
1520+ Count = TySize - Count;
1521+ assert (Count < TySize / 2 && " Unexpected shift amount" );
15141522 MachineIRBuilder MIB (I);
1515- auto ShiftI = MIB.buildInstr (IsLeft ? Z80::RLC8r : Z80::RRC8r, {Ty},
1516- {IsLeft ? LoReg : HiReg});
1517- auto RotateI = MIB.buildInstr (IsLeft ? Z80::RL8r : Z80::RR8r, {DstReg},
1518- {IsLeft ? HiReg : LoReg});
1523+ while (Count--) {
1524+ auto ShiftI = MIB.buildInstr (
1525+ IsLeft ? Z80::RLC8r : Z80::RRC8r,
1526+ {Count || HiReg != LoReg ? DstOp{Ty} : DstOp{DstReg}}, {HiReg});
1527+ MachineInstrBuilder RotateI;
1528+ if (HiReg != LoReg)
1529+ RotateI = MIB.buildInstr (IsLeft ? Z80::RL8r : Z80::RR8r,
1530+ {Count ? DstOp{Ty} : DstOp{DstReg}}, {LoReg});
1531+ if (!constrainSelectedInstRegOperands (*ShiftI, TII, TRI, RBI) ||
1532+ (HiReg != LoReg &&
1533+ !constrainSelectedInstRegOperands (*RotateI, TII, TRI, RBI)))
1534+ return false ;
1535+ LoReg = (HiReg != LoReg ? &RotateI : &ShiftI)->getReg (0 );
1536+ HiReg = ShiftI.getReg (0 );
1537+ }
15191538 I.eraseFromParent ();
1520- return constrainSelectedInstRegOperands (*ShiftI, TII, TRI, RBI) &&
1521- constrainSelectedInstRegOperands (*RotateI, TII, TRI, RBI);
1539+ return true ;
15221540}
15231541
15241542bool Z80InstructionSelector::selectSetCond (MachineInstr &I,
0 commit comments