Ban rematerializable instructions with side effects.
[oota-llvm.git] / utils / TableGen / ARMDecoderEmitter.cpp
index 34123f4533a5e694f159a7ea94a107d522909fac..145b96df98e2aa62a6b556dda22d753b518b1fdd 100644 (file)
 
 #include "ARMDecoderEmitter.h"
 #include "CodeGenTarget.h"
-#include "Record.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Record.h"
 
 #include <vector>
 #include <map>
@@ -41,7 +41,7 @@ using namespace llvm;
   ENTRY(ARM_FORMAT_BRFRM,          2) \
   ENTRY(ARM_FORMAT_BRMISCFRM,      3) \
   ENTRY(ARM_FORMAT_DPFRM,          4) \
-  ENTRY(ARM_FORMAT_DPSOREGFRM,     5) \
+  ENTRY(ARM_FORMAT_DPSOREGREGFRM,     5) \
   ENTRY(ARM_FORMAT_LDFRM,          6) \
   ENTRY(ARM_FORMAT_STFRM,          7) \
   ENTRY(ARM_FORMAT_LDMISCFRM,      8) \
@@ -77,7 +77,8 @@ using namespace llvm;
   ENTRY(ARM_FORMAT_N3RegVecSh,    38) \
   ENTRY(ARM_FORMAT_NVecExtract,   39) \
   ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
-  ENTRY(ARM_FORMAT_NVTBL,         41)
+  ENTRY(ARM_FORMAT_NVTBL,         41) \
+  ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42)
 
 // ARM instruction format specifies the encoding used by the instruction.
 #define ENTRY(n, v) n = v,
