summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2010-08-09 01:47:20 -0700
committerShih-wei Liao <sliao@google.com>2010-08-09 01:47:20 -0700
commit7f80b0a9af7a6618516fb29324c83b26189a7372 (patch)
treeb390027962c3c2d2c8391111c77fbf9c882be2c7 /lib
parente8ea0a7a9608c3233812362c342751165d573f89 (diff)
downloadexternal_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.cpp12
-rw-r--r--lib/Target/ARM/ARMJITInfo.cpp27
-rw-r--r--lib/Target/ARM/ARMRelocations.h6
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
-