[llvm] r199032 - ARM: change implicit immediate forms of {ld, st}r{, b}t to psuedo-instructions

Saleem Abdulrasool compnerd at compnerd.org
Sat Jan 11 20:36:02 PST 2014


Author: compnerd
Date: Sat Jan 11 22:36:01 2014
New Revision: 199032

URL: http://llvm.org/viewvc/llvm-project?rev=199032&view=rev
Log:
ARM: change implicit immediate forms of {ld,st}r{,b}t to psuedo-instructions

The implicit immediate 0 forms are assembly aliases, not distinct instruction
encodings.  Fix the initial implementation introduced in r198914 to an alias to
avoid two separate instruction definitions for the same encoding.

An InstAlias is insufficient in this case as the necessary due to the need to
add a new additional operand for the implicit zero.  By using the AsmPsuedoInst,
fall back to the C++ code to transform the instruction to the equivalent
_POST_IMM form, inserting the additional implicit immediate 0.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/test/MC/ARM/arm_addrmode2.s
    llvm/trunk/test/MC/Disassembler/ARM/addrmode2-reencoding.txt

Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=199032&r1=199031&r2=199032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Sat Jan 11 22:36:01 2014
@@ -329,10 +329,10 @@ class InstThumb<AddrMode am, int sz, Ind
 // Pseudo-instructions for alternate assembly syntax (never used by codegen).
 // These are aliases that require C++ handling to convert to the target
 // instruction, while InstAliases can be handled directly by tblgen.
-class AsmPseudoInst<string asm, dag iops>
+class AsmPseudoInst<string asm, dag iops, dag oops = (outs)>
   : InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
                  "", NoItinerary> {
-  let OutOperandList = (outs);
+  let OutOperandList = oops;
   let InOperandList = iops;
   let Pattern = [];
   let isCodeGenOnly = 0; // So we get asm matcher for it.
@@ -340,16 +340,16 @@ class AsmPseudoInst<string asm, dag iops
   let isPseudo = 1;
 }
 
-class ARMAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
-        Requires<[IsARM]>;
-class tAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
-        Requires<[IsThumb]>;
-class t2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
-        Requires<[IsThumb2]>;
-class VFP2AsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
-        Requires<[HasVFP2]>;
-class NEONAsmPseudo<string asm, dag iops> : AsmPseudoInst<asm, iops>,
-        Requires<[HasNEON]>;
+class ARMAsmPseudo<string asm, dag iops, dag oops = (outs)>
+  : AsmPseudoInst<asm, iops, oops>, Requires<[IsARM]>;
+class tAsmPseudo<string asm, dag iops, dag oops = (outs)>
+  : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb]>;
+class t2AsmPseudo<string asm, dag iops, dag oops = (outs)>
+  : AsmPseudoInst<asm, iops, oops>, Requires<[IsThumb2]>;
+class VFP2AsmPseudo<string asm, dag iops, dag oops = (outs)>
+  : AsmPseudoInst<asm, iops, oops>, Requires<[HasVFP2]>;
+class NEONAsmPseudo<string asm, dag iops, dag oops = (outs)>
+  : AsmPseudoInst<asm, iops, oops>, Requires<[HasNEON]>;
 
 // Pseudo instructions for the code generator.
 class PseudoInst<dag oops, dag iops, InstrItinClass itin, list<dag> pattern>

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=199032&r1=199031&r2=199032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Sat Jan 11 22:36:01 2014
@@ -2450,30 +2450,23 @@ def LDRT_POST_REG : AI2ldstidx<1, 0, 0,
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
 
-class LDRTImmediate<bit has_offset, string args, dag iops>
-  : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), iops,
+def LDRT_POST_IMM
+  : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb),
+               (ins addr_offset_none:$addr, am2offset_imm:$offset),
                IndexModePost, LdFrm, IIC_iLoad_ru,
