Thumb2 assembly parsing of 'mov(register shifted register)' aliases.
authorJim Grosbach <grosbach@apple.com>
Wed, 21 Dec 2011 20:54:00 +0000 (20:54 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 21 Dec 2011 20:54:00 +0000 (20:54 +0000)
These map to the ASR, LSR, LSL, ROR instruction definitions.

rdar://10615373

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

lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-thumb2-instructions.s

index b300ea518e083a28d17cc160d860a76b3aba06e6..10422ee111d69662b26b3e82c4865d61dc344175 100644 (file)
@@ -4141,6 +4141,11 @@ def t2MOVsi: t2AsmPseudo<"mov${p} $Rd, $shift",
 def t2MOVSsi: t2AsmPseudo<"movs${p} $Rd, $shift",
                           (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>;
 
+def t2MOVsr: t2AsmPseudo<"mov${p} $Rd, $shift",
+                         (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>;
+def t2MOVSsr: t2AsmPseudo<"movs${p} $Rd, $shift",
+                          (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>;
+
 // ADR w/o the .w suffix
 def : t2InstAlias<"adr${p} $Rd, $addr",
                   (t2ADR rGPR:$Rd, t2adrlabel:$addr, pred:$p)>;
index b6e0d1b35c5ca4c2dc132c572031ba068aa825c4..ab954bea258639e140e1ee337a047eda76b4ea87 100644 (file)
@@ -5748,6 +5748,42 @@ processInstruction(MCInst &Inst,
     return true;
   }
   // Handle the Thumb2 mode MOV complex aliases.
+  case ARM::t2MOVsr:
+  case ARM::t2MOVSsr: {
+    // Which instruction to expand to depends on the CCOut operand and
+    // whether we're in an IT block if the register operands are low
+    // registers.
+    bool isNarrow = false;
+    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
+        isARMLowRegister(Inst.getOperand(1).getReg()) &&
+        isARMLowRegister(Inst.getOperand(2).getReg()) &&
+        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
+        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr))
+      isNarrow = true;
+    MCInst TmpInst;
+    unsigned newOpc;
+    switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
+    default: llvm_unreachable("unexpected opcode!");
+    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
+    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
+    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
+    case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
+    }
+    TmpInst.setOpcode(newOpc);
+    TmpInst.addOperand(Inst.getOperand(0)); // Rd
+    if (isNarrow)
+      TmpInst.addOperand(MCOperand::CreateReg(
+          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
+    TmpInst.addOperand(Inst.getOperand(1)); // Rn
+    TmpInst.addOperand(Inst.getOperand(2)); // Rm
+    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
+    TmpInst.addOperand(Inst.getOperand(5));
+    if (!isNarrow)
+      TmpInst.addOperand(MCOperand::CreateReg(
+          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
+    Inst = TmpInst;
+    return true;
+  }
   case ARM::t2MOVsi:
   case ARM::t2MOVSsi: {
     // Which instruction to expand to depends on the CCOut operand and
index be640f0069261150e8c8f775f78e05c06677ade0..9e5c4be89d5211e04dc928374e701e713f683acc 100644 (file)
@@ -1155,11 +1155,36 @@ _func:
         mov r6, r2, lsr #16
         movs r6, r2, asr #32
         movs r6, r2, ror #5
+        movs r4, r4, lsl r5
+        movs r4, r4, lsr r5
+        movs r4, r4, asr r5
+        movs r4, r4, ror r5
+        mov r4, r4, lsl r5
+        movs r4, r4, ror r8
+        movs r4, r5, lsr r6
+        itttt eq
+        moveq r4, r4, lsl r5
+        moveq r4, r4, lsr r5
+        moveq r4, r4, asr r5
+        moveq r4, r4, ror r5
 
 @ CHECK: lsl.w r6, r2, #16             @ encoding: [0x4f,0xea,0x02,0x46]
 @ CHECK: lsr.w r6, r2, #16             @ encoding: [0x4f,0xea,0x12,0x46]
 @ CHECK: asrs  r6, r2, #32             @ encoding: [0x16,0x10]
 @ CHECK: rors.w        r6, r2, #5              @ encoding: [0x5f,0xea,0x72,0x16]
+@ CHECK: lsls  r4, r5                  @ encoding: [0xac,0x40]
+@ CHECK: lsrs  r4, r5                  @ encoding: [0xec,0x40]
+@ CHECK: asrs  r4, r5                  @ encoding: [0x2c,0x41]
+@ CHECK: rors  r4, r5                  @ encoding: [0xec,0x41]
+@ CHECK: lsl.w r4, r4, r5              @ encoding: [0x04,0xfa,0x05,0xf4]
+@ CHECK: rors.w        r4, r4, r8              @ encoding: [0x74,0xfa,0x08,0xf4]
+@ CHECK: lsrs.w        r4, r5, r6              @ encoding: [0x35,0xfa,0x06,0xf4]
+@ CHECK: itttt eq                      @ encoding: [0x01,0xbf]
+@ CHECK: lsleq r4, r5                  @ encoding: [0xac,0x40]
+@ CHECK: lsreq r4, r5                  @ encoding: [0xec,0x40]
+@ CHECK: asreq r4, r5                  @ encoding: [0x2c,0x41]
+@ CHECK: roreq r4, r5                  @ encoding: [0xec,0x41]
+
 
 
 @------------------------------------------------------------------------------