ARM Assembly syntax support for arithmetic implied dest operand.
authorJim Grosbach <grosbach@apple.com>
Mon, 27 Jun 2011 19:09:15 +0000 (19:09 +0000)
committerJim Grosbach <grosbach@apple.com>
Mon, 27 Jun 2011 19:09:15 +0000 (19:09 +0000)
When the destination operand is the same as the first source register
operand for arithmetic instructions, the destination operand may be omitted.

For example, the following two instructions are equivalent:
  sub r2, r2, #6
  sub r2, #6

rdar://9682597

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133925 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
test/MC/ARM/arm-arithmetic-aliases.s [new file with mode: 0644]

index 5c013de238eec36a2b5d8db3d629b28f41e4b63a..b34b127cc1584446bb3646af8405b8aae7389c5a 100644 (file)
@@ -676,7 +676,7 @@ include "ARMInstrFormats.td"
 /// binop that produces a value.
 multiclass AsI1_bin_irs<bits<4> opcod, string opc,
                      InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
-                        PatFrag opnode, bit Commutable = 0> {
+                        PatFrag opnode, string baseOpc, bit Commutable = 0> {
   // The register-immediate version is re-materializable. This is useful
   // in particular for taking the address of a local.
   let isReMaterializable = 1 in {
@@ -716,6 +716,24 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
     let Inst{15-12} = Rd;
     let Inst{11-0} = shift;
   }
+
+  // Assembly aliases for optional destination operand when it's the same
+  // as the source operand.
+  def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $imm"),
+     (!cast<Instruction>(!strconcat(baseOpc, "ri")) GPR:$Rdn, GPR:$Rdn,
+                                                    so_imm:$imm, pred:$p,
+                                                    cc_out:$s)>,
+     Requires<[IsARM]>;
+  def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $Rm"),
+     (!cast<Instruction>(!strconcat(baseOpc, "rr")) GPR:$Rdn, GPR:$Rdn,
+                                                    GPR:$Rm, pred:$p,
+                                                    cc_out:$s)>,
+     Requires<[IsARM]>;
+  def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $shift"),
+     (!cast<Instruction>(!strconcat(baseOpc, "rs")) GPR:$Rdn, GPR:$Rdn,
+                                                    so_reg:$shift, pred:$p,
+                                                    cc_out:$s)>,
+     Requires<[IsARM]>;
 }
 
 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
@@ -2205,10 +2223,10 @@ def UBFX  : I<(outs GPR:$Rd),
 
 defm ADD  : AsI1_bin_irs<0b0100, "add",
                          IIC_iALUi, IIC_iALUr, IIC_iALUsr,
-                         BinOpFrag<(add  node:$LHS, node:$RHS)>, 1>;
+                         BinOpFrag<(add  node:$LHS, node:$RHS)>, "ADD", 1>;
 defm SUB  : AsI1_bin_irs<0b0010, "sub",
                          IIC_iALUi, IIC_iALUr, IIC_iALUsr,
-                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
+                         BinOpFrag<(sub  node:$LHS, node:$RHS)>, "SUB">;
 
 // ADD and SUB with 's' bit set.
 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
@@ -2531,16 +2549,16 @@ def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
 
 defm AND   : AsI1_bin_irs<0b0000, "and",
                           IIC_iBITi, IIC_iBITr, IIC_iBITsr,
-                          BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
+                          BinOpFrag<(and node:$LHS, node:$RHS)>, "AND", 1>;
 defm ORR   : AsI1_bin_irs<0b1100, "orr",
                           IIC_iBITi, IIC_iBITr, IIC_iBITsr,
-                          BinOpFrag<(or  node:$LHS, node:$RHS)>, 1>;
+                          BinOpFrag<(or  node:$LHS, node:$RHS)>, "ORR", 1>;
 defm EOR   : AsI1_bin_irs<0b0001, "eor",
                           IIC_iBITi, IIC_iBITr, IIC_iBITsr,
-                          BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
+                          BinOpFrag<(xor node:$LHS, node:$RHS)>, "EOR", 1>;
 defm BIC   : AsI1_bin_irs<0b1110, "bic",
                           IIC_iBITi, IIC_iBITr, IIC_iBITsr,
-                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
+                          BinOpFrag<(and node:$LHS, (not node:$RHS))>, "BIC">;
 
 def BFC    : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
diff --git a/test/MC/ARM/arm-arithmetic-aliases.s b/test/MC/ARM/arm-arithmetic-aliases.s
new file mode 100644 (file)
index 0000000..9895cfc
--- /dev/null
@@ -0,0 +1,126 @@
+@ RUN: llvm-mc -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s
+
+foo:
+@ CHECK: foo
+
+sub r2, r2, #6
+sub r2, #6
+sub r2, r2, r3
+sub r2, r3
+
+@ CHECK: sub r2, r2, #6              @ encoding: [0x06,0x20,0x42,0xe2]
+@ CHECK: sub r2, r2, #6              @ encoding: [0x06,0x20,0x42,0xe2]
+@ CHECK: sub r2, r2, r3              @ encoding: [0x03,0x20,0x42,0xe0]
+@ CHECK: sub r2, r2, r3              @ encoding: [0x03,0x20,0x42,0xe0]
+
+add r2, r2, #6
+add r2, #6
+add r2, r2, r3
+add r2, r3
+
+@ CHECK: add r2, r2, #6              @ encoding: [0x06,0x20,0x82,0xe2]
+@ CHECK: add r2, r2, #6              @ encoding: [0x06,0x20,0x82,0xe2]
+@ CHECK: add r2, r2, r3              @ encoding: [0x03,0x20,0x82,0xe0]
+@ CHECK: add r2, r2, r3              @ encoding: [0x03,0x20,0x82,0xe0]
+
+and r2, r2, #6
+and r2, #6
+and r2, r2, r3
+and r2, r3
+
+@ CHECK: and r2, r2, #6              @ encoding: [0x06,0x20,0x02,0xe2]
+@ CHECK: and r2, r2, #6              @ encoding: [0x06,0x20,0x02,0xe2]
+@ CHECK: and r2, r2, r3              @ encoding: [0x03,0x20,0x02,0xe0]
+@ CHECK: and r2, r2, r3              @ encoding: [0x03,0x20,0x02,0xe0]
+
+orr r2, r2, #6
+orr r2, #6
+orr r2, r2, r3
+orr r2, r3
+
+@ CHECK: orr r2, r2, #6              @ encoding: [0x06,0x20,0x82,0xe3]
+@ CHECK: orr r2, r2, #6              @ encoding: [0x06,0x20,0x82,0xe3]
+@ CHECK: orr r2, r2, r3              @ encoding: [0x03,0x20,0x82,0xe1]
+@ CHECK: orr r2, r2, r3              @ encoding: [0x03,0x20,0x82,0xe1]
+
+eor r2, r2, #6
+eor r2, #6
+eor r2, r2, r3
+eor r2, r3
+
+@ CHECK: eor r2, r2, #6              @ encoding: [0x06,0x20,0x22,0xe2]
+@ CHECK: eor r2, r2, #6              @ encoding: [0x06,0x20,0x22,0xe2]
+@ CHECK: eor r2, r2, r3              @ encoding: [0x03,0x20,0x22,0xe0]
+@ CHECK: eor r2, r2, r3              @ encoding: [0x03,0x20,0x22,0xe0]
+
+bic r2, r2, #6
+bic r2, #6
+bic r2, r2, r3
+bic r2, r3
+
+@ CHECK: bic r2, r2, #6              @ encoding: [0x06,0x20,0xc2,0xe3]
+@ CHECK: bic r2, r2, #6              @ encoding: [0x06,0x20,0xc2,0xe3]
+@ CHECK: bic r2, r2, r3              @ encoding: [0x03,0x20,0xc2,0xe1]
+@ CHECK: bic r2, r2, r3              @ encoding: [0x03,0x20,0xc2,0xe1]
+
+
+@ Also check that we handle the predicate and cc_out operands.
+subseq r2, r2, #6
+subseq r2, #6
+subseq r2, r2, r3
+subseq r2, r3
+
+@ CHECK: subseq r2, r2, #6              @ encoding: [0x06,0x20,0x52,0x02]
+@ CHECK: subseq r2, r2, #6              @ encoding: [0x06,0x20,0x52,0x02]
+@ CHECK: subseq r2, r2, r3              @ encoding: [0x03,0x20,0x52,0x00]
+@ CHECK: subseq r2, r2, r3              @ encoding: [0x03,0x20,0x52,0x00]
+
+addseq r2, r2, #6
+addseq r2, #6
+addseq r2, r2, r3
+addseq r2, r3
+
+@ CHECK: addseq r2, r2, #6              @ encoding: [0x06,0x20,0x92,0x02]
+@ CHECK: addseq r2, r2, #6              @ encoding: [0x06,0x20,0x92,0x02]
+@ CHECK: addseq r2, r2, r3              @ encoding: [0x03,0x20,0x92,0x00]
+@ CHECK: addseq r2, r2, r3              @ encoding: [0x03,0x20,0x92,0x00]
+
+andseq r2, r2, #6
+andseq r2, #6
+andseq r2, r2, r3
+andseq r2, r3
+
+@ CHECK: andseq r2, r2, #6              @ encoding: [0x06,0x20,0x12,0x02]
+@ CHECK: andseq r2, r2, #6              @ encoding: [0x06,0x20,0x12,0x02]
+@ CHECK: andseq r2, r2, r3              @ encoding: [0x03,0x20,0x12,0x00]
+@ CHECK: andseq r2, r2, r3              @ encoding: [0x03,0x20,0x12,0x00]
+
+orrseq r2, r2, #6
+orrseq r2, #6
+orrseq r2, r2, r3
+orrseq r2, r3
+
+@ CHECK: orrseq r2, r2, #6              @ encoding: [0x06,0x20,0x92,0x03]
+@ CHECK: orrseq r2, r2, #6              @ encoding: [0x06,0x20,0x92,0x03]
+@ CHECK: orrseq r2, r2, r3              @ encoding: [0x03,0x20,0x92,0x01]
+@ CHECK: orrseq r2, r2, r3              @ encoding: [0x03,0x20,0x92,0x01]
+
+eorseq r2, r2, #6
+eorseq r2, #6
+eorseq r2, r2, r3
+eorseq r2, r3
+
+@ CHECK: eorseq r2, r2, #6              @ encoding: [0x06,0x20,0x32,0x02]
+@ CHECK: eorseq r2, r2, #6              @ encoding: [0x06,0x20,0x32,0x02]
+@ CHECK: eorseq r2, r2, r3              @ encoding: [0x03,0x20,0x32,0x00]
+@ CHECK: eorseq r2, r2, r3              @ encoding: [0x03,0x20,0x32,0x00]
+
+bicseq r2, r2, #6
+bicseq r2, #6
+bicseq r2, r2, r3
+bicseq r2, r3
+
+@ CHECK: bicseq r2, r2, #6              @ encoding: [0x06,0x20,0xd2,0x03]
+@ CHECK: bicseq r2, r2, #6              @ encoding: [0x06,0x20,0xd2,0x03]
+@ CHECK: bicseq r2, r2, r3              @ encoding: [0x03,0x20,0xd2,0x01]
+@ CHECK: bicseq r2, r2, r3              @ encoding: [0x03,0x20,0xd2,0x01]