-               "ldrt", args, "$addr.base = $Rn_wb", []> {
+               "ldrt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
   // {12}     isAdd
   // {11-0}   imm12/Rm
   bits<14> offset;
   bits<4> addr;
   let Inst{25} = 0;
-  let Inst{23} = !if(has_offset, offset{12}, 1);
+  let Inst{23} = offset{12};
   let Inst{21} = 1; // overwrite
   let Inst{19-16} = addr;
-  let Inst{11-0} = !if(has_offset, offset{11-0}, 0);
-}
-
-def LDRT_POST_IMM
-  : LDRTImmediate<1, "\t$Rt, $addr, $offset",
-                  (ins addr_offset_none:$addr, am2offset_imm:$offset)> {
+  let Inst{11-0} = offset{11-0};
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
 
-def LDRT_POST_IMM_0
-  : LDRTImmediate<0, "\t$Rt, $addr", (ins addr_offset_none:$addr)>;
-
 def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
                      (ins addr_offset_none:$addr, am2offset_reg:$offset),
                      IndexModePost, LdFrm, IIC_iLoad_bh_ru,
@@ -2493,30 +2486,23 @@ def LDRBT_POST_REG : AI2ldstidx<1, 1, 0,
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
 
-class LDRBTImmediate<bit has_offset, string args, dag iops>
-  : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), iops,
-                    IndexModePost, LdFrm, IIC_iLoad_bh_ru,
-                    "ldrbt", args, "$addr.base = $Rn_wb", []> {
+def LDRBT_POST_IMM
+  : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
+               (ins addr_offset_none:$addr, am2offset_imm:$offset),
+               IndexModePost, LdFrm, IIC_iLoad_bh_ru,
+               "ldrbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
   // {12}     isAdd
   // {11-0}   imm12/Rm
   bits<14> offset;
   bits<4> addr;
   let Inst{25} = 0;
-  let Inst{23} = !if(has_offset, offset{12}, 1);
+  let Inst{23} = offset{12};
   let Inst{21} = 1; // overwrite
   let Inst{19-16} = addr;
-  let Inst{11-0} = !if(has_offset, offset{11-0}, 0);
-}
-
-def LDRBT_POST_IMM
-  : LDRBTImmediate<1, "\t$Rt, $addr, $offset",
-                   (ins addr_offset_none:$addr, am2offset_imm:$offset)> {
+  let Inst{11-0} = offset{11-0};
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
 
-def LDRBT_POST_IMM_0
-  : LDRBTImmediate<0, "\t$Rt, $addr", (ins addr_offset_none:$addr)>;
-
 multiclass AI3ldrT<bits<4> op, string opc> {
   def i : AI3ldstidxT<op, 1, (outs GPR:$Rt, GPR:$base_wb),
                       (ins addr_offset_none:$addr, postidx_imm8:$offset),
@@ -2547,6 +2533,14 @@ defm LDRHT  : AI3ldrT<0b1011, "ldrht">;
 defm LDRSHT : AI3ldrT<0b1111, "ldrsht">;
 }
 
+def LDRT_POST
+  : ARMAsmPseudo<"ldrt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q),
+                 (outs GPR:$Rt)>;
+
+def LDRBT_POST
+  : ARMAsmPseudo<"ldrbt${q} $Rt, $addr", (ins addr_offset_none:$addr, pred:$q),
+                 (outs GPR:$Rt)>;
+
 // Store
 
 // Stores with truncate
@@ -2777,29 +2771,26 @@ def STRBT_POST_REG : AI2ldstidx<0, 1, 0,
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
 
-class STRBTImmediate<bit has_offset, string args, dag iops>
-  : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), iops, IndexModePost, StFrm,
-               IIC_iStore_bh_ru, "strbt", args, "$addr.base = $Rn_wb", []> {
+def STRBT_POST_IMM
+  : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb),
+               (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
+               IndexModePost, StFrm, IIC_iStore_bh_ru,
+               "strbt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
   // {12}     isAdd
   // {11-0}   imm12/Rm
   bits<14> offset;
   bits<4> addr;
   let Inst{25} = 0;
-  let Inst{23} = !if(has_offset, offset{12}, 1);
+  let Inst{23} = offset{12};
   let Inst{21} = 1; // overwrite
   let Inst{19-16} = addr;
-  let Inst{11-0} = !if(has_offset, offset{11-0}, 0);
-}
-
-def STRBT_POST_IMM
-  : STRBTImmediate<1, "\t$Rt, $addr, $offset",
-                 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset)> {
+  let Inst{11-0} = offset{11-0};
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
 
-
-def STRBT_POST_IMM_0
-  : STRBTImmediate<0, "\t$Rt, $addr", (ins GPR:$Rt, addr_offset_none:$addr)>;
+def STRBT_POST
+  : ARMAsmPseudo<"strbt${q} $Rt, $addr",
+                 (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>;
 
 let mayStore = 1, neverHasSideEffects = 1 in {
 def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
@@ -2821,30 +2812,27 @@ def STRT_POST_REG : AI2ldstidx<0, 0, 0,
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
 
-class STRTImmediate<bit has_offset, string args, dag iops>
-  : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), iops, IndexModePost, StFrm,
-               IIC_iStore_ru, "strt", args, "$addr.base = $Rn_wb", []> {
+def STRT_POST_IMM
+  : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb),
+               (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset),
+               IndexModePost, StFrm, IIC_iStore_ru,
+               "strt", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", []> {
   // {12}     isAdd
   // {11-0}   imm12/Rm
   bits<14> offset;
   bits<4> addr;
   let Inst{25} = 0;
-  let Inst{23} = !if(has_offset, offset{12}, 1);
+  let Inst{23} = offset{12};
   let Inst{21} = 1; // overwrite
   let Inst{19-16} = addr;
-  let Inst{11-0} = !if(has_offset, offset{11-0}, 0);
-}
-
-def STRT_POST_IMM
-  : STRTImmediate<1, "\t$Rt, $addr, $offset",
-                 (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset)> {
+  let Inst{11-0} = offset{11-0};
   let DecoderMethod = "DecodeAddrMode2IdxInstruction";
 }
-
-def STRT_POST_IMM_0
-  : STRTImmediate<0, "\t$Rt, $addr", (ins GPR:$Rt, addr_offset_none:$addr)>;
 }
 
