diff options
author | Shih-wei Liao <sliao@google.com> | 2010-08-09 01:47:20 -0700 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2010-08-09 01:47:20 -0700 |
commit | 7f80b0a9af7a6618516fb29324c83b26189a7372 (patch) | |
tree | b390027962c3c2d2c8391111c77fbf9c882be2c7 /lib | |
parent | e8ea0a7a9608c3233812362c342751165d573f89 (diff) | |
download | external_llvm-7f80b0a9af7a6618516fb29324c83b26189a7372.zip external_llvm-7f80b0a9af7a6618516fb29324c83b26189a7372.tar.gz external_llvm-7f80b0a9af7a6618516fb29324c83b26189a7372.tar.bz2 |
Handle load effective address (pc relative).
Change-Id: I060d0f6b7983aacacf03c40ee7b0a8a0bcee053c
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 12 | ||||
-rw-r--r-- | lib/Target/ARM/ARMJITInfo.cpp | 27 | ||||
-rw-r--r-- | lib/Target/ARM/ARMRelocations.h | 6 |
3 files changed, 34 insertions, 11 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index a99af3c..9bc0706 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -150,11 +150,11 @@ namespace { return getMachineOpValue(MI, MI.getOperand(OpIdx)); } - /// getMovi32Value - Return binary encoding of operand for movw/movt. If the + /// getMovi32Value - Return binary encoding of operand for movw/movt. If the /// machine operand requires relocation, record the relocation and return zero. - unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO, + unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO, unsigned Reloc); - unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx, + unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx, unsigned Reloc) { return getMovi32Value(MI, MI.getOperand(OpIdx), Reloc); } @@ -231,12 +231,12 @@ unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const { return 0; } -/// getMovi32Value - Return binary encoding of operand for movw/movt. If the +/// getMovi32Value - Return binary encoding of operand for movw/movt. If the /// machine operand requires relocation, record the relocation and return zero. unsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI, - const MachineOperand &MO, + const MachineOperand &MO, unsigned Reloc) { - assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw)) + assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw)) && "Relocation to this function should be for movt or movw"); switch(MO.getType()) { case MachineOperand::MO_Register: diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp index ea2455c..df8a4f5 100644 --- a/lib/Target/ARM/ARMJITInfo.cpp +++ b/lib/Target/ARM/ARMJITInfo.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "jit" +#include "ARMAddressingModes.h" #include "ARMJITInfo.h" #include "ARMInstrInfo.h" #include "ARMConstantPoolValue.h" @@ -50,7 +51,7 @@ static TargetJITInfo::JITCompilerFn JITCompilerFunction; extern "C" { // We don't need this on Android (generally on hand-held devices). This // function is for the purpose of supporting "lazy symbol lookup" (lookup - // undefined symbol at runtime) (Actually, if you tried to remove the + // undefined symbol at runtime) (Actually, if you tried to remove the // !defined(ANDROID) guard, you'll get compilation error since Android's // toolchain choose armv5te as its CPU architecture which does not support // instruction 'stmdb' and 'ldmia' within the function) @@ -325,17 +326,37 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR, break; } case ARM::reloc_arm_movw: { - ResultPtr = ResultPtr & 0xFFFF; + ResultPtr = ResultPtr & 0xFFFF; *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF; *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; // imm4:imm12, Insts[19-16] = imm4, Insts[11-0] = imm12 break; } case ARM::reloc_arm_movt: { - ResultPtr = (ResultPtr >> 16) & 0xFFFF; + ResultPtr = (ResultPtr >> 16) & 0xFFFF; *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF; *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; // imm4:imm12, Insts[19-16] = imm4, Insts[11-0] = imm12 break; } + case ARM::reloc_arm_so_imm: { + ResultPtr = ResultPtr - (intptr_t)RelocPos - 8; + // If the result is positive, set bit 22 to 0 and bit 23 to 1. + if (ResultPtr >= 0) { + *((intptr_t*)RelocPos) &= ~(1 << 22); + *((intptr_t*)RelocPos) |= 1 << 23; + } else { + // Otherwise, obtain the absolute value and set bit 22 to 1 and bit 23 to 0. + *((intptr_t*)RelocPos) |= 1 << 22; + *((intptr_t*)RelocPos) &= ~(1 << 23); + ResultPtr = - ResultPtr; + } + + int SoImmVal = ARM_AM::getSOImmVal(ResultPtr); + assert(SoImmVal != -1 && "Not a valid so_imm value!"); + *((intptr_t*)RelocPos) |= (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) + << ARMII::SoRotImmShift; + *((intptr_t*)RelocPos) |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); + break; + } } } } diff --git a/lib/Target/ARM/ARMRelocations.h b/lib/Target/ARM/ARMRelocations.h index 86e7206..3c12413 100644 --- a/lib/Target/ARM/ARMRelocations.h +++ b/lib/Target/ARM/ARMRelocations.h @@ -53,10 +53,12 @@ namespace llvm { reloc_arm_movt, // reloc_arm_movw - MOVW immediate relocation. - reloc_arm_movw + reloc_arm_movw, + + // reloc_arm_so_imm - ARM so_imm relocation. + reloc_arm_so_imm }; } } #endif - |