diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-11-12 01:02:24 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-11-12 01:02:24 +0000 |
commit | 580c0dfaed1caaf241dfb8c02c11f89d6431ee50 (patch) | |
tree | 84c1c7e62405458a06c71ec353530c1dba63ddee /lib/Target | |
parent | 4e506abedda4590ef8e3c24cd108510d494e102d (diff) |
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
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 10 | ||||
-rw-r--r-- | lib/Target/ARM/ARMJITInfo.cpp | 42 | ||||
-rw-r--r-- | lib/Target/ARM/ARMRelocations.h | 4 |
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, |