diff options
Diffstat (limited to 'llvm/lib/Target/ARM/Thumb2InstrInfo.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/Thumb2InstrInfo.cpp | 121 |
1 files changed, 63 insertions, 58 deletions
diff --git a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp index af1f0aeb27ba5..e06bb9546c036 100644 --- a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp +++ b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp @@ -120,8 +120,8 @@ Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB, void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - const DebugLoc &DL, unsigned DestReg, - unsigned SrcReg, bool KillSrc) const { + const DebugLoc &DL, MCRegister DestReg, + MCRegister SrcReg, bool KillSrc) const { // Handle SPR, DPR, and QPR copies. if (!ARM::GPRRegClass.contains(DestReg, SrcReg)) return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc); @@ -303,50 +303,45 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, continue; } - bool HasCCOut = true; - if (BaseReg == ARM::SP) { - // sub sp, sp, #imm7 - if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) { - assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?"); - Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; - BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) - .addReg(BaseReg) - .addImm(ThisVal / 4) - .setMIFlags(MIFlags) - .add(predOps(ARMCC::AL)); - NumBytes = 0; - continue; - } + assert((DestReg != ARM::SP || BaseReg == ARM::SP) && + "Writing to SP, from other register."); - // sub rd, sp, so_imm - Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; - if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { - NumBytes = 0; - } else { - // FIXME: Move this to ARMAddressingModes.h? - unsigned RotAmt = countLeadingZeros(ThisVal); - ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); - NumBytes &= ~ThisVal; - assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && - "Bit extraction didn't work?"); - } + // Try to use T1, as it smaller + if ((DestReg == ARM::SP) && (ThisVal < ((1 << 7) - 1) * 4)) { + assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?"); + Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; + BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) + .addReg(BaseReg) + .addImm(ThisVal / 4) + .setMIFlags(MIFlags) + .add(predOps(ARMCC::AL)); + break; + } + bool HasCCOut = true; + int ImmIsT2SO = ARM_AM::getT2SOImmVal(ThisVal); + bool ToSP = DestReg == ARM::SP; + unsigned t2SUB = ToSP ? ARM::t2SUBspImm : ARM::t2SUBri; + unsigned t2ADD = ToSP ? ARM::t2ADDspImm : ARM::t2ADDri; + unsigned t2SUBi12 = ToSP ? ARM::t2SUBspImm12 : ARM::t2SUBri12; + unsigned t2ADDi12 = ToSP ? ARM::t2ADDspImm12 : ARM::t2ADDri12; + Opc = isSub ? t2SUB : t2ADD; + // Prefer T2: sub rd, rn, so_imm | sub sp, sp, so_imm + if (ImmIsT2SO != -1) { + NumBytes = 0; + } else if (ThisVal < 4096) { + // Prefer T3 if can make it in a single go: subw rd, rn, imm12 | subw sp, + // sp, imm12 + Opc = isSub ? t2SUBi12 : t2ADDi12; + HasCCOut = false; + NumBytes = 0; } else { - assert(DestReg != ARM::SP && BaseReg != ARM::SP); - Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; - if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { - NumBytes = 0; - } else if (ThisVal < 4096) { - Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; - HasCCOut = false; - NumBytes = 0; - } else { - // FIXME: Move this to ARMAddressingModes.h? - unsigned RotAmt = countLeadingZeros(ThisVal); - ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); - NumBytes &= ~ThisVal; - assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && - "Bit extraction didn't work?"); - } + // Use one T2 instruction to reduce NumBytes + // FIXME: Move this to ARMAddressingModes.h? + unsigned RotAmt = countLeadingZeros(ThisVal); + ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); + NumBytes &= ~ThisVal; + assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && + "Bit extraction didn't work?"); } // Build the new ADD / SUB. @@ -375,6 +370,8 @@ negativeOffsetOpcode(unsigned opcode) case ARM::t2STRBi12: return ARM::t2STRBi8; case ARM::t2STRHi12: return ARM::t2STRHi8; case ARM::t2PLDi12: return ARM::t2PLDi8; + case ARM::t2PLDWi12: return ARM::t2PLDWi8; + case ARM::t2PLIi12: return ARM::t2PLIi8; case ARM::t2LDRi8: case ARM::t2LDRHi8: @@ -385,13 +382,13 @@ negativeOffsetOpcode(unsigned opcode) case ARM::t2STRBi8: case ARM::t2STRHi8: case ARM::t2PLDi8: + case ARM::t2PLDWi8: + case ARM::t2PLIi8: return opcode; default: - break; + llvm_unreachable("unknown thumb2 opcode."); } - - return 0; } static unsigned @@ -407,6 +404,8 @@ positiveOffsetOpcode(unsigned opcode) case ARM::t2STRBi8: return ARM::t2STRBi12; case ARM::t2STRHi8: return ARM::t2STRHi12; case ARM::t2PLDi8: return ARM::t2PLDi12; + case ARM::t2PLDWi8: return ARM::t2PLDWi12; + case ARM::t2PLIi8: return ARM::t2PLIi12; case ARM::t2LDRi12: case ARM::t2LDRHi12: @@ -417,13 +416,13 @@ positiveOffsetOpcode(unsigned opcode) case ARM::t2STRBi12: case ARM::t2STRHi12: case ARM::t2PLDi12: + case ARM::t2PLDWi12: + case ARM::t2PLIi12: return opcode; default: - break; + llvm_unreachable("unknown thumb2 opcode."); } - - return 0; } static unsigned @@ -439,6 +438,8 @@ immediateOffsetOpcode(unsigned opcode) case ARM::t2STRBs: return ARM::t2STRBi12; case ARM::t2STRHs: return ARM::t2STRHi12; case ARM::t2PLDs: return ARM::t2PLDi12; + case ARM::t2PLDWs: return ARM::t2PLDWi12; + case ARM::t2PLIs: return ARM::t2PLIi12; case ARM::t2LDRi12: case ARM::t2LDRHi12: @@ -449,6 +450,8 @@ immediateOffsetOpcode(unsigned opcode) case ARM::t2STRBi12: case ARM::t2STRHi12: case ARM::t2PLDi12: + case ARM::t2PLDWi12: + case ARM::t2PLIi12: case ARM::t2LDRi8: case ARM::t2LDRHi8: case ARM::t2LDRBi8: @@ -458,13 +461,13 @@ immediateOffsetOpcode(unsigned opcode) case ARM::t2STRBi8: case ARM::t2STRHi8: case ARM::t2PLDi8: + case ARM::t2PLDWi8: + case ARM::t2PLIi8: return opcode; default: - break; + llvm_unreachable("unknown thumb2 opcode."); } - - return 0; } bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, @@ -484,7 +487,8 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR) AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2? - if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) { + const bool IsSP = Opcode == ARM::t2ADDspImm12 || Opcode == ARM::t2ADDspImm; + if (IsSP || Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) { Offset += MI.getOperand(FrameRegIdx+1).getImm(); unsigned PredReg; @@ -501,14 +505,14 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, return true; } - bool HasCCOut = Opcode != ARM::t2ADDri12; + bool HasCCOut = (Opcode != ARM::t2ADDspImm12 && Opcode != ARM::t2ADDri12); if (Offset < 0) { Offset = -Offset; isSub = true; - MI.setDesc(TII.get(ARM::t2SUBri)); + MI.setDesc(IsSP ? TII.get(ARM::t2SUBspImm) : TII.get(ARM::t2SUBri)); } else { - MI.setDesc(TII.get(ARM::t2ADDri)); + MI.setDesc(IsSP ? TII.get(ARM::t2ADDspImm) : TII.get(ARM::t2ADDri)); } // Common case: small offset, fits into instruction. @@ -524,7 +528,8 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, // Another common case: imm12. if (Offset < 4096 && (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) { - unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; + unsigned NewOpc = isSub ? IsSP ? ARM::t2SUBspImm12 : ARM::t2SUBri12 + : IsSP ? ARM::t2ADDspImm12 : ARM::t2ADDri12; MI.setDesc(TII.get(NewOpc)); MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); |