summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-11-12 01:02:24 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-11-12 01:02:24 +0000
commit580c0dfaed1caaf241dfb8c02c11f89d6431ee50 (patch)
tree84c1c7e62405458a06c71ec353530c1dba63ddee
parent4e506abedda4590ef8e3c24cd108510d494e102d (diff)
downloadllvm-580c0dfaed1caaf241dfb8c02c11f89d6431ee50.tar.gz
llvm-580c0dfaed1caaf241dfb8c02c11f89d6431ee50.tar.bz2
llvm-580c0dfaed1caaf241dfb8c02c11f89d6431ee50.tar.xz
VFP fld / fst immediate field is multiplied by 4.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59100 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp10
-rw-r--r--lib/Target/ARM/ARMJITInfo.cpp42
-rw-r--r--lib/Target/ARM/ARMRelocations.h4
3 files changed, 37 insertions, 19 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 7e1e8046fa..5b7bc97986 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -222,9 +222,13 @@ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true);
else if (MO.isSymbol())
emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch);
- else if (MO.isCPI())
- emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
- else if (MO.isJTI())
+ else if (MO.isCPI()) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ // For VFP load, the immediate offset is multiplied by 4.
+ unsigned Reloc = ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm)
+ ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry;
+ emitConstPoolAddress(MO.getIndex(), Reloc);
+ } else if (MO.isJTI())
emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
else if (MO.isMBB())
emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch);
diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp
index c93e28be23..2c47f22697 100644
--- a/lib/Target/ARM/ARMJITInfo.cpp
+++ b/lib/Target/ARM/ARMJITInfo.cpp
@@ -13,6 +13,7 @@
#define DEBUG_TYPE "jit"
#include "ARMJITInfo.h"
+#include "ARMInstrInfo.h"
#include "ARMConstantPoolValue.h"
#include "ARMRelocations.h"
#include "ARMSubtarget.h"
@@ -201,16 +202,20 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
intptr_t ARMJITInfo::resolveRelocDestAddr(MachineRelocation *MR) const {
ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType();
- if (RT == ARM::reloc_arm_pic_jt)
+ switch (RT) {
+ default:
+ return (intptr_t)(MR->getResultPointer());
+ case ARM::reloc_arm_pic_jt:
// Destination address - jump table base.
return (intptr_t)(MR->getResultPointer()) - MR->getConstantVal();
- else if (RT == ARM::reloc_arm_jt_base)
+ case ARM::reloc_arm_jt_base:
// Jump table base address.
return getJumpTableBaseAddr(MR->getJumpTableIndex());
- else if (RT == ARM::reloc_arm_cp_entry)
+ case ARM::reloc_arm_cp_entry:
+ case ARM::reloc_arm_vfp_cp_entry:
// Constant pool entry address.
return getConstantPoolEntryAddr(MR->getConstantPoolIndex());
- else if (RT == ARM::reloc_arm_machine_cp_entry) {
+ case ARM::reloc_arm_machine_cp_entry: {
ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MR->getConstantVal();
assert((!ACPV->hasModifier() && !ACPV->mustAddCurrentAddress()) &&
"Can't handle this machine constant pool entry yet!");
@@ -218,7 +223,7 @@ intptr_t ARMJITInfo::resolveRelocDestAddr(MachineRelocation *MR) const {
Addr -= getPCLabelAddr(ACPV->getLabelId()) + ACPV->getPCAdjustment();
return Addr;
}
- return (intptr_t)(MR->getResultPointer());
+ }
}
/// relocate - Before the JIT can run a block of code that has been emitted,
@@ -231,30 +236,35 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
intptr_t ResultPtr = resolveRelocDestAddr(MR);
switch ((ARM::RelocationType)MR->getRelocationType()) {
case ARM::reloc_arm_cp_entry:
+ case ARM::reloc_arm_vfp_cp_entry:
case ARM::reloc_arm_relative: {
// It is necessary to calculate the correct PC relative value. We
// subtract the base addr from the target addr to form a byte offset.
- ResultPtr = ResultPtr-(intptr_t)RelocPos-8;
+ ResultPtr = ResultPtr - (intptr_t)RelocPos - 8;
// If the result is positive, set bit U(23) to 1.
if (ResultPtr >= 0)
- *((unsigned*)RelocPos) |= 1 << 23;
+ *((intptr_t*)RelocPos) |= 1 << ARMII::U_BitShift;
else {
- // Otherwise, obtain the absolute value and set
- // bit U(23) to 0.
- ResultPtr *= -1;
- *((unsigned*)RelocPos) &= 0xFF7FFFFF;
+ // Otherwise, obtain the absolute value and set bit U(23) to 0.
+ assert((*((intptr_t*)RelocPos) & (1 << ARMII::U_BitShift)) == 0 &&
+ "U bit is not zero?");
+ ResultPtr = - ResultPtr;
}
// Set the immed value calculated.
- *((unsigned*)RelocPos) |= (unsigned)ResultPtr;
+ // VFP immediate offset is multiplied by 4.
+ if (MR->getRelocationType() == ARM::reloc_arm_vfp_cp_entry)
+ ResultPtr = ResultPtr >> 2;
+ *((intptr_t*)RelocPos) |= ResultPtr;
// Set register Rn to PC.
- *((unsigned*)RelocPos) |= 0xF << 16;
+ *((intptr_t*)RelocPos) |=
+ ARMRegisterInfo::getRegisterNumbering(ARM::PC) << ARMII::RegRnShift;
break;
}
case ARM::reloc_arm_pic_jt:
case ARM::reloc_arm_machine_cp_entry:
case ARM::reloc_arm_absolute: {
// These addresses have already been resolved.
- *((unsigned*)RelocPos) |= (unsigned)ResultPtr;
+ *((intptr_t*)RelocPos) |= (intptr_t)ResultPtr;
break;
}
case ARM::reloc_arm_branch: {
@@ -266,13 +276,13 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
ResultPtr = ResultPtr - (intptr_t)RelocPos - 8;
ResultPtr = (ResultPtr & 0x03FFFFFC) >> 2;
assert(ResultPtr >= -33554432 && ResultPtr <= 33554428);
- *((unsigned*)RelocPos) |= ResultPtr;
+ *((intptr_t*)RelocPos) |= ResultPtr;
break;
}
case ARM::reloc_arm_jt_base: {
// JT base - (instruction addr + 8)
ResultPtr = ResultPtr - (intptr_t)RelocPos - 8;
- *((unsigned*)RelocPos) |= ResultPtr;
+ *((intptr_t*)RelocPos) |= ResultPtr;
break;
}
}
diff --git a/lib/Target/ARM/ARMRelocations.h b/lib/Target/ARM/ARMRelocations.h
index 8424386916..2cc295085b 100644
--- a/lib/Target/ARM/ARMRelocations.h
+++ b/lib/Target/ARM/ARMRelocations.h
@@ -31,6 +31,10 @@ namespace llvm {
// addresses are kept locally in a map.
reloc_arm_cp_entry,
+ // reloc_arm_vfp_cp_entry - Same as reloc_arm_cp_entry except the offset
+ // should be divided by 4.
+ reloc_arm_vfp_cp_entry,
+
// reloc_arm_machine_cp_entry - Relocation of a ARM machine constantpool
// entry.
reloc_arm_machine_cp_entry,