mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-14 15:28:20 +00:00
Encode PICADD; some code clean up.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58526 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -74,8 +74,13 @@ namespace {
|
|||||||
|
|
||||||
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
|
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID,
|
const TargetInstrDesc &TID,
|
||||||
|
const MachineOperand &MO,
|
||||||
unsigned OpIdx);
|
unsigned OpIdx);
|
||||||
|
|
||||||
|
unsigned getMachineSoImmOpValue(const MachineInstr &MI,
|
||||||
|
const TargetInstrDesc &TID,
|
||||||
|
const MachineOperand &MO);
|
||||||
|
|
||||||
unsigned getAddrMode1SBit(const MachineInstr &MI,
|
unsigned getAddrMode1SBit(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID) const;
|
const TargetInstrDesc &TID) const;
|
||||||
|
|
||||||
@@ -104,11 +109,10 @@ namespace {
|
|||||||
|
|
||||||
/// 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 getMachineOpValue(const MachineInstr &MI,const MachineOperand &MO);
|
||||||
unsigned getMachineOpValue(const MachineInstr &MI, unsigned OpIdx) {
|
unsigned getMachineOpValue(const MachineInstr &MI, unsigned OpIdx) {
|
||||||
return getMachineOpValue(MI, MI.getOperand(OpIdx));
|
return getMachineOpValue(MI, MI.getOperand(OpIdx));
|
||||||
}
|
}
|
||||||
unsigned getMachineOpValue(const MachineInstr &MI,
|
|
||||||
const MachineOperand &MO);
|
|
||||||
|
|
||||||
/// getBaseOpcodeFor - Return the opcode value.
|
/// getBaseOpcodeFor - Return the opcode value.
|
||||||
///
|
///
|
||||||
@@ -257,6 +261,70 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
|||||||
MCE.emitWordLE(getInstrBinary(MI));
|
MCE.emitWordLE(getInstrBinary(MI));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
|
||||||
|
unsigned CPI = MI.getOperand(0).getImm();
|
||||||
|
unsigned CPIndex = MI.getOperand(1).getIndex();
|
||||||
|
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex];
|
||||||
|
|
||||||
|
// Remember the CONSTPOOL_ENTRY address for later relocation.
|
||||||
|
JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());
|
||||||
|
|
||||||
|
// Emit constpool island entry. In most cases, the actual values will be
|
||||||
|
// resolved and relocated after code emission.
|
||||||
|
if (MCPE.isMachineConstantPoolEntry()) {
|
||||||
|
ARMConstantPoolValue *ACPV =
|
||||||
|
static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
|
||||||
|
|
||||||
|
DOUT << "\t** ARM constant pool #" << CPI << ", ' @ "
|
||||||
|
<< (void*)MCE.getCurrentPCValue() << *ACPV << '\n';
|
||||||
|
|
||||||
|
GlobalValue *GV = ACPV->getGV();
|
||||||
|
if (GV) {
|
||||||
|
assert(!ACPV->isStub() && "Don't know how to deal this yet!");
|
||||||
|
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
|
||||||
|
} else {
|
||||||
|
assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
|
||||||
|
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
|
||||||
|
}
|
||||||
|
MCE.emitWordLE(0);
|
||||||
|
} else {
|
||||||
|
Constant *CV = MCPE.Val.ConstVal;
|
||||||
|
|
||||||
|
DOUT << "\t** Constant pool #" << CPI << ", ' @ "
|
||||||
|
<< (void*)MCE.getCurrentPCValue() << *CV << '\n';
|
||||||
|
|
||||||
|
if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
|
||||||
|
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
|
||||||
|
MCE.emitWordLE(0);
|
||||||
|
} else {
|
||||||
|
assert(CV->getType()->isInteger() &&
|
||||||
|
"Not expecting non-integer constpool entries yet!");
|
||||||
|
const ConstantInt *CI = dyn_cast<ConstantInt>(CV);
|
||||||
|
uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
|
||||||
|
MCE.emitWordLE(Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
|
||||||
|
unsigned Opcode = MI.getDesc().Opcode;
|
||||||
|
switch (Opcode) {
|
||||||
|
default:
|
||||||
|
abort(); // FIXME:
|
||||||
|
case ARM::CONSTPOOL_ENTRY:
|
||||||
|
emitConstPoolInstruction(MI);
|
||||||
|
break;
|
||||||
|
case ARM::PICADD: {
|
||||||
|
// PICADD is just an add instruction that implicitly read pc.
|
||||||
|
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||||
|
const TargetInstrDesc &TID = MI.getDesc();
|
||||||
|
MCE.emitWordLE(getAddrMode1InstrBinary(MI, TID, Binary));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned ARMCodeEmitter::getAddrModeNoneInstrBinary(const MachineInstr &MI,
|
unsigned ARMCodeEmitter::getAddrModeNoneInstrBinary(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID,
|
const TargetInstrDesc &TID,
|
||||||
unsigned Binary) {
|
unsigned Binary) {
|
||||||
@@ -295,9 +363,9 @@ unsigned ARMCodeEmitter::getAddrModeNoneInstrBinary(const MachineInstr &MI,
|
|||||||
|
|
||||||
unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
|
unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID,
|
const TargetInstrDesc &TID,
|
||||||
|
const MachineOperand &MO,
|
||||||
unsigned OpIdx) {
|
unsigned OpIdx) {
|
||||||
// Set last operand (register Rm)
|
unsigned Binary = getMachineOpValue(MI, MO);
|
||||||
unsigned Binary = getMachineOpValue(MI, OpIdx);
|
|
||||||
|
|
||||||
const MachineOperand &MO1 = MI.getOperand(OpIdx + 1);
|
const MachineOperand &MO1 = MI.getOperand(OpIdx + 1);
|
||||||
const MachineOperand &MO2 = MI.getOperand(OpIdx + 2);
|
const MachineOperand &MO2 = MI.getOperand(OpIdx + 2);
|
||||||
@@ -351,6 +419,17 @@ unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
|
|||||||
return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
|
return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned ARMCodeEmitter::getMachineSoImmOpValue(const MachineInstr &MI,
|
||||||
|
const TargetInstrDesc &TID,
|
||||||
|
const MachineOperand &MO) {
|
||||||
|
unsigned SoImm = MO.getImm();
|
||||||
|
// Encode rotate_imm.
|
||||||
|
unsigned Binary = ARM_AM::getSOImmValRot(SoImm) << ARMII::RotImmShift;
|
||||||
|
// Encode immed_8.
|
||||||
|
Binary |= ARM_AM::getSOImmVal(SoImm);
|
||||||
|
return Binary;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI,
|
unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID) const {
|
const TargetInstrDesc &TID) const {
|
||||||
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
|
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
|
||||||
@@ -361,63 +440,6 @@ unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
|
|
||||||
unsigned CPI = MI.getOperand(0).getImm();
|
|
||||||
unsigned CPIndex = MI.getOperand(1).getIndex();
|
|
||||||
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex];
|
|
||||||
|
|
||||||
// Remember the CONSTPOOL_ENTRY address for later relocation.
|
|
||||||
JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());
|
|
||||||
|
|
||||||
// Emit constpool island entry. In most cases, the actual values will be
|
|
||||||
// resolved and relocated after code emission.
|
|
||||||
if (MCPE.isMachineConstantPoolEntry()) {
|
|
||||||
ARMConstantPoolValue *ACPV =
|
|
||||||
static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
|
|
||||||
|
|
||||||
DOUT << "\t** ARM constant pool #" << CPI << ", ' @ "
|
|
||||||
<< (void*)MCE.getCurrentPCValue() << *ACPV << '\n';
|
|
||||||
|
|
||||||
GlobalValue *GV = ACPV->getGV();
|
|
||||||
if (GV) {
|
|
||||||
assert(!ACPV->isStub() && "Don't know how to deal this yet!");
|
|
||||||
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
|
|
||||||
} else {
|
|
||||||
assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
|
|
||||||
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
|
|
||||||
}
|
|
||||||
MCE.emitWordLE(0);
|
|
||||||
} else {
|
|
||||||
Constant *CV = MCPE.Val.ConstVal;
|
|
||||||
|
|
||||||
DOUT << "\t** Constant pool #" << CPI << ", ' @ "
|
|
||||||
<< (void*)MCE.getCurrentPCValue() << *CV << '\n';
|
|
||||||
|
|
||||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
|
|
||||||
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
|
|
||||||
MCE.emitWordLE(0);
|
|
||||||
} else {
|
|
||||||
assert(CV->getType()->isInteger() &&
|
|
||||||
"Not expecting non-integer constpool entries yet!");
|
|
||||||
const ConstantInt *CI = dyn_cast<ConstantInt>(CV);
|
|
||||||
uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
|
|
||||||
MCE.emitWordLE(Val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
|
|
||||||
unsigned Opcode = MI.getDesc().Opcode;
|
|
||||||
switch (Opcode) {
|
|
||||||
default:
|
|
||||||
abort(); // FIXME:
|
|
||||||
case ARM::CONSTPOOL_ENTRY: {
|
|
||||||
emitConstPoolInstruction(MI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI,
|
unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID,
|
const TargetInstrDesc &TID,
|
||||||
unsigned Binary) {
|
unsigned Binary) {
|
||||||
@@ -437,37 +459,40 @@ unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI,
|
|||||||
|
|
||||||
// Encode first non-shifter register operand if there is one.
|
// Encode first non-shifter register operand if there is one.
|
||||||
unsigned Format = TID.TSFlags & ARMII::FormMask;
|
unsigned Format = TID.TSFlags & ARMII::FormMask;
|
||||||
bool hasRnOperand= !(Format == ARMII::DPRdMisc ||
|
bool HasRnReg = !(Format == ARMII::DPRdMisc ||
|
||||||
Format == ARMII::DPRdIm ||
|
Format == ARMII::DPRdIm ||
|
||||||
Format == ARMII::DPRdReg ||
|
Format == ARMII::DPRdReg ||
|
||||||
Format == ARMII::DPRdSoReg);
|
Format == ARMII::DPRdSoReg);
|
||||||
if (hasRnOperand) {
|
if (HasRnReg) {
|
||||||
|
if (TID.getOpcode() == ARM::PICADD)
|
||||||
|
// Special handling for PICADD. It implicitly use add.
|
||||||
|
Binary |=
|
||||||
|
ARMRegisterInfo::getRegisterNumbering(ARM::PC) << ARMII::RegRnShift;
|
||||||
|
else {
|
||||||
Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
|
Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
|
||||||
++OpIdx;
|
++OpIdx;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Encode shifter operand.
|
// Encode shifter operand.
|
||||||
bool HasSoReg = (Format == ARMII::DPRdSoReg ||
|
bool HasSoReg = (Format == ARMII::DPRdSoReg ||
|
||||||
Format == ARMII::DPRnSoReg ||
|
Format == ARMII::DPRnSoReg ||
|
||||||
Format == ARMII::DPRSoReg ||
|
Format == ARMII::DPRSoReg ||
|
||||||
Format == ARMII::DPRSoRegS);
|
Format == ARMII::DPRSoRegS);
|
||||||
if (HasSoReg)
|
|
||||||
// Encode SoReg.
|
|
||||||
return Binary | getMachineSoRegOpValue(MI, TID, OpIdx);
|
|
||||||
|
|
||||||
const MachineOperand &MO = MI.getOperand(OpIdx);
|
const MachineOperand &MO = MI.getOperand(OpIdx);
|
||||||
|
if (HasSoReg)
|
||||||
|
// Encode SoReg.
|
||||||
|
return Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx);
|
||||||
|
|
||||||
if (MO.isReg())
|
if (MO.isReg())
|
||||||
// Encode register Rm.
|
// Encode register Rm.
|
||||||
return Binary | getMachineOpValue(MI, NumDefs);
|
return Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg());
|
||||||
|
|
||||||
// Encode so_imm.
|
// Encode so_imm.
|
||||||
// Set bit I(25) to identify this is the immediate form of <shifter_op>
|
// Set bit I(25) to identify this is the immediate form of <shifter_op>
|
||||||
Binary |= 1 << ARMII::I_BitShift;
|
Binary |= 1 << ARMII::I_BitShift;
|
||||||
unsigned SoImm = MO.getImm();
|
Binary |= getMachineSoImmOpValue(MI, TID, MO);
|
||||||
// Encode rotate_imm.
|
|
||||||
Binary |= ARM_AM::getSOImmValRot(SoImm) << ARMII::RotImmShift;
|
|
||||||
// Encode immed_8.
|
|
||||||
Binary |= ARM_AM::getSOImmVal(SoImm);
|
|
||||||
return Binary;
|
return Binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user