Move base value of instruction to lookup table to prepare for case reduction.
authorJim Laskey <jlaskey@mac.com>
Wed, 12 Jul 2006 19:15:43 +0000 (19:15 +0000)
committerJim Laskey <jlaskey@mac.com>
Wed, 12 Jul 2006 19:15:43 +0000 (19:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29122 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/CodeEmitterGen.cpp

index 18827ab76a0eed5ab6cca571e8dbd4e1c4fd7205..3e9a6e9e9ab9fc8cb78f02080d7916d6682b07e4 100644 (file)
@@ -77,21 +77,30 @@ void CodeEmitterGen::run(std::ostream &o) {
 
   EmitSourceFileHeader("Machine Code Emitter", o);
   std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";
+  
+  std::vector<const CodeGenInstruction*> NumberedInstructions;
+  Target.getInstructionsByEnumValue(NumberedInstructions);
 
   // Emit function declaration
   o << "unsigned " << Target.getName() << "CodeEmitter::"
-    << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
-    << "  unsigned Value = 0;\n"
-    << "  switch (MI.getOpcode()) {\n";
+    << "getBinaryCodeForInstr(MachineInstr &MI) {\n";
 
-  // Emit a case statement for each opcode
-  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
-       I != E; ++I) {
-    Record *R = *I;
-    if (R->getName() == "PHI" || R->getName() == "INLINEASM") continue;
+  // Emit instruction base values
+  o << "  static const unsigned InstBits[] = {\n";
+  for (std::vector<const CodeGenInstruction*>::iterator
+          IN = NumberedInstructions.begin(),
+          EN = NumberedInstructions.end();
+       IN != EN; ++IN) {
+    const CodeGenInstruction *CGI = *IN;
+    Record *R = CGI->TheDef;
+    
+    if (IN != NumberedInstructions.begin()) o << ",\n";
+    
+    if (R->getName() == "PHI" || R->getName() == "INLINEASM") {
+      o << "    0U";
+      continue;
+    }
     
-    o << "    case " << Namespace << R->getName() << ": {\n";
-
     BitsInit *BI = R->getValueAsBitsInit("Inst");
 
     // For little-endian instruction bit encodings, reverse the bit order
@@ -119,20 +128,31 @@ void CodeEmitterGen::run(std::ostream &o) {
     unsigned Value = 0;
     const std::vector<RecordVal> &Vals = R->getValues();
 
-    DEBUG(o << "      // prefilling: ");
     // Start by filling in fixed values...
     for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
       if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
         Value |= B->getValue() << (e-i-1);
-        DEBUG(o << B->getValue());
-      } else {
-        DEBUG(o << "0");
       }
     }
-    DEBUG(o << "\n");
+    o << "    " << Value << "U";
+  }
+  o << "\n  };\n";
 
-    DEBUG(o << "      // " << *R->getValue("Inst") << "\n");
-    o << "      Value = " << Value << "U;\n\n";
+  // Emit initial function code
+  o << "  const unsigned opcode = MI.getOpcode();\n"
+    << "  unsigned Value = InstBits[opcode];\n"
+    << "  switch (opcode) {\n";
+
+  // Emit a case statement for each opcode
+  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
+       I != E; ++I) {
+    Record *R = *I;
+    if (R->getName() == "PHI" || R->getName() == "INLINEASM") continue;
+    
+    o << "    case " << Namespace << R->getName() << ": {\n";
+
+    BitsInit *BI = R->getValueAsBitsInit("Inst");
+    const std::vector<RecordVal> &Vals = R->getValues();
 
     // Loop over all of the fields in the instruction, determining which are the
     // operands to the instruction.