Refactor and improve the encodings/decodings for addrmode3 loads, and make the writeb...
authorOwen Anderson <resistor@mac.com>
Wed, 27 Jul 2011 23:36:57 +0000 (23:36 +0000)
committerOwen Anderson <resistor@mac.com>
Wed, 27 Jul 2011 23:36:57 +0000 (23:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136295 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp

index 722fff7d1c58c79b50b170b84771e477b4948084..6641cbd073b1f1a254c6a71368ecb2f60eca1a7b 100644 (file)
@@ -1863,7 +1863,7 @@ defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
 }
 
 multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
-  def _PRE  : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
+  def _PRE  : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rn_wb, GPR:$Rt),
                         (ins addrmode3:$addr), IndexModePre,
                         LdMiscFrm, itin,
                         opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
@@ -1874,7 +1874,7 @@ multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
     let Inst{11-8}  = addr{7-4};    // imm7_4/zero
     let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
   }
-  def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
+  def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rn_wb, GPR:$Rt),
                         (ins GPR:$Rn, am3offset:$offset), IndexModePost,
                         LdMiscFrm, itin,
                         opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
@@ -1893,7 +1893,7 @@ defm LDRH  : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
 defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
 defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
 let hasExtraDefRegAllocReq = 1 in {
-def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
+def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2),
                           (ins addrmode3:$addr), IndexModePre,
                           LdMiscFrm, IIC_iLoad_d_ru,
                           "ldrd", "\t$Rt, $Rt2, $addr!",
@@ -1904,8 +1904,9 @@ def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
   let Inst{19-16} = addr{12-9};   // Rn
   let Inst{11-8}  = addr{7-4};    // imm7_4/zero
   let Inst{3-0}   = addr{3-0};    // imm3_0/Rm
+  let DecoderMethod = "DecodeAddrMode3Instruction";
 }
-def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
+def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2),
                           (ins GPR:$Rn, am3offset:$offset), IndexModePost,
                           LdMiscFrm, IIC_iLoad_d_ru,
                           "ldrd", "\t$Rt, $Rt2, [$Rn], $offset",
@@ -1917,6 +1918,7 @@ def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
   let Inst{19-16} = Rn;
   let Inst{11-8}  = offset{7-4};    // imm7_4/zero
   let Inst{3-0}   = offset{3-0};    // imm3_0/Rm
+  let DecoderMethod = "DecodeAddrMode3Instruction";
 }
 } // hasExtraDefRegAllocReq = 1
 } // mayLoad = 1, neverHasSideEffects = 1
@@ -1953,17 +1955,17 @@ def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
   let Inst{11-0} = addr{11-0};
   let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
 }
-def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
+def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt),
              (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
              "ldrsbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
   let Inst{21} = 1; // overwrite
 }
-def LDRHT  : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
+def LDRHT  : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt),
              (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
              "ldrht", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
   let Inst{21} = 1; // overwrite
 }
-def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
+def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt),
              (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
              "ldrsht", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
   let Inst{21} = 1; // overwrite
@@ -1981,7 +1983,10 @@ def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
 def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr),
                StMiscFrm, IIC_iStore_d_r,
-               "strd", "\t$Rt, $src2, $addr", []>, Requires<[IsARM, HasV5TE]>;
+               "strd", "\t$Rt, $src2, $addr", []>,
+               Requires<[IsARM, HasV5TE]> {
+  let Inst{21} = 0;
+}
 
 // Indexed stores
 def STR_PRE_REG  : AI2stridx_reg<0, 1, (outs GPR:$Rn_wb),
@@ -2070,14 +2075,38 @@ def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
                      (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
                      StMiscFrm, IIC_iStore_d_ru,
                      "strd", "\t$src1, $src2, [$base, $offset]!",
-                     "$base = $base_wb", []>;
+                     "$base = $base_wb", []> {
+  bits<4> src1;
+  bits<4> base;
+  bits<10> offset;
+  let Inst{23} = offset{8}; // U bit
+  let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
+  let Inst{19-16} = base;
+  let Inst{15-12} = src1;
+  let Inst{11-8}  = offset{7-4};
+  let Inst{3-0}   = offset{3-0};
+
+  let DecoderMethod = "DecodeAddrMode3Instruction";
+}
 
 // For disassembly only
 def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
                      (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
                      StMiscFrm, IIC_iStore_d_ru,
                      "strd", "\t$src1, $src2, [$base], $offset",
-                     "$base = $base_wb", []>;
+                     "$base = $base_wb", []> {
+  bits<4> src1;
+  bits<4> base;
+  bits<10> offset;
+  let Inst{23} = offset{8}; // U bit
+  let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
+  let Inst{19-16} = base;
+  let Inst{15-12} = src1;
+  let Inst{11-8}  = offset{7-4};
+  let Inst{3-0}   = offset{3-0};
+
+  let DecoderMethod = "DecodeAddrMode3Instruction";
+}
 } // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
 
 // STRT, STRBT, and STRHT are for disassembly only.
index bbeec1cac4381d0793f84c09f099f62f0c77898f..fd19d671d94d3813117b00c2194b761dfe46f1d2 100644 (file)
@@ -1919,11 +1919,9 @@ cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
 bool ARMAsmParser::
 cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
                          const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
-
   // Create a writeback register dummy placeholder.
   Inst.addOperand(MCOperand::CreateImm(0));
-
+  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
   ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
   ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
   return true;
index 1f3920bd8cf21e54eed677639e1f53d65597afaf..e8c2102c3d61fa60219a88858d4f53a37d5b241a 100644 (file)
@@ -1460,7 +1460,7 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
          && "Invalid arguments");
 
   // Operand 0 of a pre- and post-indexed store is the address base writeback.
-  if (isPrePost && isStore) {
+  if (isPrePost) {
     assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
            "Reg operand expected");
     MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -1485,15 +1485,6 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     ++OpIdx;
   }
 
-  // After dst of a pre- and post-indexed load is the address base writeback.
-  if (isPrePost && !isStore) {
-    assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
-           "Reg operand expected");
-    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
-                                                       decodeRn(insn))));
-    ++OpIdx;
-  }
-
   // Disassemble the base operand.
   if (OpIdx >= NumOps)
     return false;