mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-05 18:28:29 +00:00
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
This commit is contained in:
parent
4e506abedd
commit
580c0dfaed
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user