ARM LDR_PRE/LDR_POST/STR_PRE/STR_POST (and the *B counterparts) binary encoding.
llvm-svn: 119180
This commit is contained in:
parent
db73d599b7
commit
38b469effd
|
|
@ -214,6 +214,10 @@ namespace {
|
||||||
Binary |= (Reg << 13);
|
Binary |= (Reg << 13);
|
||||||
return Binary;
|
return Binary;
|
||||||
}
|
}
|
||||||
|
uint32_t getAddrMode2OpValue(const MachineInstr &MI, unsigned OpIdx)
|
||||||
|
const { return 0;}
|
||||||
|
uint32_t getAddrMode2OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
|
||||||
|
const { return 0;}
|
||||||
uint32_t getAddrMode3OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
|
uint32_t getAddrMode3OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
|
||||||
const { return 0;}
|
const { return 0;}
|
||||||
uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op) const
|
uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op) const
|
||||||
|
|
|
||||||
|
|
@ -438,11 +438,13 @@ class AI2ldstidx<bit isLd, bit isByte, bit isPre, dag oops, dag iops,
|
||||||
string asm, string cstr, list<dag> pattern>
|
string asm, string cstr, list<dag> pattern>
|
||||||
: I<oops, iops, AddrMode2, Size4Bytes, im, f, itin,
|
: I<oops, iops, AddrMode2, Size4Bytes, im, f, itin,
|
||||||
opc, asm, cstr, pattern> {
|
opc, asm, cstr, pattern> {
|
||||||
|
bits<4> Rt;
|
||||||
let Inst{27-26} = 0b01;
|
let Inst{27-26} = 0b01;
|
||||||
let Inst{24} = isPre; // P bit
|
let Inst{24} = isPre; // P bit
|
||||||
let Inst{22} = isByte; // B bit
|
let Inst{22} = isByte; // B bit
|
||||||
let Inst{21} = isPre; // W bit
|
let Inst{21} = isPre; // W bit
|
||||||
let Inst{20} = isLd; // L bit
|
let Inst{20} = isLd; // L bit
|
||||||
|
let Inst{15-12} = Rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AXI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
|
class AXI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
|
||||||
|
|
|
||||||
|
|
@ -440,6 +440,7 @@ def ldst_so_reg : Operand<i32>,
|
||||||
//
|
//
|
||||||
def addrmode2 : Operand<i32>,
|
def addrmode2 : Operand<i32>,
|
||||||
ComplexPattern<i32, 3, "SelectAddrMode2", []> {
|
ComplexPattern<i32, 3, "SelectAddrMode2", []> {
|
||||||
|
string EncoderMethod = "getAddrMode2OpValue";
|
||||||
let PrintMethod = "printAddrMode2Operand";
|
let PrintMethod = "printAddrMode2Operand";
|
||||||
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
|
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
|
||||||
}
|
}
|
||||||
|
|
@ -447,6 +448,7 @@ def addrmode2 : Operand<i32>,
|
||||||
def am2offset : Operand<i32>,
|
def am2offset : Operand<i32>,
|
||||||
ComplexPattern<i32, 2, "SelectAddrMode2Offset",
|
ComplexPattern<i32, 2, "SelectAddrMode2Offset",
|
||||||
[], [SDNPWantRoot]> {
|
[], [SDNPWantRoot]> {
|
||||||
|
string EncoderMethod = "getAddrMode2OffsetOpValue";
|
||||||
let PrintMethod = "printAddrMode2OffsetOperand";
|
let PrintMethod = "printAddrMode2OffsetOperand";
|
||||||
let MIOperandInfo = (ops GPR, i32imm);
|
let MIOperandInfo = (ops GPR, i32imm);
|
||||||
}
|
}
|
||||||
|
|
@ -1550,11 +1552,31 @@ def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
|
||||||
multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
|
multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> {
|
||||||
def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
|
def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
|
||||||
(ins addrmode2:$addr), IndexModePre, LdFrm, itin,
|
(ins addrmode2:$addr), IndexModePre, LdFrm, itin,
|
||||||
opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>;
|
opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
|
||||||
|
// {17-14} Rn
|
||||||
|
// {13} 1 == Rm, 0 == imm12
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
bits<18> addr;
|
||||||
|
let Inst{25} = addr{13};
|
||||||
|
let Inst{23} = addr{12};
|
||||||
|
let Inst{19-16} = addr{17-14};
|
||||||
|
let Inst{11-0} = addr{11-0};
|
||||||
|
}
|
||||||
def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
|
def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
|
||||||
(ins GPR:$Rn, am2offset:$offset),
|
(ins GPR:$Rn, am2offset:$offset),
|
||||||
IndexModePost, LdFrm, itin,
|
IndexModePost, LdFrm, itin,
|
||||||
opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []>;
|
opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
|
||||||
|
// {13} 1 == Rm, 0 == imm12
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
bits<14> offset;
|
||||||
|
bits<4> Rn;
|
||||||
|
let Inst{25} = offset{13};
|
||||||
|
let Inst{23} = offset{12};
|
||||||
|
let Inst{19-16} = Rn;
|
||||||
|
let Inst{11-0} = offset{11-0};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
|
defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>;
|
||||||
|
|
@ -1647,19 +1669,39 @@ def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
|
||||||
"strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
|
"strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
|
||||||
|
|
||||||
// Indexed stores
|
// Indexed stores
|
||||||
def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$base_wb),
|
def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$Rn_wb),
|
||||||
(ins GPR:$src, GPR:$base, am2offset:$offset),
|
(ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
|
||||||
IndexModePre, StFrm, IIC_iStore_ru,
|
IndexModePre, StFrm, IIC_iStore_ru,
|
||||||
"str", "\t$src, [$base, $offset]!", "$base = $base_wb",
|
"str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
|
||||||
[(set GPR:$base_wb,
|
[(set GPR:$Rn_wb,
|
||||||
(pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
|
(pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]> {
|
||||||
|
// {13} 1 == Rm, 0 == imm12
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
bits<14> offset;
|
||||||
|
bits<4> Rn;
|
||||||
|
let Inst{25} = offset{13};
|
||||||
|
let Inst{23} = offset{12};
|
||||||
|
let Inst{19-16} = Rn;
|
||||||
|
let Inst{11-0} = offset{11-0};
|
||||||
|
}
|
||||||
|
|
||||||
def STR_POST : AI2ldstidx<0, 0, 0, (outs GPR:$base_wb),
|
def STR_POST : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
|
||||||
(ins GPR:$src, GPR:$base,am2offset:$offset),
|
(ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
|
||||||
IndexModePost, StFrm, IIC_iStore_ru,
|
IndexModePost, StFrm, IIC_iStore_ru,
|
||||||
"str", "\t$src, [$base], $offset", "$base = $base_wb",
|
"str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
|
||||||
[(set GPR:$base_wb,
|
[(set GPR:$Rn_wb,
|
||||||
(post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
|
(post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]> {
|
||||||
|
// {13} 1 == Rm, 0 == imm12
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
bits<14> offset;
|
||||||
|
bits<4> Rn;
|
||||||
|
let Inst{25} = offset{13};
|
||||||
|
let Inst{23} = offset{12};
|
||||||
|
let Inst{19-16} = Rn;
|
||||||
|
let Inst{11-0} = offset{11-0};
|
||||||
|
}
|
||||||
|
|
||||||
def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
|
def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
|
||||||
(ins GPR:$src, GPR:$base,am3offset:$offset),
|
(ins GPR:$src, GPR:$base,am3offset:$offset),
|
||||||
|
|
@ -1675,19 +1717,39 @@ def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
|
||||||
[(set GPR:$base_wb, (post_truncsti16 GPR:$src,
|
[(set GPR:$base_wb, (post_truncsti16 GPR:$src,
|
||||||
GPR:$base, am3offset:$offset))]>;
|
GPR:$base, am3offset:$offset))]>;
|
||||||
|
|
||||||
def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$base_wb),
|
def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$Rn_wb),
|
||||||
(ins GPR:$src, GPR:$base,am2offset:$offset),
|
(ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
|
||||||
IndexModePre, StFrm, IIC_iStore_bh_ru,
|
IndexModePre, StFrm, IIC_iStore_bh_ru,
|
||||||
"strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
|
"strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
|
||||||
[(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
|
[(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt,
|
||||||
GPR:$base, am2offset:$offset))]>;
|
GPR:$Rn, am2offset:$offset))]> {
|
||||||
|
// {13} 1 == Rm, 0 == imm12
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
bits<14> offset;
|
||||||
|
bits<4> Rn;
|
||||||
|
let Inst{25} = offset{13};
|
||||||
|
let Inst{23} = offset{12};
|
||||||
|
let Inst{19-16} = Rn;
|
||||||
|
let Inst{11-0} = offset{11-0};
|
||||||
|
}
|
||||||
|
|
||||||
def STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$base_wb),
|
def STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
|
||||||
(ins GPR:$src, GPR:$base,am2offset:$offset),
|
(ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
|
||||||
IndexModePost, StFrm, IIC_iStore_bh_ru,
|
IndexModePost, StFrm, IIC_iStore_bh_ru,
|
||||||
"strb", "\t$src, [$base], $offset", "$base = $base_wb",
|
"strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
|
||||||
[(set GPR:$base_wb, (post_truncsti8 GPR:$src,
|
[(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt,
|
||||||
GPR:$base, am2offset:$offset))]>;
|
GPR:$Rn, am2offset:$offset))]> {
|
||||||
|
// {13} 1 == Rm, 0 == imm12
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
bits<14> offset;
|
||||||
|
bits<4> Rn;
|
||||||
|
let Inst{25} = offset{13};
|
||||||
|
let Inst{23} = offset{12};
|
||||||
|
let Inst{19-16} = Rn;
|
||||||
|
let Inst{11-0} = offset{11-0};
|
||||||
|
}
|
||||||
|
|
||||||
// For disassembly only
|
// For disassembly only
|
||||||
def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
|
def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,29 @@ public:
|
||||||
case ARM_AM::ib: return 3;
|
case ARM_AM::ib: return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
|
||||||
|
///
|
||||||
|
unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
|
||||||
|
switch (ShOpc) {
|
||||||
|
default: llvm_unreachable("Unknown shift opc!");
|
||||||
|
case ARM_AM::no_shift:
|
||||||
|
case ARM_AM::lsl: return 0;
|
||||||
|
case ARM_AM::lsr: return 1;
|
||||||
|
case ARM_AM::asr: return 2;
|
||||||
|
case ARM_AM::ror:
|
||||||
|
case ARM_AM::rrx: return 3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// getAddrMode2OpValue - Return encoding for addrmode2 operands.
|
||||||
|
uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
|
|
||||||
|
/// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
|
||||||
|
uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
|
|
||||||
/// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
|
/// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
|
||||||
uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
|
|
@ -380,24 +403,10 @@ getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
const MCOperand &MO2 = MI.getOperand(OpIdx+2);
|
const MCOperand &MO2 = MI.getOperand(OpIdx+2);
|
||||||
unsigned Rn = getARMRegisterNumbering(MO.getReg());
|
unsigned Rn = getARMRegisterNumbering(MO.getReg());
|
||||||
unsigned Rm = getARMRegisterNumbering(MO1.getReg());
|
unsigned Rm = getARMRegisterNumbering(MO1.getReg());
|
||||||
ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
|
|
||||||
unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
|
unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
|
||||||
bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
|
bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
|
||||||
unsigned SBits;
|
ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
|
||||||
// LSL - 00
|
unsigned SBits = getShiftOp(ShOp);
|
||||||
// LSR - 01
|
|
||||||
// ASR - 10
|
|
||||||
// ROR - 11
|
|
||||||
switch (ShOp) {
|
|
||||||
default: llvm_unreachable("Unknown shift opc!");
|
|
||||||
case ARM_AM::no_shift:
|
|
||||||
assert(ShImm == 0 && "Non-zero shift amount with no shift type!");
|
|
||||||
// fall through
|
|
||||||
case ARM_AM::lsl: SBits = 0x0; break;
|
|
||||||
case ARM_AM::lsr: SBits = 0x1; break;
|
|
||||||
case ARM_AM::asr: SBits = 0x2; break;
|
|
||||||
case ARM_AM::ror: SBits = 0x3; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// {16-13} = Rn
|
// {16-13} = Rn
|
||||||
// {12} = isAdd
|
// {12} = isAdd
|
||||||
|
|
@ -415,6 +424,42 @@ getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
return Binary;
|
return Binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ARMMCCodeEmitter::
|
||||||
|
getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
|
// {17-14} Rn
|
||||||
|
// {13} 1 == imm12, 0 == Rm
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
const MCOperand &MO = MI.getOperand(OpIdx);
|
||||||
|
unsigned Rn = getARMRegisterNumbering(MO.getReg());
|
||||||
|
uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
|
||||||
|
Binary |= Rn << 14;
|
||||||
|
return Binary;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ARMMCCodeEmitter::
|
||||||
|
getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
|
// {13} 1 == imm12, 0 == Rm
|
||||||
|
// {12} isAdd
|
||||||
|
// {11-0} imm12/Rm
|
||||||
|
const MCOperand &MO = MI.getOperand(OpIdx);
|
||||||
|
const MCOperand &MO1 = MI.getOperand(OpIdx+1);
|
||||||
|
unsigned Imm = MO1.getImm();
|
||||||
|
bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
|
||||||
|
bool isReg = MO.getReg() != 0;
|
||||||
|
uint32_t Binary = ARM_AM::getAM2Offset(Imm);
|
||||||
|
// if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
|
||||||
|
if (isReg) {
|
||||||
|
ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
|
||||||
|
Binary <<= 7; // Shift amount is bits [11:7]
|
||||||
|
Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
|
||||||
|
Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0]
|
||||||
|
}
|
||||||
|
return Binary | (isAdd << 12) | (isReg << 13);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ARMMCCodeEmitter::
|
uint32_t ARMMCCodeEmitter::
|
||||||
getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue