//
def addrmode_imm12 : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
+ // 12-bit immediate operand. Note that instructions using this encode
+ // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
+ // immediate values are as normal.
string EncoderMethod = "getAddrModeImm12OpValue";
let PrintMethod = "printAddrModeImm12Operand";
// The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
multiclass APreLoad<bit data, bit read, string opc> {
- def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
- !strconcat(opc, "\t[$base, $imm]"), []> {
+ def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, NoItinerary,
+ !strconcat(opc, "\t$addr"), []> {
+ bits<4> Rt;
+ bits<17> addr;
let Inst{31-26} = 0b111101;
let Inst{25} = 0; // 0 for immediate form
let Inst{24} = data;
+ let Inst{23} = addr{12}; // U (add = ('U' == 1))
let Inst{22} = read;
let Inst{21-20} = 0b01;
+ let Inst{19-16} = addr{16-13}; // Rn
+ let Inst{15-12} = Rt;
+ let Inst{11-0} = addr{11-0}; // imm12
}
- def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary,
- !strconcat(opc, "\t$addr"), []> {
+ def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, NoItinerary,
+ !strconcat(opc, "\t$shift"), []> {
+ bits<4> Rt;
+ bits<17> shift;
let Inst{31-26} = 0b111101;
let Inst{25} = 1; // 1 for register form
let Inst{24} = data;
+ let Inst{23} = shift{12}; // U (add = ('U' == 1))
let Inst{22} = read;
let Inst{21-20} = 0b01;
- let Inst{4} = 0;
+ let Inst{19-16} = shift{16-13}; // Rn
+ let Inst{11-0} = shift{11-0};
}
}
Requires<[IsARM, IsDarwin]>;
// zextload i1 -> zextload i8
-//def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>;
def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>;
static inline bool PreLoadOpcode(unsigned Opcode) {
switch(Opcode) {
- case ARM::PLDi: case ARM::PLDr:
- case ARM::PLDWi: case ARM::PLDWr:
- case ARM::PLIi: case ARM::PLIr:
+ case ARM::PLDi12: case ARM::PLDrs:
+ case ARM::PLDWi12: case ARM::PLDWrs:
+ case ARM::PLIi12: case ARM::PLIrs:
return true;
default:
return false;
static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
- // Preload Data/Instruction requires either 2 or 4 operands.
- // PLDi, PLDWi, PLIi: Rn [+/-]imm12 add = (U == '1')
- // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: Rn Rm addrmode2_opc
+ // Preload Data/Instruction requires either 2 or 3 operands.
+ // PLDi, PLDWi, PLIi: addrmode_imm12
+ // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: ldst_so_reg
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
- if (Opcode == ARM::PLDi || Opcode == ARM::PLDWi || Opcode == ARM::PLIi) {
+ if (Opcode == ARM::PLDi12 || Opcode == ARM::PLDWi12
+ || Opcode == ARM::PLIi12) {
unsigned Imm12 = slice(insn, 11, 0);
bool Negative = getUBit(insn) == 0;
- int Offset = Negative ? -1 - Imm12 : 1 * Imm12;
- MI.addOperand(MCOperand::CreateImm(Offset));
+ // -0 is represented specially. All other values are as normal.
+ if (Imm12 == 0 && Negative)
+ Imm12 = INT32_MIN;
+ MI.addOperand(MCOperand::CreateImm(Imm12));
NumOpsAdded = 2;
} else {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,