ARM assembly parsing and encoding for RFE instruction.
authorJim Grosbach <grosbach@apple.com>
Fri, 29 Jul 2011 18:47:24 +0000 (18:47 +0000)
committerJim Grosbach <grosbach@apple.com>
Fri, 29 Jul 2011 18:47:24 +0000 (18:47 +0000)
Fill in the missing fixed bits and the register operand bits of the instruction
encoding. Refactor the definition to make the mode explicit, which is
consistent with how loads and stores are normally represented and makes
parsing much easier. Add parsing aliases for pseudo-instruction variants.
Update the disassembler for the new representations. Add tests for parsing and
encoding.

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

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
test/MC/ARM/basic-arm-instructions.s

index 351fcea6a60a4175833bf44f99b5eb83c0e06261..b7c245fe1e7e8c9d4e219f881fd0b85631441488 100644 (file)
@@ -1739,19 +1739,44 @@ def SRS  : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
   let Inst{7-5} = 0b000;
 }
 
+
 // Return From Exception
-def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
-                NoItinerary, "rfe${amode}\t$base!", []> {
+class RFEI<bit wb, string asm>
+  : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm,
+       NoItinerary, asm, "", []> {
+  bits<4> Rn;
   let Inst{31-28} = 0b1111;
-  let Inst{22-20} = 0b011; // W = 1
-  let Inst{15-0} = 0x0a00;
+  let Inst{27-25} = 0b100;
+  let Inst{22} = 0;
+  let Inst{21} = wb;
+  let Inst{20} = 1;
+  let Inst{19-16} = Rn;
+  let Inst{15-0} = 0xa00;
 }
 
-def RFE  : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
-                NoItinerary, "rfe${amode}\t$base", []> {
-  let Inst{31-28} = 0b1111;
-  let Inst{22-20} = 0b001; // W = 0
-  let Inst{15-0} = 0x0a00;
+def RFEDA : RFEI<0, "rfeda\t$Rn"> {
+  let Inst{24-23} = 0;
+}
+def RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> {
+  let Inst{24-23} = 0;
+}
+def RFEDB : RFEI<0, "rfedb\t$Rn"> {
+  let Inst{24-23} = 0b10;
+}
+def RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> {
+  let Inst{24-23} = 0b10;
+}
+def RFEIA : RFEI<0, "rfeia\t$Rn"> {
+  let Inst{24-23} = 0b01;
+}
+def RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> {
+  let Inst{24-23} = 0b01;
+}
+def RFEIB : RFEI<0, "rfeib\t$Rn"> {
+  let Inst{24-23} = 0b11;
+}
+def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> {
+  let Inst{24-23} = 0b11;
 }
 
 //===----------------------------------------------------------------------===//
@@ -4421,3 +4446,11 @@ def : InstAlias<"uxtab16${p} $Rd, $Rn, $Rm",
 def : InstAlias<"uxtb${p} $Rd, $Rm", (UXTB GPR:$Rd, GPR:$Rm, 0, pred:$p)>;
 def : InstAlias<"uxtb16${p} $Rd, $Rm", (UXTB16 GPR:$Rd, GPR:$Rm, 0, pred:$p)>;
 def : InstAlias<"uxth${p} $Rd, $Rm", (UXTH GPR:$Rd, GPR:$Rm, 0, pred:$p)>;
+
+
+// RFE aliases
+def : MnemonicAlias<"rfefa", "rfeda">;
+def : MnemonicAlias<"rfeea", "rfedb">;
+def : MnemonicAlias<"rfefd", "rfeia">;
+def : MnemonicAlias<"rfeed", "rfeib">;
+def : MnemonicAlias<"rfe", "rfeia">;
index 754c1bc883c21b020e0c577a367b5a8ab8a797ec..40c3097e1300fe8c33003a10a9a1ad0431d5b31d 100644 (file)
@@ -2540,6 +2540,7 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
       Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
       Mnemonic == "setend" ||
       ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) ||
+      (Mnemonic.startswith("rfe") && !isThumb()) ||
       Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
     CanAcceptPredicationCode = false;
   } else {
index 1f3920bd8cf21e54eed677639e1f53d65597afaf..983589f6983c50cab362db465d655e27f46ba23c 100644 (file)
@@ -799,7 +799,7 @@ static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, uint32_t insn,
 // BXJ:        Rm
 // MSRi/MSRsysi: so_imm
 // SRSW/SRS: ldstm_mode:$amode mode_imm
-// RFEW/RFE: ldstm_mode:$amode Rn
+// RFE: Rn
 static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
 
@@ -858,19 +858,26 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     NumOpsAdded = 2;
     return true;
   }
