Destination register operand is optional for ADC and SBC ARM.
authorJim Grosbach <grosbach@apple.com>
Wed, 13 Jul 2011 17:57:17 +0000 (17:57 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 13 Jul 2011 17:57:17 +0000 (17:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135052 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
test/MC/ARM/basic-arm-instructions.s

index 3fd27b0e305b8c28aa900fec66638a60baab415c..d87b526739e9485d7046ee84c7e6fa9bef2a9ff4 100644 (file)
@@ -950,9 +950,9 @@ multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
 }
 
 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
-let Uses = [CPSR] in {
 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
-                             bit Commutable = 0> {
+                             string baseOpc, bit Commutable = 0> {
+  let Uses = [CPSR] in {
   def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
                 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm",
                [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>,
@@ -991,7 +991,24 @@ multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
     let Inst{15-12} = Rd;
     let Inst{19-16} = Rn;
   }
-}
+  }
+  // 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]>;
 }
 
 // Carry setting variants
@@ -2252,9 +2269,11 @@ defm SUBS : AI1_bin_s_irs<0b0010, "subs",
                           BinOpFrag<(subc node:$LHS, node:$RHS)>>;
 
 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
-                          BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
+                          BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>,
+                          "ADC", 1>;
 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
-                          BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
+                          BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>,
+                          "SBC">;
 
 // ADC and SUBC with 's' bit set.
 let usesCustomInserter = 1 in {
index 756b59f10ec80a5292dbbd7e8520a6aafec37f03..66a3a4ee24f3b8d8f018bed0033545c18b8e05a5 100644 (file)
@@ -60,6 +60,25 @@ _func:
   adc r6, r7, r8, ror r9
   adc r4, r5, r6, rrx
 
+  @ Destination register is optional
+  adc r5, r6
+  adc r4, r5, lsl #1
+  adc r4, r5, lsl #31
+  adc r4, r5, lsr #1
+  adc r4, r5, lsr #31
+  adc r4, r5, lsr #32
+  adc r4, r5, asr #1
+  adc r4, r5, asr #31
+  adc r4, r5, asr #32
+  adc r4, r5, ror #1
+  adc r4, r5, ror #31
+  adc r4, r5, rrx
+  adc r6, r7, lsl r9
+  adc r6, r7, lsr r9
+  adc r6, r7, asr r9
+  adc r6, r7, ror r9
+  adc r4, r5, rrx
+
 @ CHECK: adc   r4, r5, r6              @ encoding: [0x06,0x40,0xa5,0xe0]
 
 @ CHECK: adc   r4, r5, r6, lsl #1      @ encoding: [0x86,0x40,0xa5,0xe0]
@@ -79,3 +98,20 @@ _func:
 @ CHECK: adc   r6, r7, r8, ror r9      @ encoding: [0x78,0x69,0xa7,0xe0]
 @ CHECK: adc   r4, r5, r6, rrx         @ encoding: [0x66,0x40,0xa5,0xe0]
 
+@ CHECK: adc   r5, r5, r6              @ encoding: [0x06,0x50,0xa5,0xe0]
+@ CHECK: adc   r4, r4, r5, lsl #1      @ encoding: [0x85,0x40,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, lsl #31     @ encoding: [0x85,0x4f,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, lsr #1      @ encoding: [0xa5,0x40,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, lsr #31     @ encoding: [0xa5,0x4f,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, lsr #32     @ encoding: [0x25,0x40,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, asr #1      @ encoding: [0xc5,0x40,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, asr #31     @ encoding: [0xc5,0x4f,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, asr #32     @ encoding: [0x45,0x40,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, ror #1      @ encoding: [0xe5,0x40,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, ror #31     @ encoding: [0xe5,0x4f,0xa4,0xe0]
+@ CHECK: adc   r4, r4, r5, rrx         @ encoding: [0x65,0x40,0xa4,0xe0]
+@ CHECK: adc   r6, r6, r7, lsl r9      @ encoding: [0x17,0x69,0xa6,0xe0]
+@ CHECK: adc   r6, r6, r7, lsr r9      @ encoding: [0x37,0x69,0xa6,0xe0]
+@ CHECK: adc   r6, r6, r7, asr r9      @ encoding: [0x57,0x69,0xa6,0xe0]
+@ CHECK: adc   r6, r6, r7, ror r9      @ encoding: [0x77,0x69,0xa6,0xe0]
+@ CHECK: adc   r4, r4, r5, rrx         @ encoding: [0x65,0x40,0xa4,0xe0]