+def STRT_POST
+  : ARMAsmPseudo<"strt${q} $Rt, $addr",
+                 (ins GPR:$Rt, addr_offset_none:$addr, pred:$q)>;
 
 multiclass AI3strT<bits<4> op, string opc> {
   def i : AI3ldstidxT<op, 0, (outs GPR:$base_wb),

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=199032&r1=199031&r2=199032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Sat Jan 11 22:36:01 2014
@@ -6055,6 +6055,42 @@ bool ARMAsmParser::
 processInstruction(MCInst &Inst,
                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   switch (Inst.getOpcode()) {
+  // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
+  case ARM::LDRT_POST:
+  case ARM::LDRBT_POST: {
+    const unsigned Opcode =
+      (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
+                                           : ARM::LDRBT_POST_IMM;
+    MCInst TmpInst;
+    TmpInst.setOpcode(Opcode);
+    TmpInst.addOperand(Inst.getOperand(0));
+    TmpInst.addOperand(Inst.getOperand(1));
+    TmpInst.addOperand(Inst.getOperand(1));
+    TmpInst.addOperand(MCOperand::CreateReg(0));
+    TmpInst.addOperand(MCOperand::CreateImm(0));
+    TmpInst.addOperand(Inst.getOperand(2));
+    TmpInst.addOperand(Inst.getOperand(3));
+    Inst = TmpInst;
+    return true;
+  }
+  // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction.
+  case ARM::STRT_POST:
+  case ARM::STRBT_POST: {
+    const unsigned Opcode =
+      (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
+                                           : ARM::STRBT_POST_IMM;
+    MCInst TmpInst;
+    TmpInst.setOpcode(Opcode);
+    TmpInst.addOperand(Inst.getOperand(1));
+    TmpInst.addOperand(Inst.getOperand(0));
+    TmpInst.addOperand(Inst.getOperand(1));
+    TmpInst.addOperand(MCOperand::CreateReg(0));
+    TmpInst.addOperand(MCOperand::CreateImm(0));
+    TmpInst.addOperand(Inst.getOperand(2));
+    TmpInst.addOperand(Inst.getOperand(3));
+    Inst = TmpInst;
+    return true;
+  }
   // Alias for alternate form of 'ADR Rd, #imm' instruction.
   case ARM::ADDri: {
     if (Inst.getOperand(1).getReg() != ARM::PC ||

Modified: llvm/trunk/test/MC/ARM/arm_addrmode2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=199032&r1=199031&r2=199032&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/arm_addrmode2.s (original)
+++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Sat Jan 11 22:36:01 2014
@@ -4,19 +4,19 @@
 @ CHECK: ldrt  r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6]
 @ CHECK: ldrt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6]
 @ CHECK: ldrt  r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4]
-@ CHECK: ldrt  r1, [r0] @ encoding: [0x00,0x10,0xb0,0xe4]
+@ CHECK: ldrt  r1, [r0], #0 @ encoding: [0x00,0x10,0xb0,0xe4]
 @ CHECK: ldrbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6]
 @ CHECK: ldrbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6]
 @ CHECK: ldrbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4]
-@ CHECK: ldrbt  r1, [r0] @ encoding: [0x00,0x10,0xf0,0xe4]
+@ CHECK: ldrbt  r1, [r0], #0 @ encoding: [0x00,0x10,0xf0,0xe4]
 @ CHECK: strt  r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6]
 @ CHECK: strt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6]
 @ CHECK: strt  r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4]