-  if (Opcode == ARM::SRSW || Opcode == ARM::SRS ||
-      Opcode == ARM::RFEW || Opcode == ARM::RFE) {
+  if (Opcode == ARM::SRSW || Opcode == ARM::SRS) {
     ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn));
     MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode)));
 
     if (Opcode == ARM::SRSW || Opcode == ARM::SRS)
       MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
-    else
       MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
                                                          decodeRn(insn))));
     NumOpsAdded = 3;
     return true;
   }
+  if (Opcode == ARM::RFEDA || Opcode == ARM::RFEDB ||
+      Opcode == ARM::RFEIA || Opcode == ARM::RFEIB ||
+      Opcode == ARM::RFEDA_UPD || Opcode == ARM::RFEDB_UPD ||
+      Opcode == ARM::RFEIA_UPD || Opcode == ARM::RFEIB_UPD) {
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+                                                       decodeRn(insn))));
+    NumOpsAdded = 1;
+    return true;
+  }
 
   assert((Opcode == ARM::Bcc || Opcode == ARM::BL || Opcode == ARM::BL_pred
           || Opcode == ARM::SMC || Opcode == ARM::SVC) &&
index 872341ffe97b5a8dc9a77c191a9e9ba665cbe023..1a271986b34719781eaa9c3ddeb3a6d8fb1b084e 100644 (file)
@@ -1168,6 +1168,56 @@ Lforward:
 @ CHECK: revshne r9, r1                 @ encoding: [0xb1,0x9f,0xff,0x16]
 
 
+@------------------------------------------------------------------------------
+@ RFE
+@------------------------------------------------------------------------------
+        rfeda r2
+        rfedb r3
+        rfeia r5
+        rfeib r6
+
+        rfeda r4!
+        rfedb r7!
+        rfeia r9!
+        rfeib r8!
+
+        rfefa r2
+        rfeea r3
+        rfefd r5
+        rfeed r6
+
+        rfefa r4!
+        rfeea r7!
+        rfefd r9!
+        rfeed r8!
+
+        rfe r1
+        rfe r1!
+
+@ CHECK: rfeda r2                      @ encoding: [0x00,0x0a,0x12,0xf8]
+@ CHECK: rfedb r3                      @ encoding: [0x00,0x0a,0x13,0xf9]
+@ CHECK: rfeia r5                      @ encoding: [0x00,0x0a,0x95,0xf8]
+@ CHECK: rfeib r6                      @ encoding: [0x00,0x0a,0x96,0xf9]
+
+@ CHECK: rfeda r4!                     @ encoding: [0x00,0x0a,0x34,0xf8]
+@ CHECK: rfedb r7!                     @ encoding: [0x00,0x0a,0x37,0xf9]
+@ CHECK: rfeia r9!                     @ encoding: [0x00,0x0a,0xb9,0xf8]
+@ CHECK: rfeib r8!                     @ encoding: [0x00,0x0a,0xb8,0xf9]
+
+@ CHECK: rfeda r2                      @ encoding: [0x00,0x0a,0x12,0xf8]
+@ CHECK: rfedb r3                      @ encoding: [0x00,0x0a,0x13,0xf9]
+@ CHECK: rfeia r5                      @ encoding: [0x00,0x0a,0x95,0xf8]
+@ CHECK: rfeib r6                      @ encoding: [0x00,0x0a,0x96,0xf9]
+
+@ CHECK: rfeda r4!                     @ encoding: [0x00,0x0a,0x34,0xf8]
+@ CHECK: rfedb r7!                     @ encoding: [0x00,0x0a,0x37,0xf9]
+@ CHECK: rfeia r9!                     @ encoding: [0x00,0x0a,0xb9,0xf8]
+@ CHECK: rfeib r8!                     @ encoding: [0x00,0x0a,0xb8,0xf9]
+
+@ CHECK: rfeia r1                      @ encoding: [0x00,0x0a,0x91,0xf8]
+@ CHECK: rfeia r1!                     @ encoding: [0x00,0x0a,0xb1,0xf8]
+
+
 @------------------------------------------------------------------------------
 @ RSB
 @------------------------------------------------------------------------------