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:
Evan Cheng 2008-11-05 23:22:34 +00:00
parent ec740e325c
commit 83b5cf0272
3 changed files with 153 additions and 89 deletions

View File

@ -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"

View File

@ -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

View File

@ -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)>;