[llvm] r218521 - Elide repeated register operand in Thumb1 instructions

Renato Golin renato.golin at linaro.org
Fri Sep 26 09:14:29 PDT 2014


Author: rengolin
Date: Fri Sep 26 11:14:29 2014
New Revision: 218521

URL: http://llvm.org/viewvc/llvm-project?rev=218521&view=rev
Log:
Elide repeated register operand in Thumb1 instructions

This patch makes the ARM backend transform 3 operand instructions such as
'adds/subs' to the 2 operand version of the same instruction if the first
two register operands are the same.

Example: 'adds r0, r0, #1' will is transformed to 'adds r0, #1'.

Currently for some instructions such as 'adds' if you try to assemble
'adds r0, r0, #8' for thumb v6m the assembler would throw an error message
because the immediate cannot be encoded using 3 bits.

The backend should be smart enough to transform the instruction to
'adds r0, #8', which allows for larger immediate constants.

Patch by Ranjeet Singh.

Added:
    llvm/trunk/test/MC/ARM/thumb_rewrites.s
Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

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=218521&r1=218520&r2=218521&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Fri Sep 26 11:14:29 2014
@@ -5674,6 +5674,48 @@ bool ARMAsmParser::ParseInstruction(Pars
     }
   }
 
+  // If first 2 operands of a 3 operand instruction are the same
+  // then transform to 2 operand version of the same instruction
+  // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
+  // FIXME: We would really like to be able to tablegen'erate this.
+  if (isThumbOne() && Operands.size() == 6 &&
+       (Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
+        Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
+        Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
+        Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic")) {
+      ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
+      ARMOperand &Op4 = static_cast<ARMOperand &>(*Operands[4]);
+      ARMOperand &Op5 = static_cast<ARMOperand &>(*Operands[5]);
+
+      // If both registers are the same then remove one of them from
+      // the operand list.
+      if (Op3.isReg() && Op4.isReg() && Op3.getReg() == Op4.getReg()) {
+          // If 3rd operand (variable Op5) is a register and the instruction is adds/sub
+          // then do not transform as the backend already handles this instruction
+          // correctly.
+          if (!Op5.isReg() || !((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub")) {
+              Operands.erase(Operands.begin() + 3);
+              if (Mnemonic == "add" && !CarrySetting) {
+                  // Special case for 'add' (not 'adds') instruction must
+                  // remove the CCOut operand as well.
+                  Operands.erase(Operands.begin() + 1);
+              }
+          }
+      }
+  }
+
+  // If instruction is 'add' and first two register operands
+  // use SP register, then remove one of the SP registers from
+  // the instruction.
+  // FIXME: We would really like to be able to tablegen'erate this.
+  if (isThumbOne() && Operands.size() == 5 && Mnemonic == "add" && !CarrySetting) {
+      ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]);
+      ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
+      if (Op2.isReg() && Op3.isReg() && Op2.getReg() == ARM::SP && Op3.getReg() == ARM::SP) {
+          Operands.erase(Operands.begin() + 2);
+      }
+  }
+
   // GNU Assembler extension (compatibility)
   if ((Mnemonic == "ldrd" || Mnemonic == "strd")) {
     ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]);
@@ -8180,7 +8222,7 @@ unsigned ARMAsmParser::checkTargetMatchP
   }
   // Some high-register supporting Thumb1 encodings only allow both registers
   // to be from r0-r7 when in Thumb2.
-  else if (Opc == ARM::tADDhirr && isThumbOne() &&
+  else if (Opc == ARM::tADDhirr && isThumbOne() && !hasV6MOps() &&
            isARMLowRegister(Inst.getOperand(1).getReg()) &&
            isARMLowRegister(Inst.getOperand(2).getReg()))
     return Match_RequiresThumb2;

Added: llvm/trunk/test/MC/ARM/thumb_rewrites.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb_rewrites.s?rev=218521&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb_rewrites.s (added)
+++ llvm/trunk/test/MC/ARM/thumb_rewrites.s Fri Sep 26 11:14:29 2014
@@ -0,0 +1,52 @@
+@ RUN: llvm-mc -triple thumbv6m -show-encoding < %s | FileCheck %s
+
+    adds    r0, r0, #8
+@ CHECK: adds   r0, #8              @ encoding: [0x08,0x30]
+
+    adds    r0, r0, r0
+@ CHECK: adds   r0, r0, r0          @ encoding: [0x00,0x18]
+
+    add     r0, r0, r8
+@ CHECK: add    r0, r8              @ encoding: [0x40,0x44]
+
+    add     sp, sp, r0
+@ CHECK: add    sp, r0              @ encoding: [0x85,0x44]
+
+    add     r0, r0, r1
+@ CHECK: add    r0, r1              @ encoding: [0x08,0x44]
+
+    add     r2, r2, r3
+@ CHECK: add    r2, r3              @ encoding: [0x1a,0x44]
+
+    subs    r0, r0, r0
+@ CHECK: subs   r0, r0, r0          @ encoding: [0x00,0x1a]
+
+    ands    r0, r0, r1
+@ CHECK: ands   r0, r1              @ encoding: [0x08,0x40]
+
+    eors    r0, r0, r1
+@ CHECK: eors   r0, r1              @ encoding: [0x48,0x40]
+
+    lsls    r0, r0, r1
+@ CHECK: lsls   r0, r1              @ encoding: [0x88,0x40]
+
+    lsrs    r0, r0, r1
+@ CHECK: lsrs   r0, r1              @ encoding: [0xc8,0x40]
+
+    asrs    r0, r0, r1
+@ CHECK: asrs   r0, r1              @ encoding: [0x08,0x41]
+
+    adcs    r0, r0, r1
+@ CHECK: adcs   r0, r1              @ encoding: [0x48,0x41]
+
+    sbcs    r0, r0, r1
+@ CHECK: sbcs   r0, r1              @ encoding: [0x88,0x41]
+
+    rors    r0, r0, r1
+@ CHECK: rors   r0, r1              @ encoding: [0xc8,0x41]
+
+    orrs    r0, r0, r1
+@ CHECK: orrs   r0, r1              @ encoding: [0x08,0x43]
+
+    bics    r0, r0, r1
+@ CHECK: bics   r0, r1              @ encoding: [0x88,0x43]





More information about the llvm-commits mailing list