Cleaned up the for-disassembly-only entries in the arm instruction table so that
authorJohnny Chen <johnny.chen@apple.com>
Thu, 12 Aug 2010 20:46:17 +0000 (20:46 +0000)
committerJohnny Chen <johnny.chen@apple.com>
Thu, 12 Aug 2010 20:46:17 +0000 (20:46 +0000)
the memory barrier variants (other than 'SY' full system domain read and write)
are treated as one instruction with option operand.

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

lib/Target/ARM/ARM.h
lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
test/MC/Disassembler/arm-tests.txt
utils/TableGen/EDEmitter.cpp

index 233706735e30dde7982a561c0b5a15dfea84ec1c..e76791921ee2bd1595ee64b1425b2139eaff7727 100644 (file)
@@ -90,6 +90,33 @@ inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
   }
 }
 
+namespace ARM_MB {
+  // The Memory Barrier Option constants map directly to the 4-bit encoding of
+  // the option field for memory barrier operations.
+  enum MemBOpt {
+    ST    = 14,
+    ISH   = 11,
+    ISHST = 10,
+    NSH   = 7,
+    NSHST = 6,
+    OSH   = 3,
+    OSHST = 2
+  };
+
+  inline static const char *MemBOptToString(unsigned val) {
+    switch (val) {
+    default: llvm_unreachable("Unknown memory opetion");
+    case ST:    return "st";
+    case ISH:   return "ish";
+    case ISHST: return "ishst";
+    case NSH:   return "nsh";
+    case NSHST: return "nshst";
+    case OSH:   return "osh";
+    case OSHST: return "oshst";
+    }
+  }
+} // namespace ARM_MB
+
 FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM,
                                CodeGenOpt::Level OptLevel);
 
index b09cd73176df169bd1ff47a4121a58bd42d5eb9a..ded9800052e19cf3380ffc190c0a33dddc4940d3 100644 (file)
@@ -122,6 +122,8 @@ namespace {
                                 const char *Modifier = 0);
     void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
                                         raw_ostream &O);
+    void printMemBOption(const MachineInstr *MI, int OpNum,
+                         raw_ostream &O);
     void printSatShiftOperand(const MachineInstr *MI, int OpNum,
                               raw_ostream &O);
 
@@ -671,6 +673,13 @@ ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
   O << "#" << lsb << ", #" << width;
 }
 
+void
+ARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum,
+                               raw_ostream &O) {
+  unsigned val = MI->getOperand(OpNum).getImm();
+  O << ARM_MB::MemBOptToString(val);
+}
+
 void ARMAsmPrinter::printSatShiftOperand(const MachineInstr *MI, int OpNum,
                                          raw_ostream &O) {
   unsigned ShiftOp = MI->getOperand(OpNum).getImm();
index f058ee195f20e239d496ccbbf9ca3badc77db3b2..2e7757b0969446540feb6c632f59899a0b3fbc6e 100644 (file)
@@ -2389,61 +2389,30 @@ def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,
 }
 }
 
