/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize /// a destreg = basereg + immediate in Thumb code. Materialize the immediate /// in a register using mov / mvn sequences or load the immediate from a /// constpool entry. static void emitThumbRegPlusImmInReg( MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, bool CanChangeCC, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) { MachineFunction &MF = *MBB.getParent(); const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>(); bool isHigh = !isARMLowRegister(DestReg) || (BaseReg != 0 && !isARMLowRegister(BaseReg)); bool isSub = false; // Subtract doesn't have high register version. Load the negative value // if either base or dest register is a high register. Also, if do not // issue sub as part of the sequence if condition register is to be // preserved. if (NumBytes < 0 && !isHigh && CanChangeCC) { isSub = true; NumBytes = -NumBytes; } unsigned LdReg = DestReg; if (DestReg == ARM::SP) assert(BaseReg == ARM::SP && "Unexpected!"); if (!isARMLowRegister(DestReg) && !MRI.isVirtualRegister(DestReg)) LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) { BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg) .add(t1CondCodeOp()) .addImm(NumBytes) .setMIFlags(MIFlags); } else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) { BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg) .add(t1CondCodeOp()) .addImm(NumBytes) .setMIFlags(MIFlags); BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg) .add(t1CondCodeOp()) .addReg(LdReg, RegState::Kill) .setMIFlags(MIFlags); } else if (ST.genExecuteOnly()) { BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), LdReg) .addImm(NumBytes).setMIFlags(MIFlags); } else MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0, MIFlags); // Emit add / sub. int Opc = (isSub) ? ARM::tSUBrr : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); if (Opc != ARM::tADDhirr) MIB = MIB.add(t1CondCodeOp()); if (DestReg == ARM::SP || isSub) MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); else MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); MIB.add(predOps(ARMCC::AL)); }
/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize /// a destreg = basereg + immediate in Thumb code. Materialize the immediate /// in a register using mov / mvn sequences or load the immediate from a /// constpool entry. static void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, unsigned DestReg, unsigned BaseReg, int NumBytes, bool CanChangeCC, const TargetInstrInfo &TII, const ARMBaseRegisterInfo& MRI, DebugLoc dl) { MachineFunction &MF = *MBB.getParent(); bool isHigh = !isARMLowRegister(DestReg) || (BaseReg != 0 && !isARMLowRegister(BaseReg)); bool isSub = false; // Subtract doesn't have high register version. Load the negative value // if either base or dest register is a high register. Also, if do not // issue sub as part of the sequence if condition register is to be // preserved. if (NumBytes < 0 && !isHigh && CanChangeCC) { isSub = true; NumBytes = -NumBytes; } unsigned LdReg = DestReg; if (DestReg == ARM::SP) { assert(BaseReg == ARM::SP && "Unexpected!"); LdReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass); } if (NumBytes <= 255 && NumBytes >= 0) AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) .addImm(NumBytes); else if (NumBytes < 0 && NumBytes >= -255) { AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) .addImm(NumBytes); AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) .addReg(LdReg, RegState::Kill); } else MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes); // Emit add / sub. int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); if (Opc != ARM::tADDhirr) MIB = AddDefaultT1CC(MIB); if (DestReg == ARM::SP || isSub) MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); else MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); AddDefaultPred(MIB); }