@@ -421,6 +422,9 @@ public:
 protected:
   // Populates the insn given the uid.
   void insnWithID(insn_t &Insn, unsigned Opcode) const {
+    if (AllInstructions[Opcode]->isPseudo)
+      return;
+
     BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst");
 
     for (unsigned i = 0; i < BIT_WIDTH; ++i)
@@ -607,7 +611,7 @@ void ARMFilter::recurse() {
     for (bitIndex = 0; bitIndex < NumBits; bitIndex++)
       BitValueArray[StartBit + bitIndex] = BIT_UNSET;
 
-    // Delegates to an inferior filter chooser for futher processing on this
+    // Delegates to an inferior filter chooser for further processing on this
     // group of instructions whose segment values are variable.
     FilterChooserMap.insert(std::pair<unsigned, ARMFilterChooser*>(
                               (unsigned)-1,
@@ -639,7 +643,7 @@ void ARMFilter::recurse() {
         BitValueArray[StartBit + bitIndex] = BIT_FALSE;
     }
 
-    // Delegates to an inferior filter chooser for futher processing on this
+    // Delegates to an inferior filter chooser for further processing on this
     // category of instructions.
     FilterChooserMap.insert(std::pair<unsigned, ARMFilterChooser*>(
                               mapIterator->first,
@@ -1382,7 +1386,7 @@ bool ARMFilterChooser::emit(raw_ostream &o, unsigned &Indentation) {
     // 2. source registers are identical => VMOVQ; otherwise => VORRq
     // 3. LDR, LDRcp => return LDR for now.
     // FIXME: How can we distinguish between LDR and LDRcp?  Do we need to?
-    // 4. tLDM, tLDM_UPD => Rn = Inst{10-8}, reglist = Inst{7-0},
+    // 4. tLDMIA, tLDMIA_UPD => Rn = Inst{10-8}, reglist = Inst{7-0},
     //    wback = registers<Rn> = 0
     // NOTE: (tLDM, tLDM_UPD) resolution must come before Advanced SIMD
     //       addressing mode resolution!!!
@@ -1423,7 +1427,7 @@ bool ARMFilterChooser::emit(raw_ostream &o, unsigned &Indentation) {
         << "; // Returning LDR for {LDR, LDRcp}\n";
       return true;
     }
-    if (name1 == "tLDM" && name2 == "tLDM_UPD") {
+    if (name1 == "tLDMIA" && name2 == "tLDMIA_UPD") {
       // Inserting the opening curly brace for this case block.
       --Indentation; --Indentation;
       o.indent(Indentation) << "{\n";
@@ -1584,54 +1588,14 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI,
         Name == "MOVr_TC")
       return false;
 
+    // Delegate ADR disassembly to the more generic ADDri/SUBri instructions.
+    if (Name == "ADR")
+      return false;
+
     //
     // The following special cases are for conflict resolutions.
     //
 
-    // NEON NLdStFrm conflict resolutions:
-    //
-    // 1. Ignore suffix "odd" and "odd_UPD", prefer the "even" register-
-    //    numbered ones which have the same Asm format string.
-    // 2. Ignore VST2d64_UPD, which conflicts with VST1q64_UPD.
-    // 3. Ignore VLD2d64_UPD, which conflicts with VLD1q64_UPD.
-    // 4. Ignore VLD1q[_UPD], which conflicts with VLD1q64[_UPD].
-    // 5. Ignore VST1q[_UPD], which conflicts with VST1q64[_UPD].
-    if (Name.endswith("odd") || Name.endswith("odd_UPD") ||
-        Name == "VST2d64_UPD" || Name == "VLD2d64_UPD" ||
-        Name == "VLD1q" || Name == "VLD1q_UPD" ||
-        Name == "VST1q" || Name == "VST1q_UPD")
-      return false;
-
-    // RSCSri and RSCSrs set the 's' bit, but are not predicated.  We are
-    // better off using the generic RSCri and RSCrs instructions.
-    if (Name == "RSCSri" || Name == "RSCSrs") return false;
-
-    // FCYPScc, FCYPDcc, FNEGScc, and FNEGDcc are used in the compiler
-    // to implement conditional moves. We can ignore them in favor of
-    // their more generic versions of instructions. See also
-    // SDNode *ARMDAGToDAGISel::Select(SDValue Op).
-    if (Name == "FCPYScc" || Name == "FCPYDcc" || Name == "FNEGScc" ||
-        Name == "FNEGDcc")
-      return false;
-
-    // Ditto for VMOVDcc, VMOVScc, VNEGDcc, and VNEGScc.
-    if (Name == "VMOVDcc" || Name == "VMOVScc" || Name == "VNEGDcc" ||
-        Name == "VNEGScc")
-      return false;
-
-    // LDMIA_RET is a special case of LDM (Load Multiple) where the registers
-    // loaded include the PC, causing a branch to a loaded address.  Ignore
-    // the LDMIA_RET instruction when decoding.
-    if (Name == "LDMIA_RET") return false;
-
-    // Bcc is in a more generic form than B.  Ignore B when decoding.
-    if (Name == "B") return false;
-
-    // Ignore the non-Darwin BL instructions and the TPsoft (TLS) instruction.
-    if (Name == "BL" || Name == "BL_pred" || Name == "BLX" ||
-        Name == "BLX_pred" || Name == "TPsoft")
-      return false;
-
     // A8-598: VEXT
     // Vector Extract extracts elements from the bottom end of the second
     // operand vector and the top end of the first, concatenates them and
@@ -1651,27 +1615,29 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI,
     if (!thumbInstruction(Form))
       return false;
 
-    // On Darwin R9 is call-clobbered.  Ignore the non-Darwin counterparts.
-    if (Name == "tBL" || Name == "tBLXi" || Name == "tBLXr")
-      return false;
-
-    // Ignore the TPsoft (TLS) instructions, which conflict with tBLr9.
-    if (Name == "tTPsoft" || Name == "t2TPsoft")
+    // A8.6.25 BX.  Use the generic tBX_Rm, ignore tBX_RET and tBX_RET_vararg.
+    if (Name == "tBX_RET" || Name == "tBX_RET_vararg")
       return false;
 
     // Ignore tADR, prefer tADDrPCi.
     if (Name == "tADR")
       return false;
 
+    // Delegate t2ADR disassembly to the more generic t2ADDri12/t2SUBri12
+    // instructions.
+    if (Name == "t2ADR")
+      return false;
+
     // Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr.
     // Ignore t2SUBrSPs, prefer the t2SUB[S]r[r|s].
     // Ignore t2ADDrSPs, prefer the t2ADD[S]r[r|s].
-    // Ignore t2ADDrSPi/t2SUBrSPi, which have more generic couterparts.
-    // Ignore t2ADDrSPi12/t2SUBrSPi12, which have more generic couterparts
     if (Name == "tADDrSP" || Name == "tADDspr" || Name == "tPICADD" ||
-        Name == "t2SUBrSPs" || Name == "t2ADDrSPs" ||
-        Name == "t2ADDrSPi" || Name == "t2SUBrSPi" ||
-        Name == "t2ADDrSPi12" || Name == "t2SUBrSPi12")
+        Name == "t2SUBrSPs" || Name == "t2ADDrSPs")
+      return false;
+
+    // FIXME: Use ldr.n to work around a Darwin assembler bug.
+    // Introduce a workaround with tLDRpciDIS opcode.
+    if (Name == "tLDRpci")
       return false;
 
     // Ignore t2LDRDpci, prefer the generic t2LDRDi8, t2LDRD_PRE, t2LDRD_POST.
@@ -1680,18 +1646,14 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI,
 
     // Resolve conflicts:
     //
-    //   tBfar conflicts with tBLr9
-    //   tPOP_RET/t2LDMIA_RET conflict with tPOP/t2LDM (ditto)
+    //   t2LDMIA_RET conflict with t2LDM (ditto)
     //   tMOVCCi conflicts with tMOVi8
     //   tMOVCCr conflicts with tMOVgpr2gpr
-    //   tSpill conflicts with tSTRspi
     //   tLDRcp conflicts with tLDRspi
-    //   tRestore conflicts with tLDRspi
     //   t2MOVCCi16 conflicts with tMOVi16
-    if (Name == "tBfar" ||
-        Name == "tPOP_RET" || Name == "t2LDMIA_RET" ||
+    if (Name == "t2LDMIA_RET" ||
         Name == "tMOVCCi" || Name == "tMOVCCr" ||
-        Name == "tSpill" || Name == "tLDRcp" || Name == "tRestore" ||
+        Name == "tLDRcp" || 
         Name == "t2MOVCCi16")
       return false;
   }