-// Helper class for multiclass MemB -- for disassembly only
-class AMBI<string opc, string asm>
-  : AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
-          [/* For disassembly only; pattern left blank */]>,
-    Requires<[IsARM, HasV7]> {
-  let Inst{31-20} = 0xf57;
-}
-
-multiclass MemB<bits<4> op7_4, string opc> {
-
-  def st : AMBI<opc, "\tst"> {
-    let Inst{7-4} = op7_4;
-    let Inst{3-0} = 0b1110;
-  }
-
-  def ish : AMBI<opc, "\tish"> {
-    let Inst{7-4} = op7_4;
-    let Inst{3-0} = 0b1011;
-  }
-
-  def ishst : AMBI<opc, "\tishst"> {
-    let Inst{7-4} = op7_4;
-    let Inst{3-0} = 0b1010;
-  }
+// Memory Barrier Operations Variants -- for disassembly only
 
-  def nsh : AMBI<opc, "\tnsh"> {
-    let Inst{7-4} = op7_4;
-    let Inst{3-0} = 0b0111;
-  }
-
-  def nshst : AMBI<opc, "\tnshst"> {
-    let Inst{7-4} = op7_4;
-    let Inst{3-0} = 0b0110;
-  }
-
-  def osh : AMBI<opc, "\tosh"> {
-    let Inst{7-4} = op7_4;
-    let Inst{3-0} = 0b0011;
-  }
+def memb_opt : Operand<i32> {
+  let PrintMethod = "printMemBOption";
+}
 
-  def oshst : AMBI<opc, "\toshst"> {
-    let Inst{7-4} = op7_4;
-    let Inst{3-0} = 0b0010;
-  }
+class AMBI<bits<4> op7_4, string opc>
+  : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt",
+          [/* For disassembly only; pattern left blank */]>,
+    Requires<[IsARM, HasDB]> {
+  let Inst{31-8} = 0xf57ff0;
+  let Inst{7-4} = op7_4;
 }
 
 // These DMB variants are for disassembly only.
-defm DMB : MemB<0b0101, "dmb">;
+def DMBvar : AMBI<0b0101, "dmb">;
 
 // These DSB variants are for disassembly only.
-defm DSB : MemB<0b0100, "dsb">;
+def DSBvar : AMBI<0b0100, "dsb">;
 
 // ISB has only full system option -- for disassembly only
-def ISBsy : AMBI<"isb", ""> {
-  let Inst{7-4} = 0b0110;
+def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>,
+            Requires<[IsARM, HasDB]> {
+  let Inst{31-4} = 0xf57ff06;
   let Inst{3-0} = 0b1111;
 }
 
index f40da955041d6efaa45cdbb613d01def34585c90..b662289cd50c35280051b1a26ba208c956decb8e 100644 (file)
@@ -472,6 +472,12 @@ void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
   O << '#' << lsb << ", #" << width;
 }
 
+void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
+                                     raw_ostream &O) {
+  unsigned val = MI->getOperand(OpNum).getImm();
+  O << ARM_MB::MemBOptToString(val);
+}
+
 void ARMInstPrinter::printSatShiftOperand(const MCInst *MI, unsigned OpNum,
                                           raw_ostream &O) {
   unsigned ShiftOp = MI->getOperand(OpNum).getImm();
index 14d7ec9308780b03d5b6bc9bb5ec5580ac241716..3eaa6f78823392ce07cd54047e1e9c9f18166178 100644 (file)
@@ -57,6 +57,7 @@ public:
 
   void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,
                                       raw_ostream &O);
+  void printMemBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printSatShiftOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
   void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
index cb15cff734bb25dd8cf7a0698b5020bf2369d85e..9637caaa578cb46d69504fa93f5e7aac6672d27e 100644 (file)
@@ -2935,7 +2935,7 @@ static bool DisassembleNDupFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
 // A8.6.49 ISB
 static inline bool MemBarrierInstr(uint32_t insn) {
   unsigned op7_4 = slice(insn, 7, 4);
-  if (slice(insn, 31, 20) == 0xf57 && (op7_4 >= 4 && op7_4 <= 6))
+  if (slice(insn, 31, 8) == 0xf57ff0 && (op7_4 >= 4 && op7_4 <= 6))
     return true;
 
   return false;
@@ -2992,8 +2992,15 @@ static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
 static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
 
-  if (MemBarrierInstr(insn))
+  if (MemBarrierInstr(insn)) {
+    // DMBsy, DSBsy, and ISBsy instructions have zero operand and are taken care
+    // of within the generic ARMBasicMCBuilder::BuildIt() method.
+    //
+    // Inst{3-0} encodes the memory barrier option for the variants.
+    MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
+    NumOpsAdded = 1;
     return true;
+  }
 
   switch (Opcode) {
   case ARM::CLREX:
index bb5875d2f3412a317c6892948b72903d537aff6e..cca4f32a20c42e5daeaf277027854488e7467a60 100644 (file)
 # CHECK:       dsb
 0x4f 0xf0 0x7f 0xf5
 
+# CHECK:       dsb     st
+0x4e 0xf0 0x7f 0xf5
+
+# CHECK:       isb
+0x6f 0xf0 0x7f 0xf5
+
 # CHECK:       ldclvc  p5, cr15, [r8], #-0
 0x00 0xf5 0x78 0x7c
 
index a640a74d21621bc067908bf04d09cfd7dd6a4e5a..8706ed5426e46e5fae952d84bf9b3655fe9bf884 100644 (file)
@@ -599,6 +599,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   IMM("cps_opt");
   IMM("vfp_f64imm");
   IMM("vfp_f32imm");
+  IMM("memb_opt");
   IMM("msr_mask");
   IMM("neg_zero");
   IMM("imm0_31");