-@ CHECK: strt  r1, [r0] @ encoding: [0x00,0x10,0xa0,0xe4]
+@ CHECK: strt  r1, [r0], #0 @ encoding: [0x00,0x10,0xa0,0xe4]
 @ CHECK: strbt  r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6]
 @ CHECK: strbt  r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6]
 @ CHECK: strbt  r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4]
-@ CHECK: strbt  r1, [r0] @ encoding: [0x00,0x10,0xe0,0xe4]
+@ CHECK: strbt  r1, [r0], #0 @ encoding: [0x00,0x10,0xe0,0xe4]
         ldrt  r1, [r0], r2
         ldrt  r1, [r0], r2, lsr #3
         ldrt  r1, [r0], #4

Modified: llvm/trunk/test/MC/Disassembler/ARM/addrmode2-reencoding.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/addrmode2-reencoding.txt?rev=199032&r1=199031&r2=199032&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/addrmode2-reencoding.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM/addrmode2-reencoding.txt Sat Jan 11 22:36:01 2014
@@ -5,8 +5,8 @@
 0x00 0x10 0xa0 0xe4
 0x00 0x10 0xe0 0xe4
 
-# CHECK: ldrt r1, [r0]    @ encoding: [0x00,0x10,0xb0,0xe4]
-# CHECK: ldrbt r1, [r0]   @ encoding: [0x00,0x10,0xf0,0xe4]
-# CHECK: strt r1, [r0]    @ encoding: [0x00,0x10,0xa0,0xe4]
-# CHECK: strbt r1, [r0]   @ encoding: [0x00,0x10,0xe0,0xe4]
+# CHECK: ldrt r1, [r0], #0    @ encoding: [0x00,0x10,0xb0,0xe4]
+# CHECK: ldrbt r1, [r0], #0   @ encoding: [0x00,0x10,0xf0,0xe4]
+# CHECK: strt r1, [r0], #0    @ encoding: [0x00,0x10,0xa0,0xe4]
+# CHECK: strbt r1, [r0], #0   @ encoding: [0x00,0x10,0xe0,0xe4]
 





More information about the llvm-commits mailing list