Home | History | Annotate | Download | only in TableGen
      1 //===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // CodeEmitterGen uses the descriptions of instructions and their fields to
     11 // construct an automated code emitter: a function that, given a MachineInstr,
     12 // returns the (currently, 32-bit unsigned) value of the instruction.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "CodeGenTarget.h"
     17 #include "llvm/ADT/StringExtras.h"
     18 #include "llvm/Support/CommandLine.h"
     19 #include "llvm/Support/Debug.h"
     20 #include "llvm/TableGen/Record.h"
     21 #include "llvm/TableGen/TableGenBackend.h"
     22 #include <map>
     23 #include <string>
     24 #include <vector>
     25 using namespace llvm;
     26 
     27 namespace {
     28 
     29 class CodeEmitterGen {
     30   RecordKeeper &Records;
     31 public:
     32   CodeEmitterGen(RecordKeeper &R) : Records(R) {}
     33 
     34   void run(raw_ostream &o);
     35 private:
     36   int getVariableBit(const std::string &VarName, BitsInit *BI, int bit);
     37   std::string getInstructionCase(Record *R, CodeGenTarget &Target);
     38   void AddCodeToMergeInOperand(Record *R, BitsInit *BI,
     39                                const std::string &VarName,
     40                                unsigned &NumberedOp,
     41                                std::set<unsigned> &NamedOpIndices,
     42                                std::string &Case, CodeGenTarget &Target);
     43 
     44 };
     45 
     46 // If the VarBitInit at position 'bit' matches the specified variable then
     47 // return the variable bit position.  Otherwise return -1.
     48 int CodeEmitterGen::getVariableBit(const std::string &VarName,
     49                                    BitsInit *BI, int bit) {
     50   if (VarBitInit *VBI = dyn_cast<VarBitInit>(BI->getBit(bit))) {
     51     if (VarInit *VI = dyn_cast<VarInit>(VBI->getBitVar()))
     52       if (VI->getName() == VarName)
     53         return VBI->getBitNum();
     54   } else if (VarInit *VI = dyn_cast<VarInit>(BI->getBit(bit))) {
     55     if (VI->getName() == VarName)
     56       return 0;
     57   }
     58 
     59   return -1;
     60 }
     61 
     62 void CodeEmitterGen::
     63 AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
     64                         unsigned &NumberedOp,
     65                         std::set<unsigned> &NamedOpIndices,
     66                         std::string &Case, CodeGenTarget &Target) {
     67   CodeGenInstruction &CGI = Target.getInstruction(R);
     68 
     69   // Determine if VarName actually contributes to the Inst encoding.
     70   int bit = BI->getNumBits()-1;
     71 
     72   // Scan for a bit that this contributed to.
     73   for (; bit >= 0; ) {
     74     if (getVariableBit(VarName, BI, bit) != -1)
     75       break;
     76 
     77     --bit;
     78   }
     79 
     80   // If we found no bits, ignore this value, otherwise emit the call to get the
     81   // operand encoding.
     82   if (bit < 0) return;
     83 
     84   // If the operand matches by name, reference according to that
     85   // operand number. Non-matching operands are assumed to be in
     86   // order.
     87   unsigned OpIdx;
     88   if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
     89     // Get the machine operand number for the indicated operand.
     90     OpIdx = CGI.Operands[OpIdx].MIOperandNo;
     91     assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
     92            "Explicitly used operand also marked as not emitted!");
     93   } else {
     94     unsigned NumberOps = CGI.Operands.size();
     95     /// If this operand is not supposed to be emitted by the
     96     /// generated emitter, skip it.
     97     while (NumberedOp < NumberOps &&
     98            (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
     99               (!NamedOpIndices.empty() && NamedOpIndices.count(
    100                 CGI.Operands.getSubOperandNumber(NumberedOp).first)))) {
    101       ++NumberedOp;
    102 
    103       if (NumberedOp >= CGI.Operands.back().MIOperandNo +
    104                         CGI.Operands.back().MINumOperands) {
    105         errs() << "Too few operands in record " << R->getName() <<
    106                   " (no match for variable " << VarName << "):\n";
    107         errs() << *R;
    108         errs() << '\n';
    109 
    110         return;
    111       }
    112     }
    113 
    114     OpIdx = NumberedOp++;
    115   }
    116 
    117   std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx);
    118   std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName;
    119 
    120   // If the source operand has a custom encoder, use it. This will
    121   // get the encoding for all of the suboperands.
    122   if (!EncoderMethodName.empty()) {
    123     // A custom encoder has all of the information for the
    124     // sub-operands, if there are more than one, so only
    125     // query the encoder once per source operand.
    126     if (SO.second == 0) {
    127       Case += "      // op: " + VarName + "\n" +
    128               "      op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
    129       Case += ", Fixups, STI";
    130       Case += ");\n";
    131     }
    132   } else {
    133     Case += "      // op: " + VarName + "\n" +
    134       "      op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
    135     Case += ", Fixups, STI";
    136     Case += ");\n";
    137   }
    138 
    139   for (; bit >= 0; ) {
    140     int varBit = getVariableBit(VarName, BI, bit);
    141 
    142     // If this bit isn't from a variable, skip it.
    143     if (varBit == -1) {
    144       --bit;
    145       continue;
    146     }
    147 
    148     // Figure out the consecutive range of bits covered by this operand, in
    149     // order to generate better encoding code.
    150     int beginInstBit = bit;
    151     int beginVarBit = varBit;
    152     int N = 1;
    153     for (--bit; bit >= 0;) {
    154       varBit = getVariableBit(VarName, BI, bit);
    155       if (varBit == -1 || varBit != (beginVarBit - N)) break;
    156       ++N;
    157       --bit;
    158     }
    159 
    160     uint64_t opMask = ~(uint64_t)0 >> (64-N);
    161     int opShift = beginVarBit - N + 1;
    162     opMask <<= opShift;
    163     opShift = beginInstBit - beginVarBit;
    164 
    165     if (opShift > 0) {
    166       Case += "      Value |= (op & UINT64_C(" + utostr(opMask) + ")) << " +
    167               itostr(opShift) + ";\n";
    168     } else if (opShift < 0) {
    169       Case += "      Value |= (op & UINT64_C(" + utostr(opMask) + ")) >> " +
    170               itostr(-opShift) + ";\n";
    171     } else {
    172       Case += "      Value |= op & UINT64_C(" + utostr(opMask) + ");\n";
    173     }
    174   }
    175 }
    176 
    177 
    178 std::string CodeEmitterGen::getInstructionCase(Record *R,
    179                                                CodeGenTarget &Target) {
    180   std::string Case;
    181 
    182   BitsInit *BI = R->getValueAsBitsInit("Inst");
    183   const std::vector<RecordVal> &Vals = R->getValues();
    184   unsigned NumberedOp = 0;
    185 
    186   std::set<unsigned> NamedOpIndices;
    187   // Collect the set of operand indices that might correspond to named
    188   // operand, and skip these when assigning operands based on position.
    189   if (Target.getInstructionSet()->
    190        getValueAsBit("noNamedPositionallyEncodedOperands")) {
    191     CodeGenInstruction &CGI = Target.getInstruction(R);
    192     for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
    193       unsigned OpIdx;
    194       if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
    195         continue;
    196 
    197       NamedOpIndices.insert(OpIdx);
    198     }
    199   }
    200 
    201   // Loop over all of the fields in the instruction, determining which are the
    202   // operands to the instruction.
    203   for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
    204     // Ignore fixed fields in the record, we're looking for values like:
    205     //    bits<5> RST = { ?, ?, ?, ?, ? };
    206     if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
    207       continue;
    208 
    209     AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp,
    210                             NamedOpIndices, Case, Target);
    211   }
    212 
    213   std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
    214   if (!PostEmitter.empty()) {
    215     Case += "      Value = " + PostEmitter + "(MI, Value";
    216     Case += ", STI";
    217     Case += ");\n";
    218   }
    219 
    220   return Case;
    221 }
    222 
    223 void CodeEmitterGen::run(raw_ostream &o) {
    224   CodeGenTarget Target(Records);
    225   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
    226 
    227   // For little-endian instruction bit encodings, reverse the bit order
    228   Target.reverseBitsForLittleEndianEncoding();
    229 
    230   const std::vector<const CodeGenInstruction*> &NumberedInstructions =
    231     Target.getInstructionsByEnumValue();
    232 
    233   // Emit function declaration
    234   o << "uint64_t " << Target.getName();
    235   o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
    236     << "    SmallVectorImpl<MCFixup> &Fixups,\n"
    237     << "    const MCSubtargetInfo &STI) const {\n";
    238 
    239   // Emit instruction base values
    240   o << "  static const uint64_t InstBits[] = {\n";
    241   for (std::vector<const CodeGenInstruction*>::const_iterator
    242           IN = NumberedInstructions.begin(),
    243           EN = NumberedInstructions.end();
    244        IN != EN; ++IN) {
    245     const CodeGenInstruction *CGI = *IN;
    246     Record *R = CGI->TheDef;
    247 
    248     if (R->getValueAsString("Namespace") == "TargetOpcode" ||
    249         R->getValueAsBit("isPseudo")) {
    250       o << "    UINT64_C(0),\n";
    251       continue;
    252     }
    253 
    254     BitsInit *BI = R->getValueAsBitsInit("Inst");
    255 
    256     // Start by filling in fixed values.
    257     uint64_t Value = 0;
    258     for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
    259       if (BitInit *B = dyn_cast<BitInit>(BI->getBit(e-i-1)))
    260         Value |= (uint64_t)B->getValue() << (e-i-1);
    261     }
    262     o << "    UINT64_C(" << Value << ")," << '\t' << "// " << R->getName() << "\n";
    263   }
    264   o << "    UINT64_C(0)\n  };\n";
    265 
    266   // Map to accumulate all the cases.
    267   std::map<std::string, std::vector<std::string> > CaseMap;
    268 
    269   // Construct all cases statement for each opcode
    270   for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end();
    271         IC != EC; ++IC) {
    272     Record *R = *IC;
    273     if (R->getValueAsString("Namespace") == "TargetOpcode" ||
    274         R->getValueAsBit("isPseudo"))
    275       continue;
    276     const std::string &InstName = R->getValueAsString("Namespace") + "::"
    277       + R->getName();
    278     std::string Case = getInstructionCase(R, Target);
    279 
    280     CaseMap[Case].push_back(InstName);
    281   }
    282 
    283   // Emit initial function code
    284   o << "  const unsigned opcode = MI.getOpcode();\n"
    285     << "  uint64_t Value = InstBits[opcode];\n"
    286     << "  uint64_t op = 0;\n"
    287     << "  (void)op;  // suppress warning\n"
    288     << "  switch (opcode) {\n";
    289 
    290   // Emit each case statement
    291   std::map<std::string, std::vector<std::string> >::iterator IE, EE;
    292   for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) {
    293     const std::string &Case = IE->first;
    294     std::vector<std::string> &InstList = IE->second;
    295 
    296     for (int i = 0, N = InstList.size(); i < N; i++) {
    297       if (i) o << "\n";
    298       o << "    case " << InstList[i]  << ":";
    299     }
    300     o << " {\n";
    301     o << Case;
    302     o << "      break;\n"
    303       << "    }\n";
    304   }
    305 
    306   // Default case: unhandled opcode
    307   o << "  default:\n"
    308     << "    std::string msg;\n"
    309     << "    raw_string_ostream Msg(msg);\n"
    310     << "    Msg << \"Not supported instr: \" << MI;\n"
    311     << "    report_fatal_error(Msg.str());\n"
    312     << "  }\n"
    313     << "  return Value;\n"
    314     << "}\n\n";
    315 }
    316 
    317 } // End anonymous namespace
    318 
    319 namespace llvm {
    320 
    321 void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) {
    322   emitSourceFileHeader("Machine Code Emitter", OS);
    323   CodeEmitterGen(RK).run(OS);
    324 }
    325 
    326 } // End llvm namespace
    327