mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
Add support to MOVimm32 using movt/movw for ARM JIT
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104587 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -88,6 +88,7 @@ namespace {
|
|||||||
void emitWordLE(unsigned Binary);
|
void emitWordLE(unsigned Binary);
|
||||||
void emitDWordLE(uint64_t Binary);
|
void emitDWordLE(uint64_t Binary);
|
||||||
void emitConstPoolInstruction(const MachineInstr &MI);
|
void emitConstPoolInstruction(const MachineInstr &MI);
|
||||||
|
void emitMOVi32immInstruction(const MachineInstr &MI);
|
||||||
void emitMOVi2piecesInstruction(const MachineInstr &MI);
|
void emitMOVi2piecesInstruction(const MachineInstr &MI);
|
||||||
void emitLEApcrelJTInstruction(const MachineInstr &MI);
|
void emitLEApcrelJTInstruction(const MachineInstr &MI);
|
||||||
void emitPseudoMoveInstruction(const MachineInstr &MI);
|
void emitPseudoMoveInstruction(const MachineInstr &MI);
|
||||||
@@ -145,6 +146,15 @@ namespace {
|
|||||||
return getMachineOpValue(MI, MI.getOperand(OpIdx));
|
return getMachineOpValue(MI, MI.getOperand(OpIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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 Reloc);
|
||||||
|
unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx,
|
||||||
|
unsigned Reloc) {
|
||||||
|
return getMovi32Value(MI, MI.getOperand(OpIdx), Reloc);
|
||||||
|
}
|
||||||
|
|
||||||
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
|
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
|
||||||
///
|
///
|
||||||
unsigned getShiftOp(unsigned Imm) const ;
|
unsigned getShiftOp(unsigned Imm) const ;
|
||||||
@@ -217,6 +227,31 @@ unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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,
|
||||||
|
unsigned Reloc) {
|
||||||
|
assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw))
|
||||||
|
&& "Relocation to this function should be for movt or movw");
|
||||||
|
|
||||||
|
if (MO.isImm())
|
||||||
|
return static_cast<unsigned>(MO.getImm());
|
||||||
|
else if (MO.isGlobal())
|
||||||
|
emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
|
||||||
|
else if (MO.isSymbol())
|
||||||
|
emitExternalSymbolAddress(MO.getSymbolName(), Reloc);
|
||||||
|
else if (MO.isMBB())
|
||||||
|
emitMachineBasicBlock(MO.getMBB(), Reloc);
|
||||||
|
else {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
errs() << MO;
|
||||||
|
#endif
|
||||||
|
llvm_unreachable("Unsupported operand type for movw/movt");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||||
/// operand requires relocation, record the relocation and return zero.
|
/// operand requires relocation, record the relocation and return zero.
|
||||||
unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
||||||
@@ -438,6 +473,42 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMCodeEmitter::emitMOVi32immInstruction(const MachineInstr &MI) {
|
||||||
|
const MachineOperand &MO0 = MI.getOperand(0);
|
||||||
|
const MachineOperand &MO1 = MI.getOperand(1);
|
||||||
|
|
||||||
|
// Emit the 'movw' instruction.
|
||||||
|
unsigned Binary = 0x30 << 20; // mov: Insts{27-20} = 0b00110000
|
||||||
|
|
||||||
|
unsigned Lo16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movw) & 0xFFFF;
|
||||||
|
|
||||||
|
// Set the conditional execution predicate.
|
||||||
|
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||||
|
|
||||||
|
// Encode Rd.
|
||||||
|
Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
|
||||||
|
|
||||||
|
// Encode imm16 as imm4:imm12
|
||||||
|
Binary |= Lo16 & 0xFFF; // Insts{11-0} = imm12
|
||||||
|
Binary |= ((Lo16 >> 12) & 0xF) << 16; // Insts{19-16} = imm4
|
||||||
|
emitWordLE(Binary);
|
||||||
|
|
||||||
|
unsigned Hi16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movt) >> 16;
|
||||||
|
// Emit the 'movt' instruction.
|
||||||
|
Binary = 0x34 << 20; // movt: Insts{27-20} = 0b00110100
|
||||||
|
|
||||||
|
// Set the conditional execution predicate.
|
||||||
|
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
|
||||||
|
|
||||||
|
// Encode Rd.
|
||||||
|
Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
|
||||||
|
|
||||||
|
// Encode imm16 as imm4:imm1, same as movw above.
|
||||||
|
Binary |= Hi16 & 0xFFF;
|
||||||
|
Binary |= ((Hi16 >> 12) & 0xF) << 16;
|
||||||
|
emitWordLE(Binary);
|
||||||
|
}
|
||||||
|
|
||||||
void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
|
void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
|
||||||
const MachineOperand &MO0 = MI.getOperand(0);
|
const MachineOperand &MO0 = MI.getOperand(0);
|
||||||
const MachineOperand &MO1 = MI.getOperand(1);
|
const MachineOperand &MO1 = MI.getOperand(1);
|
||||||
@@ -557,7 +628,6 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
|
|||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
|
llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
|
||||||
// FIXME: Add support for MOVimm32.
|
|
||||||
case TargetOpcode::INLINEASM: {
|
case TargetOpcode::INLINEASM: {
|
||||||
// We allow inline assembler nodes with empty bodies - they can
|
// We allow inline assembler nodes with empty bodies - they can
|
||||||
// implicitly define registers, which is ok for JIT.
|
// implicitly define registers, which is ok for JIT.
|
||||||
@@ -604,6 +674,11 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
|
|||||||
emitMiscLoadStoreInstruction(MI, ARM::PC);
|
emitMiscLoadStoreInstruction(MI, ARM::PC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ARM::MOVi32imm:
|
||||||
|
emitMOVi32immInstruction(MI);
|
||||||
|
break;
|
||||||
|
|
||||||
case ARM::MOVi2pieces:
|
case ARM::MOVi2pieces:
|
||||||
// Two instructions to materialize a constant.
|
// Two instructions to materialize a constant.
|
||||||
emitMOVi2piecesInstruction(MI);
|
emitMOVi2piecesInstruction(MI);
|
||||||
@@ -729,6 +804,24 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
|
|||||||
Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd)
|
Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd)
|
||||||
<< ARMII::RegRdShift);
|
<< ARMII::RegRdShift);
|
||||||
|
|
||||||
|
if (TID.Opcode == ARM::MOVi16) {
|
||||||
|
// Get immediate from MI.
|
||||||
|
unsigned Lo16 = getMovi32Value(MI, MI.getOperand(OpIdx),
|
||||||
|
ARM::reloc_arm_movw);
|
||||||
|
// Encode imm which is the same as in emitMOVi32immInstruction().
|
||||||
|
Binary |= Lo16 & 0xFFF;
|
||||||
|
Binary |= ((Lo16 >> 12) & 0xF) << 16;
|
||||||
|
emitWordLE(Binary);
|
||||||
|
return;
|
||||||
|
} else if(TID.Opcode == ARM::MOVTi16) {
|
||||||
|
unsigned Hi16 = (getMovi32Value(MI, MI.getOperand(OpIdx),
|
||||||
|
ARM::reloc_arm_movt) >> 16);
|
||||||
|
Binary |= Hi16 & 0xFFF;
|
||||||
|
Binary |= ((Hi16 >> 12) & 0xF) << 16;
|
||||||
|
emitWordLE(Binary);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a two-address operand, skip it. e.g. MOVCCr operand 1.
|
// If this is a two-address operand, skip it. e.g. MOVCCr operand 1.
|
||||||
if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
|
if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
|
||||||
++OpIdx;
|
++OpIdx;
|
||||||
|
@@ -318,6 +318,18 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
|
|||||||
*((intptr_t*)RelocPos) |= ResultPtr;
|
*((intptr_t*)RelocPos) |= ResultPtr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ARM::reloc_arm_movw: {
|
||||||
|
ResultPtr = ResultPtr & 0xFFFF;
|
||||||
|
*((intptr_t*)RelocPos) |= ResultPtr & 0xFFF;
|
||||||
|
*((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ARM::reloc_arm_movt: {
|
||||||
|
ResultPtr = (ResultPtr >> 16) & 0xFFFF;
|
||||||
|
*((intptr_t*)RelocPos) |= ResultPtr & 0xFFF;
|
||||||
|
*((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,7 +47,13 @@ namespace llvm {
|
|||||||
reloc_arm_pic_jt,
|
reloc_arm_pic_jt,
|
||||||
|
|
||||||
// reloc_arm_branch - Branch address relocation.
|
// reloc_arm_branch - Branch address relocation.
|
||||||
reloc_arm_branch
|
reloc_arm_branch,
|
||||||
|
|
||||||
|
// reloc_arm_movt - MOVT immediate relocation.
|
||||||
|
reloc_arm_movt,
|
||||||
|
|
||||||
|
// reloc_arm_movw - MOVW immediate relocation.
|
||||||
|
reloc_arm_movw
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user