diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-07-28 05:48:47 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-07-28 05:48:47 +0000 |
commit | 6495f63945e8dbde81f03a1dc2ab421993b9a495 (patch) | |
tree | 3938678849c493091334cec9e5e426962ea88090 /lib/Target/ARM/Thumb2RegisterInfo.cpp | |
parent | f4b64f67b6d397cedcb8a9c0539f62957cca1627 (diff) | |
download | llvm-6495f63945e8dbde81f03a1dc2ab421993b9a495.tar.gz llvm-6495f63945e8dbde81f03a1dc2ab421993b9a495.tar.bz2 llvm-6495f63945e8dbde81f03a1dc2ab421993b9a495.tar.xz |
- More refactoring. This gets rid of all of the getOpcode calls.
- This change also makes it possible to switch between ARM / Thumb on a
per-function basis.
- Fixed thumb2 routine which expand reg + arbitrary immediate. It was using
using ARM so_imm logic.
- Use movw and movt to do reg + imm when profitable.
- Other code clean ups and minor optimizations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77300 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/Thumb2RegisterInfo.cpp')
-rw-r--r-- | lib/Target/ARM/Thumb2RegisterInfo.cpp | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/lib/Target/ARM/Thumb2RegisterInfo.cpp b/lib/Target/ARM/Thumb2RegisterInfo.cpp index ae2d21e90c..98be2041fd 100644 --- a/lib/Target/ARM/Thumb2RegisterInfo.cpp +++ b/lib/Target/ARM/Thumb2RegisterInfo.cpp @@ -60,218 +60,7 @@ void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, .addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0); } -static unsigned -negativeOffsetOpcode(unsigned opcode) -{ - switch (opcode) { - case ARM::t2LDRi12: return ARM::t2LDRi8; - case ARM::t2LDRHi12: return ARM::t2LDRHi8; - case ARM::t2LDRBi12: return ARM::t2LDRBi8; - case ARM::t2LDRSHi12: return ARM::t2LDRSHi8; - case ARM::t2LDRSBi12: return ARM::t2LDRSBi8; - case ARM::t2STRi12: return ARM::t2STRi8; - case ARM::t2STRBi12: return ARM::t2STRBi8; - case ARM::t2STRHi12: return ARM::t2STRHi8; - - case ARM::t2LDRi8: - case ARM::t2LDRHi8: - case ARM::t2LDRBi8: - case ARM::t2LDRSHi8: - case ARM::t2LDRSBi8: - case ARM::t2STRi8: - case ARM::t2STRBi8: - case ARM::t2STRHi8: - return opcode; - - default: - break; - } - - return 0; -} - -static unsigned -positiveOffsetOpcode(unsigned opcode) -{ - switch (opcode) { - case ARM::t2LDRi8: return ARM::t2LDRi12; - case ARM::t2LDRHi8: return ARM::t2LDRHi12; - case ARM::t2LDRBi8: return ARM::t2LDRBi12; - case ARM::t2LDRSHi8: return ARM::t2LDRSHi12; - case ARM::t2LDRSBi8: return ARM::t2LDRSBi12; - case ARM::t2STRi8: return ARM::t2STRi12; - case ARM::t2STRBi8: return ARM::t2STRBi12; - case ARM::t2STRHi8: return ARM::t2STRHi12; - - case ARM::t2LDRi12: - case ARM::t2LDRHi12: - case ARM::t2LDRBi12: - case ARM::t2LDRSHi12: - case ARM::t2LDRSBi12: - case ARM::t2STRi12: - case ARM::t2STRBi12: - case ARM::t2STRHi12: - return opcode; - - default: - break; - } - - return 0; -} - -static unsigned -immediateOffsetOpcode(unsigned opcode) -{ - switch (opcode) { - case ARM::t2LDRs: return ARM::t2LDRi12; - case ARM::t2LDRHs: return ARM::t2LDRHi12; - case ARM::t2LDRBs: return ARM::t2LDRBi12; - case ARM::t2LDRSHs: return ARM::t2LDRSHi12; - case ARM::t2LDRSBs: return ARM::t2LDRSBi12; - case ARM::t2STRs: return ARM::t2STRi12; - case ARM::t2STRBs: return ARM::t2STRBi12; - case ARM::t2STRHs: return ARM::t2STRHi12; - - case ARM::t2LDRi12: - case ARM::t2LDRHi12: - case ARM::t2LDRBi12: - case ARM::t2LDRSHi12: - case ARM::t2LDRSBi12: - case ARM::t2STRi12: - case ARM::t2STRBi12: - case ARM::t2STRHi12: - case ARM::t2LDRi8: - case ARM::t2LDRHi8: - case ARM::t2LDRBi8: - case ARM::t2LDRSHi8: - case ARM::t2LDRSBi8: - case ARM::t2STRi8: - case ARM::t2STRBi8: - case ARM::t2STRHi8: - return opcode; - - default: - break; - } - - return 0; -} - bool Thumb2RegisterInfo:: requiresRegisterScavenging(const MachineFunction &MF) const { return true; } - -int Thumb2RegisterInfo:: -rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, - unsigned MOVOpc, unsigned ADDriOpc, unsigned SUBriOpc, - unsigned FrameReg, int Offset) const -{ - unsigned Opcode = MI.getOpcode(); - const TargetInstrDesc &Desc = MI.getDesc(); - unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); - bool isSub = false; - - // Memory operands in inline assembly always use AddrModeT2_i12 - if (Opcode == ARM::INLINEASM) - AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2? - - if (Opcode == ADDriOpc) { - Offset += MI.getOperand(FrameRegIdx+1).getImm(); - if (Offset == 0) { - // Turn it into a move. - MI.setDesc(TII.get(MOVOpc)); - MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); - MI.RemoveOperand(FrameRegIdx+1); - return 0; - } else if (Offset < 0) { - Offset = -Offset; - isSub = true; - MI.setDesc(TII.get(SUBriOpc)); - } - - // Common case: small offset, fits into instruction. - if (ARM_AM::getT2SOImmVal(Offset) != -1) { - // Replace the FrameIndex with sp / fp - MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); - MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); - return 0; - } - - // Otherwise, extract 8 adjacent bits from the immediate into this - // t2ADDri/t2SUBri. - unsigned RotAmt = CountLeadingZeros_32(Offset); - if (RotAmt > 24) - RotAmt = 24; - unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt); - - // We will handle these bits from offset, clear them. - Offset &= ~ThisImmVal; - - assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 && - "Bit extraction didn't work?"); - MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal); - } else { - // AddrModeT2_so cannot handle any offset. If there is no offset - // register then we change to an immediate version. - if (AddrMode == ARMII::AddrModeT2_so) { - unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg(); - if (OffsetReg != 0) { - MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); - return Offset; - } - - MI.RemoveOperand(FrameRegIdx+1); - MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0); - Opcode = immediateOffsetOpcode(Opcode); - AddrMode = ARMII::AddrModeT2_i12; - } - - // Neon and FP address modes are handled by the base ARM version... - if ((AddrMode != ARMII::AddrModeT2_i8) && - (AddrMode != ARMII::AddrModeT2_i12)) { - return ARMBaseRegisterInfo::rewriteFrameIndex(MI, FrameRegIdx, - ARM::t2MOVr, ARM::t2ADDri, ARM::t2SUBri, FrameReg, Offset); - } - - unsigned NumBits = 0; - Offset += MI.getOperand(FrameRegIdx+1).getImm(); - - // i8 supports only negative, and i12 supports only positive, so - // based on Offset sign convert Opcode to the appropriate - // instruction - if (Offset < 0) { - Opcode = negativeOffsetOpcode(Opcode); - NumBits = 8; - isSub = true; - Offset = -Offset; - } - else { - Opcode = positiveOffsetOpcode(Opcode); - NumBits = 12; - } - - if (Opcode) { - MI.setDesc(TII.get(Opcode)); - MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1); - - // Attempt to fold address computation - // Common case: small offset, fits into instruction. - unsigned Mask = (1 << NumBits) - 1; - if ((unsigned)Offset <= Mask) { - // Replace the FrameIndex with fp/sp - MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); - ImmOp.ChangeToImmediate((isSub) ? -Offset : Offset); - return 0; - } - - // Otherwise, offset doesn't fit. Pull in what we can to simplify - unsigned ImmedOffset = Offset & Mask; - ImmOp.ChangeToImmediate((isSub) ? -ImmedOffset : ImmedOffset); - Offset &= ~Mask; - } - } - - return (isSub) ? -Offset : Offset; -} |