Revert r114340 (improvements in Darwin function prologue/epilogue), as it broke
[oota-llvm.git] / utils / TableGen / CodeEmitterGen.cpp
index ac085120bf3dcaba640282d885eb9d664f6bd405..fbe9947b096ebe965ed2da7c5f5eb4dc3a8a3a83 100644 (file)
 #include "CodeGenTarget.h"
 #include "Record.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 using namespace llvm;
 
+static cl::opt<bool>
+MCEmitter("mc-code-emitter",
+          cl::desc("Generate CodeEmitter for use with the MC library."),
+          cl::init(false));
+
 void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
   for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
        I != E; ++I) {
@@ -49,7 +55,6 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
   }
 }
 
-
 // If the VarBitInit at position 'bit' matches the specified variable then
 // return the variable bit position.  Otherwise return -1.
 int CodeEmitterGen::getVariableBit(const std::string &VarName,
@@ -65,7 +70,6 @@ int CodeEmitterGen::getVariableBit(const std::string &VarName,
   return -1;
 }
 
-
 void CodeEmitterGen::run(raw_ostream &o) {
   CodeGenTarget Target;
   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
@@ -81,7 +85,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
 
   // Emit function declaration
   o << "unsigned " << Target.getName() << "CodeEmitter::"
-    << "getBinaryCodeForInstr(const MachineInstr &MI) {\n";
+    << "getBinaryCodeForInstr(const MachineInstr &MI) const {\n";
 
   // Emit instruction base values
   o << "  static const unsigned InstBits[] = {\n";
@@ -128,7 +132,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
 
     // Loop over all of the fields in the instruction, determining which are the
     // operands to the instruction.
-    unsigned op = 0;
+    unsigned NumberedOp = 0;
     for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
       if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) {
         // Is the operand continuous? If so, we can just mask and OR it in
@@ -154,14 +158,43 @@ void CodeEmitterGen::run(raw_ostream &o) {
             }
 
             if (!gotOp) {
-              /// If this operand is not supposed to be emitted by the generated
-              /// emitter, skip it.
-              while (CGI.isFlatOperandNotEmitted(op))
-                ++op;
-
-              Case += "      // op: " + VarName + "\n"
-                   +  "      op = getMachineOpValue(MI, MI.getOperand("
-                   +  utostr(op++) + "));\n";
+              // 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) + ");\n";
+                }
+              } else {
+                Case += "      // op: " + VarName + "\n"
+                     +  "      op = getMachineOpValue(MI, MI.getOperand("
+                     +  utostr(OpIdx) + "));\n";
+              }
               gotOp = true;
             }
 
@@ -188,7 +221,6 @@ void CodeEmitterGen::run(raw_ostream &o) {
     InstList.push_back(InstName);
   }
 
-
   // Emit initial function code
   o << "  const unsigned opcode = MI.getOpcode();\n"
     << "  unsigned Value = InstBits[opcode];\n"