Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
lib/Target/ARM/ThumbRegisterInfo.cpp
Show First 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | |||||
/// in a register using mov / mvn sequences or load the immediate from a | /// in a register using mov / mvn sequences or load the immediate from a | ||||
/// constpool entry. | /// constpool entry. | ||||
static void emitThumbRegPlusImmInReg( | static void emitThumbRegPlusImmInReg( | ||||
MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, | MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, | ||||
const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, | const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, | ||||
bool CanChangeCC, const TargetInstrInfo &TII, | bool CanChangeCC, const TargetInstrInfo &TII, | ||||
const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) { | const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) { | ||||
MachineFunction &MF = *MBB.getParent(); | MachineFunction &MF = *MBB.getParent(); | ||||
const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>(); | |||||
bool isHigh = !isARMLowRegister(DestReg) || | bool isHigh = !isARMLowRegister(DestReg) || | ||||
(BaseReg != 0 && !isARMLowRegister(BaseReg)); | (BaseReg != 0 && !isARMLowRegister(BaseReg)); | ||||
bool isSub = false; | bool isSub = false; | ||||
// Subtract doesn't have high register version. Load the negative value | // 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 | // 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 | // issue sub as part of the sequence if condition register is to be | ||||
// preserved. | // preserved. | ||||
if (NumBytes < 0 && !isHigh && CanChangeCC) { | if (NumBytes < 0 && !isHigh && CanChangeCC) { | ||||
Show All 12 Lines | AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) | ||||
.setMIFlags(MIFlags); | .setMIFlags(MIFlags); | ||||
} else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) { | } else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) { | ||||
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) | AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) | ||||
.addImm(NumBytes) | .addImm(NumBytes) | ||||
.setMIFlags(MIFlags); | .setMIFlags(MIFlags); | ||||
AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) | AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) | ||||
.addReg(LdReg, RegState::Kill) | .addReg(LdReg, RegState::Kill) | ||||
.setMIFlags(MIFlags); | .setMIFlags(MIFlags); | ||||
} else if (ST.genExecuteOnly()) { | |||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), LdReg) | |||||
.addImm(NumBytes).setMIFlags(MIFlags); | |||||
} else | } else | ||||
MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0, | MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0, | ||||
MIFlags); | MIFlags); | ||||
// Emit add / sub. | // Emit add / sub. | ||||
int Opc = (isSub) ? ARM::tSUBrr | int Opc = (isSub) ? ARM::tSUBrr | ||||
: ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr); | : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr); | ||||
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); | MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); | ||||
▲ Show 20 Lines • Show All 400 Lines • ▼ Show 20 Lines | #endif // NDEBUG | ||||
if (PIdx != -1) | if (PIdx != -1) | ||||
removeOperands(MI, PIdx); | removeOperands(MI, PIdx); | ||||
if (MI.mayLoad()) { | if (MI.mayLoad()) { | ||||
// Use the destination register to materialize sp + offset. | // Use the destination register to materialize sp + offset. | ||||
unsigned TmpReg = MI.getOperand(0).getReg(); | unsigned TmpReg = MI.getOperand(0).getReg(); | ||||
bool UseRR = false; | bool UseRR = false; | ||||
if (Opcode == ARM::tLDRspi) { | if (Opcode == ARM::tLDRspi) { | ||||
if (FrameReg == ARM::SP) | if (FrameReg == ARM::SP || STI.genExecuteOnly()) | ||||
emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg, | emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg, | ||||
Offset, false, TII, *this); | Offset, false, TII, *this); | ||||
else { | else { | ||||
emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); | emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); | ||||
UseRR = true; | UseRR = true; | ||||
} | } | ||||
} else { | } else { | ||||
emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII, | emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII, | ||||
*this); | *this); | ||||
} | } | ||||
MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); | MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); | ||||
MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true); | MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true); | ||||
if (UseRR) | if (UseRR) | ||||
// Use [reg, reg] addrmode. Replace the immediate operand w/ the frame | // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame | ||||
// register. The offset is already handled in the vreg value. | // register. The offset is already handled in the vreg value. | ||||
MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, | MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, | ||||
false); | false); | ||||
} else if (MI.mayStore()) { | } else if (MI.mayStore()) { | ||||
VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); | VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); | ||||
bool UseRR = false; | bool UseRR = false; | ||||
if (Opcode == ARM::tSTRspi) { | if (Opcode == ARM::tSTRspi) { | ||||
if (FrameReg == ARM::SP) | if (FrameReg == ARM::SP || STI.genExecuteOnly()) | ||||
emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg, | emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg, | ||||
Offset, false, TII, *this); | Offset, false, TII, *this); | ||||
else { | else { | ||||
emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); | emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); | ||||
UseRR = true; | UseRR = true; | ||||
} | } | ||||
} else | } else | ||||
emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII, | emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII, | ||||
Show All 16 Lines |