forked from OSchip/llvm-project
* Add support for encoding t_addrmode_s2 and t_addrmode_s1. They are the same as
t_addrmode_s4, but with a different scaling factor. * Encode the Thumb1 load and store instructions. This involved a bit of refactoring (hi, Chris! :-). Some of the patterns became dead afterwards and were removed. llvm-svn: 120482
This commit is contained in:
parent
8335e8fa63
commit
a9e3df7aa0
|
@ -241,6 +241,10 @@ namespace {
|
|||
const { return 0; }
|
||||
uint32_t getAddrModeS4OpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
uint32_t getAddrModeS2OpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
uint32_t getAddrModeS1OpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const {
|
||||
// {17-13} = reg
|
||||
// {12} = (U)nsigned (add == '1', sub == '0')
|
||||
|
|
|
@ -863,15 +863,6 @@ class T1pIt<dag oops, dag iops, InstrItinClass itin,
|
|||
: Thumb1pI<oops, iops, AddrModeNone, Size2Bytes, itin, opc, asm,
|
||||
"$lhs = $dst", pattern>;
|
||||
|
||||
class T1pI1<dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: Thumb1pI<oops, iops, AddrModeT1_1, Size2Bytes, itin, opc, asm, "", pattern>;
|
||||
class T1pI2<dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: Thumb1pI<oops, iops, AddrModeT1_2, Size2Bytes, itin, opc, asm, "", pattern>;
|
||||
class T1pI4<dag oops, dag iops, InstrItinClass itin,
|
||||
string opc, string asm, list<dag> pattern>
|
||||
: Thumb1pI<oops, iops, AddrModeT1_4, Size2Bytes, itin, opc, asm, "", pattern>;
|
||||
class T1pIs<dag oops, dag iops,
|
||||
InstrItinClass itin, string opc, string asm, list<dag> pattern>
|
||||
: Thumb1pI<oops, iops, AddrModeT1_s, Size2Bytes, itin, opc, asm, "", pattern>;
|
||||
|
@ -909,11 +900,39 @@ class T1LoadStore<bits<4> opA, bits<3> opB> : Encoding16 {
|
|||
let Inst{11-9} = opB;
|
||||
}
|
||||
class T1LdSt<bits<3> opB> : T1LoadStore<0b0101, opB>;
|
||||
class T1LdSt4Imm<bits<3> opB> : T1LoadStore<0b0110, opB>; // Immediate, 4 bytes
|
||||
class T1LdSt1Imm<bits<3> opB> : T1LoadStore<0b0111, opB>; // Immediate, 1 byte
|
||||
class T1LdSt2Imm<bits<3> opB> : T1LoadStore<0b1000, opB>; // Immediate, 2 bytes
|
||||
class T1LdStSP<bits<3> opB> : T1LoadStore<0b1001, opB>; // SP relative
|
||||
|
||||
// Helper classes to encode Thumb1 loads and stores. For immediates, the
|
||||
// following bits are used for "opA":
|
||||
//
|
||||
// 0b0110 => Immediate, 4 bytes
|
||||
// 0b1000 => Immediate, 2 bytes
|
||||
// 0b0111 => Immediate, 1 byte
|
||||
class T1LdStImm<bits<4> opA, bits<3> opB> : T1LoadStore<opA, opB>;
|
||||
|
||||
class T1pIEncode<bits<3> opcode, dag oops, dag iops, AddrMode am,
|
||||
InstrItinClass itin, string opc, string asm,
|
||||
list<dag> pattern>
|
||||
: Thumb1pI<oops, iops, am, Size2Bytes, itin, opc, asm, "", pattern>,
|
||||
T1LdSt<opcode> {
|
||||
bits<3> Rt;
|
||||
bits<8> addr;
|
||||
let Inst{8-6} = addr{5-3}; // Rm
|
||||
let Inst{5-3} = addr{2-0}; // Rn
|
||||
let Inst{2-0} = Rt;
|
||||
}
|
||||
class T1pIEncodeImm<bits<4> opA, bit opB, dag oops, dag iops, AddrMode am,
|
||||
InstrItinClass itin, string opc, string asm,
|
||||
list<dag> pattern>
|
||||
: Thumb1pI<oops, iops, am, Size2Bytes, itin, opc, asm, "", pattern>,
|
||||
T1LdStImm<opA, {opB,?,?}> {
|
||||
bits<3> Rt;
|
||||
bits<8> addr;
|
||||
let Inst{10-6} = addr{7-3}; // imm5
|
||||
let Inst{5-3} = addr{2-0}; // Rn
|
||||
let Inst{2-0} = Rt;
|
||||
}
|
||||
|
||||
// A6.2.5 Miscellaneous 16-bit instructions encoding.
|
||||
class T1Misc<bits<7> opcode> : Encoding16 {
|
||||
let Inst{15-12} = 0b1011;
|
||||
|
|
|
@ -103,8 +103,10 @@ def t_addrmode_s4 : Operand<i32>,
|
|||
//
|
||||
def t_addrmode_s2 : Operand<i32>,
|
||||
ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> {
|
||||
string EncoderMethod = "getAddrModeS2OpValue";
|
||||
let PrintMethod = "printThumbAddrModeS2Operand";
|
||||
let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
|
||||
let ParserMatchClass = MemModeThumbAsmOperand;
|
||||
}
|
||||
|
||||
// t_addrmode_s1 := reg + reg
|
||||
|
@ -112,8 +114,10 @@ def t_addrmode_s2 : Operand<i32>,
|
|||
//
|
||||
def t_addrmode_s1 : Operand<i32>,
|
||||
ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> {
|
||||
string EncoderMethod = "getAddrModeS1OpValue";
|
||||
let PrintMethod = "printThumbAddrModeS1Operand";
|
||||
let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
|
||||
let ParserMatchClass = MemModeThumbAsmOperand;
|
||||
}
|
||||
|
||||
// t_addrmode_sp := sp + imm8 * 4
|
||||
|
@ -122,6 +126,7 @@ def t_addrmode_sp : Operand<i32>,
|
|||
ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
|
||||
let PrintMethod = "printThumbAddrModeSPOperand";
|
||||
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
|
||||
let ParserMatchClass = MemModeThumbAsmOperand;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -508,59 +513,55 @@ def tTRAP : TI<(outs), (ins), IIC_Br,
|
|||
//
|
||||
|
||||
let canFoldAsLoad = 1, isReMaterializable = 1 in
|
||||
def tLDR : T1pI4<(outs tGPR:$Rt), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
|
||||
"ldr", "\t$Rt, $addr",
|
||||
[(set tGPR:$Rt, (load t_addrmode_s4:$addr))]>,
|
||||
T1LdSt<0b100> {
|
||||
// A8.6.60
|
||||
bits<3> Rt;
|
||||
bits<8> addr;
|
||||
let Inst{8-6} = addr{5-3}; // Rm
|
||||
let Inst{5-3} = addr{2-0}; // Rn
|
||||
let Inst{2-0} = Rt;
|
||||
}
|
||||
def tLDR : // A8.6.60
|
||||
T1pIEncode<0b100, (outs tGPR:$Rt), (ins t_addrmode_s4:$addr),
|
||||
AddrModeT1_4, IIC_iLoad_r,
|
||||
"ldr", "\t$Rt, $addr",
|
||||
[(set tGPR:$Rt, (load t_addrmode_s4:$addr))]>;
|
||||
|
||||
def tLDRi: T1pI4<(outs tGPR:$Rt), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
|
||||
"ldr", "\t$Rt, $addr",
|
||||
[]>,
|
||||
T1LdSt4Imm<{1,?,?}> {
|
||||
// A8.6.57
|
||||
bits<3> Rt;
|
||||
bits<8> addr;
|
||||
let Inst{10-6} = addr{7-3}; // imm5
|
||||
let Inst{5-3} = addr{2-0}; // Rn
|
||||
let Inst{2-0} = Rt;
|
||||
}
|
||||
def tLDRi: // A8.6.57
|
||||
T1pIEncodeImm<0b0110, 1, (outs tGPR:$Rt), (ins t_addrmode_s4:$addr),
|
||||
AddrModeT1_4, IIC_iLoad_r,
|
||||
"ldr", "\t$Rt, $addr",
|
||||
[]>;
|
||||
|
||||
def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r,
|
||||
def tLDRB : // A8.6.64
|
||||
T1pIEncode<0b110, (outs tGPR:$Rt), (ins t_addrmode_s1:$addr),
|
||||
AddrModeT1_1, IIC_iLoad_bh_r,
|
||||
"ldrb", "\t$Rt, $addr",
|
||||
[(set tGPR:$Rt, (zextloadi8 t_addrmode_s1:$addr))]>;
|
||||
|
||||
def tLDRBi : // A8.6.61
|
||||
T1pIEncodeImm<0b0111, 1, (outs tGPR:$dst), (ins t_addrmode_s1:$addr),
|
||||
AddrModeT1_1, IIC_iLoad_bh_r,
|
||||
"ldrb", "\t$dst, $addr",
|
||||
[(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>,
|
||||
T1LdSt<0b110>;
|
||||
def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r,
|
||||
"ldrb", "\t$dst, $addr",
|
||||
[]>,
|
||||
T1LdSt1Imm<{1,?,?}>;
|
||||
[]>;
|
||||
|
||||
def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad_bh_r,
|
||||
def tLDRH : // A8.6.76
|
||||
T1pIEncode<0b101, (outs tGPR:$dst), (ins t_addrmode_s2:$addr),
|
||||
AddrModeT1_2, IIC_iLoad_bh_r,
|
||||
"ldrh", "\t$dst, $addr",
|
||||
[(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
|
||||
|
||||
def tLDRHi: // A8.6.73
|
||||
T1pIEncodeImm<0b1000, 1, (outs tGPR:$dst), (ins t_addrmode_s2:$addr),
|
||||
AddrModeT1_2, IIC_iLoad_bh_r,
|
||||
"ldrh", "\t$dst, $addr",
|
||||
[(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>,
|
||||
T1LdSt<0b101>;
|
||||
def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad_bh_r,
|
||||
"ldrh", "\t$dst, $addr",
|
||||
[]>,
|
||||
T1LdSt2Imm<{1,?,?}>;
|
||||
[]>;
|
||||
|
||||
let AddedComplexity = 10 in
|
||||
def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad_bh_r,
|
||||
"ldrsb", "\t$dst, $addr",
|
||||
[(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>,
|
||||
T1LdSt<0b011>;
|
||||
def tLDRSB : // A8.6.80
|
||||
T1pIEncode<0b011, (outs tGPR:$dst), (ins t_addrmode_rr:$addr),
|
||||
AddrModeT1_1, IIC_iLoad_bh_r,
|
||||
"ldrsb", "\t$dst, $addr",
|
||||
[(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
|
||||
|
||||
let AddedComplexity = 10 in
|
||||
def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad_bh_r,
|
||||
"ldrsh", "\t$dst, $addr",
|
||||
[(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>,
|
||||
T1LdSt<0b111>;
|
||||
def tLDRSH : // A8.6.84
|
||||
T1pIEncode<0b111, (outs tGPR:$dst), (ins t_addrmode_rr:$addr),
|
||||
AddrModeT1_2, IIC_iLoad_bh_r,
|
||||
"ldrsh", "\t$dst, $addr",
|
||||
[(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
|
||||
|
||||
let canFoldAsLoad = 1 in
|
||||
def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad_i,
|
||||
|
@ -590,32 +591,41 @@ def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad_i,
|
|||
"ldr", "\t$dst, $addr", []>,
|
||||
T1LdStSP<{1,?,?}>;
|
||||
|
||||
def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore_r,
|
||||
"str", "\t$src, $addr",
|
||||
[(store tGPR:$src, t_addrmode_s4:$addr)]>,
|
||||
T1LdSt<0b000>;
|
||||
def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore_r,
|
||||
"str", "\t$src, $addr",
|
||||
[]>,
|
||||
T1LdSt4Imm<{0,?,?}>;
|
||||
def tSTR : // A8.6.194
|
||||
T1pIEncode<0b000, (outs), (ins tGPR:$src, t_addrmode_s4:$addr),
|
||||
AddrModeT1_4, IIC_iStore_r,
|
||||
"str", "\t$src, $addr",
|
||||
[(store tGPR:$src, t_addrmode_s4:$addr)]>;
|
||||
|
||||
def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore_bh_r,
|
||||
"strb", "\t$src, $addr",
|
||||
[(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>,
|
||||
T1LdSt<0b010>;
|
||||
def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore_bh_r,
|
||||
"strb", "\t$src, $addr",
|
||||
[]>,
|
||||
T1LdSt1Imm<{0,?,?}>;
|
||||
def tSTRi : // A8.6.192
|
||||
T1pIEncodeImm<0b0110, 0, (outs), (ins tGPR:$src, t_addrmode_s4:$addr),
|
||||
AddrModeT1_4, IIC_iStore_r,
|
||||
"str", "\t$src, $addr",
|
||||
[]>;
|
||||
|
||||
def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore_bh_r,
|
||||
"strh", "\t$src, $addr",
|
||||
[(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>,
|
||||
T1LdSt<0b001>;
|
||||
def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore_bh_r,
|
||||
"strh", "\t$src, $addr",
|
||||
[]>,
|
||||
T1LdSt2Imm<{0,?,?}>;
|
||||
def tSTRB : // A8.6.197
|
||||
T1pIEncode<0b010, (outs), (ins tGPR:$src, t_addrmode_s1:$addr),
|
||||
AddrModeT1_1, IIC_iStore_bh_r,
|
||||
"strb", "\t$src, $addr",
|
||||
[(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>;
|
||||
|
||||
def tSTRBi : // A8.6.195
|
||||
T1pIEncodeImm<0b0111, 0, (outs), (ins tGPR:$src, t_addrmode_s1:$addr),
|
||||
AddrModeT1_1, IIC_iStore_bh_r,
|
||||
"strb", "\t$src, $addr",
|
||||
[]>;
|
||||
|
||||
def tSTRH : // A8.6.207
|
||||
T1pIEncode<0b001, (outs), (ins tGPR:$src, t_addrmode_s2:$addr),
|
||||
AddrModeT1_2, IIC_iStore_bh_r,
|
||||
"strh", "\t$src, $addr",
|
||||
[(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>;
|
||||
|
||||
def tSTRHi : // A8.6.205
|
||||
T1pIEncodeImm<0b1000, 0, (outs), (ins tGPR:$src, t_addrmode_s2:$addr),
|
||||
AddrModeT1_2, IIC_iStore_bh_r,
|
||||
"strh", "\t$src, $addr",
|
||||
[]>;
|
||||
|
||||
def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore_i,
|
||||
"str", "\t$src, $addr",
|
||||
|
|
|
@ -140,6 +140,14 @@ public:
|
|||
uint32_t getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getAddrModeS2OpValue - Return encoding for t_addrmode_s2 operands.
|
||||
uint32_t getAddrModeS2OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getAddrModeS1OpValue - Return encoding for t_addrmode_s1 operands.
|
||||
uint32_t getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
|
||||
uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
@ -545,10 +553,9 @@ getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
|
|||
return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
|
||||
}
|
||||
|
||||
/// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
/// getAddrModeSOpValue - Encode the t_addrmode_s# operands.
|
||||
static unsigned getAddrModeSOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
unsigned Scale) {
|
||||
// [Rn, Rm]
|
||||
// {5-3} = Rm
|
||||
// {2-0} = Rn
|
||||
|
@ -560,11 +567,32 @@ getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
|
|||
const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
|
||||
const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
|
||||
unsigned Rn = getARMRegisterNumbering(MO.getReg());
|
||||
unsigned Imm5 = MO1.getImm();
|
||||
unsigned Imm5 = (MO1.getImm() / Scale) & 0x1f;
|
||||
unsigned Rm = getARMRegisterNumbering(MO2.getReg());
|
||||
return (Rm << 3) | (Imm5 << 3) | Rn;
|
||||
}
|
||||
|
||||
/// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &) const {
|
||||
return getAddrModeSOpValue(MI, OpIdx, 4);
|
||||
}
|
||||
|
||||
/// getAddrModeS2OpValue - Return encoding for t_addrmode_s2 operands.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getAddrModeS2OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &) const {
|
||||
return getAddrModeSOpValue(MI, OpIdx, 2);
|
||||
}
|
||||
|
||||
/// getAddrModeS1OpValue - Return encoding for t_addrmode_s1 operands.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &) const {
|
||||
return getAddrModeSOpValue(MI, OpIdx, 1);
|
||||
}
|
||||
|
||||
/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm12' operand.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
|
|
|
@ -323,7 +323,7 @@ public:
|
|||
if (Mem.Offset) {
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
|
||||
assert(CE && "Non-constant mode offset operand!");
|
||||
Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
|
||||
Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
|
||||
Inst.addOperand(MCOperand::CreateReg(0));
|
||||
} else {
|
||||
Inst.addOperand(MCOperand::CreateImm(0));
|
||||
|
|
Loading…
Reference in New Issue