diff options
author | Bill Wendling <isanbard@gmail.com> | 2010-11-03 01:49:29 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2010-11-03 01:49:29 +0000 |
commit | 92b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4 (patch) | |
tree | 534c8e3e743a503fd2abdb4a63599fb3e4b979dc /lib/Target/ARM/ARMCodeEmitter.cpp | |
parent | 394d6298bcf89a75b51c8314a6705f6984e46b49 (diff) | |
download | external_llvm-92b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4.zip external_llvm-92b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4.tar.gz external_llvm-92b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4.tar.bz2 |
The MC code couldn't handle ARM LDR instructions with negative offsets:
vldr.64 d1, [r0, #-32]
The problem was with how the addressing mode 5 encodes the offsets. This change
makes sure that the way offsets are handled in addressing mode 5 is consistent
throughout the MC code. It involves re-refactoring the "getAddrModeImmOpValue"
method into an "Imm12" and "addressing mode 5" version. But not to worry! The
majority of the duplicated code has been unified.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118144 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMCodeEmitter.cpp')
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 0584dec..15b3aab 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -177,25 +177,44 @@ namespace { const { return 0; } unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - uint32_t getAddrModeImmOpValue(const MachineInstr &MI, unsigned Op) const { - // {20-17} = reg - // {16} = (U)nsigned (add == '1', sub == '0') - // {15-0} = imm + + unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op) + const { + // {17-13} = reg + // {12} = (U)nsigned (add == '1', sub == '0') + // {11-0} = imm12 const MachineOperand &MO = MI.getOperand(Op); const MachineOperand &MO1 = MI.getOperand(Op + 1); if (!MO.isReg()) { emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry); return 0; } - unsigned Reg = getARMRegisterNumbering(MO.getReg()); - int32_t Imm = MO1.getImm(); + int32_t Imm12 = MO1.getImm(); uint32_t Binary; - Binary = Imm & 0xffff; - if (Imm >= 0) - Binary |= (1 << 16); - - Binary |= (Reg << 17); + Binary = Imm12 & 0xfff; + if (Imm12 >= 0) + Binary |= (1 << 12); + Binary |= (Reg << 13); + return Binary; + } + uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const { + // {12-9} = reg + // {8} = (U)nsigned (add == '1', sub == '0') + // {7-0} = imm12 + const MachineOperand &MO = MI.getOperand(Op); + const MachineOperand &MO1 = MI.getOperand(Op + 1); + if (!MO.isReg()) { + emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry); + return 0; + } + unsigned Reg = getARMRegisterNumbering(MO.getReg()); + int32_t Imm8 = MO1.getImm(); + uint32_t Binary; + Binary = Imm8 & 0xff; + if (Imm8 >= 0) + Binary |= (1 << 8); + Binary |= (Reg << 9); return Binary; } unsigned getNEONVcvtImm32OpValue(const MachineInstr &MI, unsigned Op) |