Put targets on folders, if the IDE supports the feature.
[oota-llvm.git] / utils / TableGen / CodeEmitterGen.cpp
index f3c9de96bdb38632e253c163db9639456e25a5dd..957dd19da1c24f790192baef1fd584d6beacf3fa 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include <map>
 using namespace llvm;
 
 // FIXME: Somewhat hackish to use a command line option for this. There should
@@ -74,10 +75,65 @@ void CodeEmitterGen::
 AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
                         unsigned &NumberedOp,
                         std::string &Case, CodeGenTarget &Target) {
-  bool gotOp = false;
   CodeGenInstruction &CGI = Target.getInstruction(R);
 
-  for (int bit = BI->getNumBits()-1; bit >= 0; ) {
+  // Determine if VarName actually contributes to the Inst encoding.
+  int bit = BI->getNumBits()-1;
+
+  // Scan for a bit that this contributed to.
+  for (; bit >= 0; ) {
+    if (getVariableBit(VarName, BI, bit) != -1)
+      break;
+    
+    --bit;
+  }
+  
+  // If we found no bits, ignore this value, otherwise emit the call to get the
+  // operand encoding.
+  if (bit < 0) return;
+  
+  // If the operand matches by name, reference according to that
+  // operand number. Non-matching operands are assumed to be in
+  // order.
+  unsigned OpIdx;
+  if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
+    // Get the machine operand number for the indicated operand.
+    OpIdx = CGI.Operands[OpIdx].MIOperandNo;
+    assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
+           "Explicitly used operand also marked as not emitted!");
+  } else {
+    /// If this operand is not supposed to be emitted by the
+    /// generated emitter, skip it.
+    while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
+      ++NumberedOp;
+    OpIdx = NumberedOp++;
+  }
+  
+  std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx);
+  std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName;
+  
+  // If the source operand has a custom encoder, use it. This will
+  // get the encoding for all of the suboperands.
+  if (!EncoderMethodName.empty()) {
+    // A custom encoder has all of the information for the
+    // sub-operands, if there are more than one, so only
+    // query the encoder once per source operand.
+    if (SO.second == 0) {
+      Case += "      // op: " + VarName + "\n" +
+              "      op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
+      if (MCEmitter)
+        Case += ", Fixups";
+      Case += ");\n";
+    }
+  } else {
+    Case += "      // op: " + VarName + "\n" +
+      "      op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
+    if (MCEmitter)
+      Case += ", Fixups";
+    Case += ");\n";
+  }
+  
+  for (; bit >= 0; ) {
     int varBit = getVariableBit(VarName, BI, bit);
     
     // If this bit isn't from a variable, skip it.
@@ -86,7 +142,7 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
       continue;
     }
     
-    // Figure out the consequtive range of bits covered by this operand, in
+    // Figure out the consecutive range of bits covered by this operand, in
     // order to generate better encoding code.
     int beginInstBit = bit;
     int beginVarBit = varBit;
@@ -97,52 +153,7 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
       ++N;
       --bit;
     }
-    
-    if (!gotOp) {
-      // If the operand matches by name, reference according to that
-      // operand number. Non-matching operands are assumed to be in
-      // order.
-      unsigned OpIdx;
-      if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
-        // Get the machine operand number for the indicated operand.
-        OpIdx = CGI.Operands[OpIdx].MIOperandNo;
-        assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
-               "Explicitly used operand also marked as not emitted!");
-      } else {
-        /// If this operand is not supposed to be emitted by the
-        /// generated emitter, skip it.
-        while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
-          ++NumberedOp;
-        OpIdx = NumberedOp++;
-      }
-      std::pair<unsigned, unsigned> SO =CGI.Operands.getSubOperandNumber(OpIdx);
-      std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName;
-      
-      // If the source operand has a custom encoder, use it. This will
-      // get the encoding for all of the suboperands.
-      if (!EncoderMethodName.empty()) {
-        // A custom encoder has all of the information for the
-        // sub-operands, if there are more than one, so only
-        // query the encoder once per source operand.
-        if (SO.second == 0) {
-          Case += "      // op: " + VarName + "\n"
-          + "      op = " + EncoderMethodName + "(MI, "
-          + utostr(OpIdx);
-          if (MCEmitter)
-            Case += ", Fixups";
-          Case += ");\n";
-        }
-      } else {
-        Case += "      // op: " + VarName + "\n" +
-                "      op = getMachineOpValue(MI, MI.getOperand(" +
-                utostr(OpIdx) + ")";
-        if (MCEmitter)
-          Case += ", Fixups";
-        Case += ");\n";
-      }
-      gotOp = true;
-    }
-    
+     
     unsigned opMask = ~0U >> (32-N);
     int opShift = beginVarBit - N + 1;
     opMask <<= opShift;
@@ -188,14 +199,13 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
 }
 
 void CodeEmitterGen::run(raw_ostream &o) {
-  CodeGenTarget Target;
+  CodeGenTarget Target(Records);
   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
 
   // For little-endian instruction bit encodings, reverse the bit order
   if (Target.isLittleEndianEncoding()) reverseBits(Insts);
 
   EmitSourceFileHeader("Machine Code Emitter", o);
-  std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";
 
   const std::vector<const CodeGenInstruction*> &NumberedInstructions =
     Target.getInstructionsByEnumValue();
@@ -243,7 +253,8 @@ void CodeEmitterGen::run(raw_ostream &o) {
     Record *R = *IC;
     if (R->getValueAsString("Namespace") == "TargetOpcode")
       continue;
-    const std::string &InstName = R->getName();
+    const std::string &InstName = R->getValueAsString("Namespace") + "::"
+      + R->getName();
     std::string Case = getInstructionCase(R, Target);
 
     CaseMap[Case].push_back(InstName);
@@ -253,7 +264,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
   o << "  const unsigned opcode = MI.getOpcode();\n"
     << "  unsigned Value = InstBits[opcode];\n"
     << "  unsigned op = 0;\n"
-    << "  op = op;  // suppress warning\n"
+    << "  (void)op;  // suppress warning\n"
     << "  switch (opcode) {\n";
 
   // Emit each case statement
@@ -264,7 +275,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
 
     for (int i = 0, N = InstList.size(); i < N; i++) {
       if (i) o << "\n";
-      o << "    case " << Namespace << InstList[i]  << ":";
+      o << "    case " << InstList[i]  << ":";
     }
     o << " {\n";
     o << Case;