forked from OSchip/llvm-project
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);
|
||||
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)
|
||||
const { return 0;}
|
||||
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>
|
||||
: I<oops, iops, AddrMode2, Size4Bytes, im, f, itin,
|
||||
opc, asm, cstr, pattern> {
|
||||
bits<4> Rt;
|
||||
let Inst{27-26} = 0b01;
|
||||
let Inst{24} = isPre; // P bit
|
||||
let Inst{22} = isByte; // B bit
|
||||
let Inst{21} = isPre; // W bit
|
||||
let Inst{20} = isLd; // L bit
|
||||
let Inst{15-12} = Rt;
|
||||
}
|
||||
|
||||
class AXI2ldw<dag oops, dag iops, Format f, InstrItinClass itin,
|
||||
|
|
|
@ -440,6 +440,7 @@ def ldst_so_reg : Operand<i32>,
|
|||
//
|
||||
def addrmode2 : Operand<i32>,
|
||||
ComplexPattern<i32, 3, "SelectAddrMode2", []> {
|
||||
string EncoderMethod = "getAddrMode2OpValue";
|
||||
let PrintMethod = "printAddrMode2Operand";
|
||||
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
|
||||
}
|
||||
|
@ -447,6 +448,7 @@ def addrmode2 : Operand<i32>,
|
|||
def am2offset : Operand<i32>,
|
||||
ComplexPattern<i32, 2, "SelectAddrMode2Offset",
|
||||
[], [SDNPWantRoot]> {
|
||||
string EncoderMethod = "getAddrMode2OffsetOpValue";
|
||||
let PrintMethod = "printAddrMode2OffsetOperand";
|
||||
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> {
|
||||
def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb),
|
||||
(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),
|
||||
(ins GPR:$Rn, am2offset:$offset),
|
||||
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>;
|
||||
|
@ -1647,19 +1669,39 @@ def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
|
|||
"strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
|
||||
|
||||
// Indexed stores
|
||||
def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$base_wb),
|
||||
(ins GPR:$src, GPR:$base, am2offset:$offset),
|
||||
def STR_PRE : AI2ldstidx<0, 0, 1, (outs GPR:$Rn_wb),
|
||||
(ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
|
||||
IndexModePre, StFrm, IIC_iStore_ru,
|
||||
"str", "\t$src, [$base, $offset]!", "$base = $base_wb",
|
||||
[(set GPR:$base_wb,
|
||||
(pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
|
||||
"str", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
|
||||
[(set GPR:$Rn_wb,
|
||||
(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),
|
||||
(ins GPR:$src, GPR:$base,am2offset:$offset),
|
||||
def STR_POST : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
|
||||
(ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
|
||||
IndexModePost, StFrm, IIC_iStore_ru,
|
||||
"str", "\t$src, [$base], $offset", "$base = $base_wb",
|
||||
[(set GPR:$base_wb,
|
||||
(post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
|
||||
"str", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
|
||||
[(set GPR:$Rn_wb,
|
||||
(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),
|
||||
(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,
|
||||
GPR:$base, am3offset:$offset))]>;
|
||||
|
||||
def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$base_wb),
|
||||
(ins GPR:$src, GPR:$base,am2offset:$offset),
|
||||
def STRB_PRE : AI2ldstidx<0, 1, 1, (outs GPR:$Rn_wb),
|
||||
(ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
|
||||
IndexModePre, StFrm, IIC_iStore_bh_ru,
|
||||
"strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
|
||||
[(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
|
||||
GPR:$base, am2offset:$offset))]>;
|
||||
"strb", "\t$Rt, [$Rn, $offset]!", "$Rn = $Rn_wb",
|
||||
[(set GPR:$Rn_wb, (pre_truncsti8 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 STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$base_wb),
|
||||
(ins GPR:$src, GPR:$base,am2offset:$offset),
|
||||
def STRB_POST: AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
|
||||
(ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
|
||||
IndexModePost, StFrm, IIC_iStore_bh_ru,
|
||||
"strb", "\t$src, [$base], $offset", "$base = $base_wb",
|
||||
[(set GPR:$base_wb, (post_truncsti8 GPR:$src,
|
||||
GPR:$base, am2offset:$offset))]>;
|
||||
"strb", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
|
||||
[(set GPR:$Rn_wb, (post_truncsti8 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};
|
||||
}
|
||||
|
||||
// For disassembly only
|
||||
def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
|
||||
|
|
|
@ -101,6 +101,29 @@ public:
|
|||
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.
|
||||
uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
@ -380,24 +403,10 @@ getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
|
|||
const MCOperand &MO2 = MI.getOperand(OpIdx+2);
|
||||
unsigned Rn = getARMRegisterNumbering(MO.getReg());
|
||||
unsigned Rm = getARMRegisterNumbering(MO1.getReg());
|
||||
ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
|
||||
unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
|
||||
bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
|
||||
unsigned SBits;
|
||||
// LSL - 00
|
||||
// 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;
|
||||
}
|
||||
ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
|
||||
unsigned SBits = getShiftOp(ShOp);
|
||||
|
||||
// {16-13} = Rn
|
||||
// {12} = isAdd
|
||||
|
@ -415,6 +424,42 @@ getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
|
|||
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::
|
||||
getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
|
|
Loading…
Reference in New Issue