[llvm-commits] [llvm] r150169 - in /llvm/trunk: lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrThumb.td test/MC/Disassembler/ARM/unpredictables-thumb.txt utils/TableGen/FixedLenDecoderEmitter.cpp

James Molloy james.molloy at arm.com
Thu Feb 9 02:56:31 PST 2012


Author: jamesm
Date: Thu Feb  9 04:56:31 2012
New Revision: 150169

URL: http://llvm.org/viewvc/llvm-project?rev=150169&view=rev
Log:
Teach the MC and disassembler about SoftFail, and hook it up to UNPREDICTABLE on ARM. Wire this to tBLX in order to provide test coverage.


Added:
    llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt   (with props)
Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
    llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=150169&r1=150168&r2=150169&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Feb  9 04:56:31 2012
@@ -290,6 +290,14 @@
 
 class Encoding {
   field bits<32> Inst;
+  // Mask of bits that cause an encoding to be UNPREDICTABLE.
+  // If a bit is set, then if the corresponding bit in the
+  // target encoding differs from its value in the "Inst" field,
+  // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
+  field bits<32> Unpredictable = 0;
+  // SoftFail is the generic name for this field, but we alias it so
+  // as to make it more obvious what it means in ARM-land.
+  field bits<32> SoftFail = Unpredictable;
 }
 
 class InstARM<AddrMode am, int sz, IndexMode im,

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=150169&r1=150168&r2=150169&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Thu Feb  9 04:56:31 2012
@@ -387,6 +387,7 @@
     bits<4> Rm;
     let Inst{6-3} = Rm;
     let Inst{2-0} = 0b000;
+    let Unpredictable{2-0} = 0b111;
   }
 }
 

Added: llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt?rev=150169&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt (added)
+++ llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt Thu Feb  9 04:56:31 2012
@@ -0,0 +1,5 @@
+# RUN: llvm-mc --disassemble %s -triple=thumbv7 |& FileCheck %s
+
+0x01 0x47
+# CHECK: 3:1: warning: potentially undefined
+# CHECK: bx r0

Propchange: llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=150169&r1=150168&r2=150169&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Thu Feb  9 04:56:31 2012
@@ -17,6 +17,7 @@
 #include "FixedLenDecoderEmitter.h"
 #include "CodeGenTarget.h"
 #include "llvm/TableGen/Record.h"
+#include "llvm/ADT/APInt.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -285,8 +286,19 @@
   void insnWithID(insn_t &Insn, unsigned Opcode) const {
     BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst");
 
-    for (unsigned i = 0; i < BitWidth; ++i)
-      Insn.push_back(bitFromBits(Bits, i));
+    // We may have a SoftFail bitmask, which specifies a mask where an encoding
+    // may differ from the value in "Inst" and yet still be valid, but the
+    // disassembler should return SoftFail instead of Success.
+    //
+    // This is used for marking UNPREDICTABLE instructions in the ARM world.
+    BitsInit *SFBits = AllInstructions[Opcode]->TheDef->getValueAsBitsInit("SoftFail");
+
+    for (unsigned i = 0; i < BitWidth; ++i) {
+      if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE)
+        Insn.push_back(BIT_UNSET);
+      else
+        Insn.push_back(bitFromBits(Bits, i));
+    }
   }
 
   // Returns the record name.
@@ -334,6 +346,8 @@
   // Returns true if predicate matches were emitted, false otherwise.
   bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,unsigned Opc);
 
+  void emitSoftFailCheck(raw_ostream &o, unsigned Indentation, unsigned Opc);
+
   // Emits code to decode the singleton.  Return true if we have matched all the
   // well-known bits.
   bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc);
@@ -800,6 +814,64 @@
   return Predicates->getSize() > 0;
 }
 
+void FilterChooser::emitSoftFailCheck(raw_ostream &o, unsigned Indentation, unsigned Opc) {
+  BitsInit *SFBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("SoftFail");
+  if (!SFBits) return;
+  BitsInit *InstBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("Inst");
+
+  APInt PositiveMask(BitWidth, 0ULL);
+  APInt NegativeMask(BitWidth, 0ULL);
+  for (unsigned i = 0; i < BitWidth; ++i) {
+    bit_value_t B = bitFromBits(*SFBits, i);
+    bit_value_t IB = bitFromBits(*InstBits, i);
+
+    if (B != BIT_TRUE) continue;
+
+    switch (IB) {
+    case BIT_FALSE:
+      // The bit is meant to be false, so emit a check to see if it is true.
+      PositiveMask.setBit(i);
+      break;
+    case BIT_TRUE:
+      // The bit is meant to be true, so emit a check to see if it is false.
+      NegativeMask.setBit(i);
+      break;
+    default:
+      // The bit is not set; this must be an error!
+      StringRef Name = AllInstructions[Opc]->TheDef->getName();
+      errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
+             << Name
+             << " is set but Inst{" << i <<"} is unset!\n"
+             << "  - You can only mark a bit as SoftFail if it is fully defined"
+             << " (1/0 - not '?') in Inst\n";
+      o << "#error SoftFail Conflict, " << Name << "::SoftFail{" << i 
+        << "} set but Inst{" << i << "} undefined!\n";
+    }
+  }
+
+  bool NeedPositiveMask = PositiveMask.getBoolValue();
+  bool NeedNegativeMask = NegativeMask.getBoolValue();
+
+  if (!NeedPositiveMask && !NeedNegativeMask)
+    return;
+
+  std::string PositiveMaskStr = PositiveMask.toString(16, /*signed=*/false);
+  std::string NegativeMaskStr = NegativeMask.toString(16, /*signed=*/false);
+  StringRef BitExt = "";
+  if (BitWidth > 32)
+    BitExt = "ULL";
+
+  o.indent(Indentation) << "if (";
+  if (NeedPositiveMask)
+    o << "insn & 0x" << PositiveMaskStr << BitExt;
+  if (NeedPositiveMask && NeedNegativeMask)
+    o << " || ";
+  if (NeedNegativeMask)
+    o << "~insn & 0x" << NegativeMaskStr << BitExt;
+  o << ")\n";
+  o.indent(Indentation+2) << "S = MCDisassembler::SoftFail;\n";
+}
+
 // Emits code to decode the singleton.  Return true if we have matched all the
 // well-known bits.
 bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
@@ -822,6 +894,7 @@
     if (!emitPredicateMatch(o, Indentation, Opc))
       o << "1";
     o << ") {\n";
+    emitSoftFailCheck(o, Indentation+2, Opc);
     o.indent(Indentation) << "  MI.setOpcode(" << Opc << ");\n";
     std::vector<OperandInfo>& InsnOperands = Operands[Opc];
     for (std::vector<OperandInfo>::iterator
@@ -871,6 +944,7 @@
     else
       o << ") {\n";
   }
+  emitSoftFailCheck(o, Indentation+2, Opc);
   o.indent(Indentation) << "  MI.setOpcode(" << Opc << ");\n";
   std::vector<OperandInfo>& InsnOperands = Operands[Opc];
   for (std::vector<OperandInfo>::iterator





More information about the llvm-commits mailing list