mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Encode pic load / store instructions; fix some encoding bugs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58780 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ec740e325c
commit
83b5cf0272
@ -65,8 +65,12 @@ namespace {
|
||||
|
||||
private:
|
||||
|
||||
void emitWordLE(unsigned Binary);
|
||||
|
||||
void emitConstPoolInstruction(const MachineInstr &MI);
|
||||
|
||||
void addPCLabel(unsigned LabelID);
|
||||
|
||||
void emitPseudoInstruction(const MachineInstr &MI);
|
||||
|
||||
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
|
||||
@ -81,11 +85,14 @@ namespace {
|
||||
unsigned getAddrModeSBit(const MachineInstr &MI,
|
||||
const TargetInstrDesc &TID) const;
|
||||
|
||||
void emitDataProcessingInstruction(const MachineInstr &MI);
|
||||
void emitDataProcessingInstruction(const MachineInstr &MI,
|
||||
unsigned ImplicitRn = 0);
|
||||
|
||||
void emitLoadStoreInstruction(const MachineInstr &MI);
|
||||
void emitLoadStoreInstruction(const MachineInstr &MI,
|
||||
unsigned ImplicitRn = 0);
|
||||
|
||||
void emitMiscLoadStoreInstruction(const MachineInstr &MI);
|
||||
void emitMiscLoadStoreInstruction(const MachineInstr &MI,
|
||||
unsigned ImplicitRn = 0);
|
||||
|
||||
void emitLoadStoreMultipleInstruction(const MachineInstr &MI);
|
||||
|
||||
@ -114,9 +121,9 @@ namespace {
|
||||
return (TID.TSFlags & ARMII::OpcodeMask) >> ARMII::OpcodeShift;
|
||||
}
|
||||
|
||||
/// getShiftOp - Return the shift opcode (bit[6:5]) of the machine operand.
|
||||
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
|
||||
///
|
||||
unsigned getShiftOp(const MachineOperand &MO) const ;
|
||||
unsigned getShiftOp(unsigned Imm) const ;
|
||||
|
||||
/// Routines that handle operands which add machine relocations which are
|
||||
/// fixed up by the JIT fixup stage.
|
||||
@ -165,10 +172,10 @@ bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getShiftOp - Return the shift opcode (bit[6:5]) of the machine operand.
|
||||
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
|
||||
///
|
||||
unsigned ARMCodeEmitter::getShiftOp(const MachineOperand &MO) const {
|
||||
switch (ARM_AM::getAM2ShiftOpc(MO.getImm())) {
|
||||
unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
|
||||
switch (ARM_AM::getAM2ShiftOpc(Imm)) {
|
||||
default: assert(0 && "Unknown shift opc!");
|
||||
case ARM_AM::asr: return 2;
|
||||
case ARM_AM::lsl: return 0;
|
||||
@ -246,6 +253,11 @@ void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB) {
|
||||
ARM::reloc_arm_branch, BB));
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitWordLE(unsigned Binary) {
|
||||
DOUT << "\t" << (void*)Binary << "\n";
|
||||
MCE.emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
||||
DOUT << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI;
|
||||
|
||||
@ -312,7 +324,7 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
|
||||
assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
|
||||
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
|
||||
}
|
||||
MCE.emitWordLE(0);
|
||||
emitWordLE(0);
|
||||
} else {
|
||||
Constant *CV = MCPE.Val.ConstVal;
|
||||
|
||||
@ -321,17 +333,23 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
|
||||
|
||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
|
||||
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
|
||||
MCE.emitWordLE(0);
|
||||
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);
|
||||
emitWordLE(Val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::addPCLabel(unsigned LabelID) {
|
||||
DOUT << "\t** LPC" << LabelID << " @ "
|
||||
<< (void*)MCE.getCurrentPCValue() << '\n';
|
||||
JTI->addPCLabelAddr(LabelID, MCE.getCurrentPCValue());
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
|
||||
unsigned Opcode = MI.getDesc().Opcode;
|
||||
switch (Opcode) {
|
||||
@ -342,13 +360,29 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
|
||||
break;
|
||||
case ARM::PICADD: {
|
||||
// Remember of the address of the PC label for relocation later.
|
||||
const MachineOperand &MO2 = MI.getOperand(2);
|
||||
DOUT << "\t** LPC" << MO2.getImm() << " @ "
|
||||
<< (void*)MCE.getCurrentPCValue() << '\n';
|
||||
JTI->addPCLabelAddr(MO2.getImm(), MCE.getCurrentPCValue());
|
||||
|
||||
addPCLabel(MI.getOperand(2).getImm());
|
||||
// PICADD is just an add instruction that implicitly read pc.
|
||||
emitDataProcessingInstruction(MI);
|
||||
emitDataProcessingInstruction(MI, ARM::PC);
|
||||
break;
|
||||
}
|
||||
case ARM::PICLDR:
|
||||
case ARM::PICLDRB:
|
||||
case ARM::PICSTR:
|
||||
case ARM::PICSTRB: {
|
||||
// Remember of the address of the PC label for relocation later.
|
||||
addPCLabel(MI.getOperand(2).getImm());
|
||||
// These are just load / store instructions that implicitly read pc.
|
||||
emitLoadStoreInstruction(MI, ARM::PC);
|
||||
break;
|
||||
}
|
||||
case ARM::PICLDRH:
|
||||
case ARM::PICLDRSH:
|
||||
case ARM::PICLDRSB:
|
||||
case ARM::PICSTRH: {
|
||||
// Remember of the address of the PC label for relocation later.
|
||||
addPCLabel(MI.getOperand(2).getImm());
|
||||
// These are just load / store instructions that implicitly read pc.
|
||||
emitMiscLoadStoreInstruction(MI, ARM::PC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -434,7 +468,8 @@ unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI) {
|
||||
void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
|
||||
unsigned ImplicitRn) {
|
||||
const TargetInstrDesc &TID = MI.getDesc();
|
||||
if (TID.getOpcode() == ARM::MOVi2pieces)
|
||||
abort(); // FIXME
|
||||
@ -459,9 +494,9 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI) {
|
||||
// Encode first non-shifter register operand if there is one.
|
||||
bool isUnary = TID.TSFlags & ARMII::UnaryDP;
|
||||
if (!isUnary) {
|
||||
if (TID.getOpcode() == ARM::PICADD)
|
||||
// Special handling for PICADD. It implicitly uses PC register.
|
||||
Binary |= (ARMRegisterInfo::getRegisterNumbering(ARM::PC)
|
||||
if (ImplicitRn)
|
||||
// Special handling for implicit use (e.g. PC).
|
||||
Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn)
|
||||
<< ARMII::RegRnShift);
|
||||
else {
|
||||
Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
|
||||
@ -473,13 +508,13 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI) {
|
||||
const MachineOperand &MO = MI.getOperand(OpIdx);
|
||||
if ((TID.TSFlags & ARMII::FormMask) == ARMII::DPSoRegFrm) {
|
||||
// Encode SoReg.
|
||||
MCE.emitWordLE(Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx));
|
||||
emitWordLE(Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx));
|
||||
return;
|
||||
}
|
||||
|
||||
if (MO.isReg()) {
|
||||
// Encode register Rm.
|
||||
MCE.emitWordLE(Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg()));
|
||||
emitWordLE(Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg()));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -488,10 +523,11 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI) {
|
||||
Binary |= 1 << ARMII::I_BitShift;
|
||||
Binary |= getMachineSoImmOpValue(MI, TID, MO);
|
||||
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI) {
|
||||
void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
|
||||
unsigned ImplicitRn) {
|
||||
const TargetInstrDesc &TID = MI.getDesc();
|
||||
|
||||
// Part of binary is determined by TableGn.
|
||||
@ -504,19 +540,28 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI) {
|
||||
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
|
||||
|
||||
// Set second operand
|
||||
Binary |= getMachineOpValue(MI, 1) << ARMII::RegRnShift;
|
||||
unsigned OpIdx = 1;
|
||||
if (ImplicitRn)
|
||||
// Special handling for implicit use (e.g. PC).
|
||||
Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn)
|
||||
<< ARMII::RegRnShift);
|
||||
else {
|
||||
Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
|
||||
++OpIdx;
|
||||
}
|
||||
|
||||
const MachineOperand &MO2 = MI.getOperand(2);
|
||||
const MachineOperand &MO3 = MI.getOperand(3);
|
||||
const MachineOperand &MO2 = MI.getOperand(OpIdx);
|
||||
unsigned AM2Opc = (OpIdx == TID.getNumOperands())
|
||||
? 0 : MI.getOperand(OpIdx+1).getImm();
|
||||
|
||||
// Set bit U(23) according to sign of immed value (positive or negative).
|
||||
Binary |= ((ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) <<
|
||||
Binary |= ((ARM_AM::getAM2Op(AM2Opc) == ARM_AM::add ? 1 : 0) <<
|
||||
ARMII::U_BitShift);
|
||||
if (!MO2.getReg()) { // is immediate
|
||||
if (ARM_AM::getAM2Offset(MO3.getImm()))
|
||||
if (ARM_AM::getAM2Offset(AM2Opc))
|
||||
// Set the value of offset_12 field
|
||||
Binary |= ARM_AM::getAM2Offset(MO3.getImm());
|
||||
MCE.emitWordLE(Binary);
|
||||
Binary |= ARM_AM::getAM2Offset(AM2Opc);
|
||||
emitWordLE(Binary);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -528,15 +573,16 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI) {
|
||||
|
||||
// if this instr is in scaled register offset/index instruction, set
|
||||
// shift_immed(bit[11:7]) and shift(bit[6:5]) fields.
|
||||
if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) {
|
||||
Binary |= getShiftOp(MO3) << 5; // shift
|
||||
Binary |= ShImm << 7; // shift_immed
|
||||
if (unsigned ShImm = ARM_AM::getAM2Offset(AM2Opc)) {
|
||||
Binary |= getShiftOp(AM2Opc) << 5; // shift
|
||||
Binary |= ShImm << 7; // shift_immed
|
||||
}
|
||||
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI) {
|
||||
void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
|
||||
unsigned ImplicitRn) {
|
||||
const TargetInstrDesc &TID = MI.getDesc();
|
||||
|
||||
// Part of binary is determined by TableGn.
|
||||
@ -549,37 +595,44 @@ void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI) {
|
||||
Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
|
||||
|
||||
// Set second operand
|
||||
Binary |= getMachineOpValue(MI, 1) << ARMII::RegRnShift;
|
||||
unsigned OpIdx = 1;
|
||||
if (ImplicitRn)
|
||||
// Special handling for implicit use (e.g. PC).
|
||||
Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn)
|
||||
<< ARMII::RegRnShift);
|
||||
else {
|
||||
Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
|
||||
++OpIdx;
|
||||
}
|
||||
|
||||
const MachineOperand &MO2 = MI.getOperand(2);
|
||||
const MachineOperand &MO3 = MI.getOperand(3);
|
||||
const MachineOperand &MO2 = MI.getOperand(OpIdx);
|
||||
unsigned AM3Opc = (OpIdx == TID.getNumOperands())
|
||||
? 0 : MI.getOperand(OpIdx+1).getImm();
|
||||
|
||||
// Set bit U(23) according to sign of immed value (positive or negative)
|
||||
Binary |= ((ARM_AM::getAM2Op(MO3.getImm()) == ARM_AM::add ? 1 : 0) <<
|
||||
Binary |= ((ARM_AM::getAM3Op(AM3Opc) == ARM_AM::add ? 1 : 0) <<
|
||||
ARMII::U_BitShift);
|
||||
|
||||
// If this instr is in register offset/index encoding, set bit[3:0]
|
||||
// to the corresponding Rm register.
|
||||
if (MO2.getReg()) {
|
||||
Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg());
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
return;
|
||||
}
|
||||
|
||||
// if this instr is in immediate offset/index encoding, set bit 22 to 1
|
||||
if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) {
|
||||
if (unsigned ImmOffs = ARM_AM::getAM3Offset(AM3Opc)) {
|
||||
Binary |= 1 << 22;
|
||||
// Set operands
|
||||
Binary |= (ImmOffs >> 4) << 8; // immedH
|
||||
Binary |= (ImmOffs & ~0xF); // immedL
|
||||
}
|
||||
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
||||
const TargetInstrDesc &TID = MI.getDesc();
|
||||
|
||||
// Part of binary is determined by TableGn.
|
||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||
|
||||
@ -619,7 +672,7 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
|
||||
Binary |= 0x1 << RegNum;
|
||||
}
|
||||
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitMulFrm1Instruction(const MachineInstr &MI) {
|
||||
@ -649,7 +702,7 @@ void ARMCodeEmitter::emitMulFrm1Instruction(const MachineInstr &MI) {
|
||||
// Encode Rs
|
||||
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift;
|
||||
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
|
||||
@ -670,7 +723,7 @@ void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
|
||||
Binary |= getMachineOpValue(MI, 1) << 28; // set conditional field
|
||||
}
|
||||
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
|
||||
@ -691,7 +744,7 @@ void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
|
||||
// otherwise, set the return register
|
||||
Binary |= getMachineOpValue(MI, 0);
|
||||
|
||||
MCE.emitWordLE(Binary);
|
||||
emitWordLE(Binary);
|
||||
}
|
||||
|
||||
#include "ARMGenCodeEmitter.inc"
|
||||
|
@ -235,81 +235,89 @@ class AI2<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
asm, "", pattern> {
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AXI2<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern>;
|
||||
|
||||
// loads
|
||||
class AI2ldw<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: AI2<opcod, oops, iops, f, opc, asm, pattern> {
|
||||
: I<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 1; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AXI2ldw<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 1; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AI2ldb<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: AI2<opcod, oops, iops, f, opc, asm, pattern> {
|
||||
: I<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 1; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AXI2ldb<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 1; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
|
||||
// stores
|
||||
class AI2stw<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: AI2<opcod, oops, iops, f, opc, asm, pattern> {
|
||||
: I<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 0; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AXI2stw<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 0; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AI2stb<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, list<dag> pattern>
|
||||
: AI2<opcod, oops, iops, f, opc, asm, pattern> {
|
||||
: I<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 0; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AXI2stb<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{20} = 0; // L bit
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
|
||||
// Pre-indexed loads
|
||||
@ -321,6 +329,7 @@ class AI2ldwpr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 1; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AI2ldbpr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, string cstr, list<dag> pattern>
|
||||
@ -330,6 +339,7 @@ class AI2ldbpr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 1; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
|
||||
// Pre-indexed stores
|
||||
@ -341,6 +351,7 @@ class AI2stwpr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 1; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AI2stbpr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, string cstr, list<dag> pattern>
|
||||
@ -350,6 +361,7 @@ class AI2stbpr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 1; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 1; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
|
||||
// Post-indexed loads
|
||||
@ -361,6 +373,7 @@ class AI2ldwpo<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 0; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AI2ldbpo<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, string cstr, list<dag> pattern>
|
||||
@ -370,6 +383,7 @@ class AI2ldbpo<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 0; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
|
||||
// Post-indexed stores
|
||||
@ -381,6 +395,7 @@ class AI2stwpo<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 0; // B bit
|
||||
let Inst{24} = 0; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
class AI2stbpo<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
string asm, string cstr, list<dag> pattern>
|
||||
@ -390,6 +405,7 @@ class AI2stbpo<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
let Inst{21} = 0; // W bit
|
||||
let Inst{22} = 1; // B bit
|
||||
let Inst{24} = 0; // P bit
|
||||
let Inst{27-26} = {0,1};
|
||||
}
|
||||
|
||||
// addrmode3 instructions
|
||||
@ -417,8 +433,8 @@ class AI3ldh<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
}
|
||||
class AXI3ldh<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{4} = 1;
|
||||
let Inst{5} = 1; // H bit
|
||||
let Inst{6} = 0; // S bit
|
||||
@ -441,8 +457,8 @@ class AI3ldsh<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
}
|
||||
class AXI3ldsh<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{4} = 1;
|
||||
let Inst{5} = 1; // H bit
|
||||
let Inst{6} = 1; // S bit
|
||||
@ -465,8 +481,8 @@ class AI3ldsb<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
}
|
||||
class AXI3ldsb<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{4} = 1;
|
||||
let Inst{5} = 0; // H bit
|
||||
let Inst{6} = 1; // S bit
|
||||
@ -503,8 +519,8 @@ class AI3sth<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||
}
|
||||
class AXI3sth<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
||||
list<dag> pattern>
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
|
||||
"", pattern> {
|
||||
: XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
|
||||
asm, "", pattern> {
|
||||
let Inst{4} = 1;
|
||||
let Inst{5} = 1; // H bit
|
||||
let Inst{6} = 0; // S bit
|
||||
|
@ -472,31 +472,23 @@ def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
|
||||
|
||||
let AddedComplexity = 10 in {
|
||||
let isSimpleLoad = 1 in
|
||||
def PICLD : AXI2ldw<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
def PICLDR : AXI2ldw<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tldr$p $dst, $addr",
|
||||
[(set GPR:$dst, (load addrmodepc:$addr))]>;
|
||||
|
||||
def PICLDZH : AXI3ldh<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
def PICLDRH : AXI3ldh<0xB, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
|
||||
[(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
|
||||
|
||||
def PICLDZB : AXI2ldb<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
def PICLDRB : AXI2ldb<0x1, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
|
||||
[(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
|
||||
|
||||
def PICLDH : AXI3ldh<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
|
||||
[(set GPR:$dst, (extloadi16 addrmodepc:$addr))]>;
|
||||
|
||||
def PICLDB : AXI2ldb<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
|
||||
[(set GPR:$dst, (extloadi8 addrmodepc:$addr))]>;
|
||||
|
||||
def PICLDSH : AXI3ldsh<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
def PICLDRSH : AXI3ldsh<0xE, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tldr${p}sh $dst, $addr",
|
||||
[(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
|
||||
|
||||
def PICLDSB : AXI3ldsb<0x0, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
def PICLDRSB : AXI3ldsb<0xD, (outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tldr${p}sb $dst, $addr",
|
||||
[(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
|
||||
}
|
||||
@ -505,11 +497,11 @@ def PICSTR : AXI2stw<0x0, (outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tstr$p $src, $addr",
|
||||
[(store GPR:$src, addrmodepc:$addr)]>;
|
||||
|
||||
def PICSTRH : AXI3sth<0x0, (outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
|
||||
def PICSTRH : AXI3sth<0xB, (outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tstr${p}h $src, $addr",
|
||||
[(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
|
||||
|
||||
def PICSTRB : AXI2stb<0x0, (outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
|
||||
def PICSTRB : AXI2stb<0x1, (outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
|
||||
Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr",
|
||||
[(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
|
||||
}
|
||||
@ -1219,6 +1211,9 @@ def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
|
||||
def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
|
||||
def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
|
||||
|
||||
def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
|
||||
def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
|
||||
|
||||
// smul* and smla*
|
||||
def : ARMV5TEPat<(mul (sra (shl GPR:$a, 16), 16), (sra (shl GPR:$b, 16), 16)),
|
||||
(SMULBB GPR:$a, GPR:$b)>;
|
||||
|
Loading…
Reference in New Issue
Block a user