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