CodeEmitterGen.cpp revision 28eefa5464ca6415fcee577d5c47f739535d7e6c
1c9670ef17d43a6c20fcc0f6765988216754419a0Chris Lattner//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
201d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//
301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//                     The LLVM Compiler Infrastructure
401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//
501d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// This file was developed by the LLVM research group and is distributed under
601d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details.
701d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//
801d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//===----------------------------------------------------------------------===//
9c9670ef17d43a6c20fcc0f6765988216754419a0Chris Lattner//
104e4f8631f68862cfd725de66422bb867bda0efdfMisha Brukman// CodeEmitterGen uses the descriptions of instructions and their fields to
114e4f8631f68862cfd725de66422bb867bda0efdfMisha Brukman// construct an automated code emitter: a function that, given a MachineInstr,
124e4f8631f68862cfd725de66422bb867bda0efdfMisha Brukman// returns the (currently, 32-bit unsigned) value of the instruction.
13c9670ef17d43a6c20fcc0f6765988216754419a0Chris Lattner//
14c9670ef17d43a6c20fcc0f6765988216754419a0Chris Lattner//===----------------------------------------------------------------------===//
15c9670ef17d43a6c20fcc0f6765988216754419a0Chris Lattner
169fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman#include "CodeEmitterGen.h"
17d7a5b2826cbef9d980893a41f39bab6948e9c852Misha Brukman#include "CodeGenTarget.h"
18c9670ef17d43a6c20fcc0f6765988216754419a0Chris Lattner#include "Record.h"
19551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h"
202082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm;
21d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
2228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukmanvoid CodeEmitterGen::emitInstrOpBits(std::ostream &o,
2328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                                     const std::vector<RecordVal> &Vals,
2428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                                     std::map<std::string, unsigned> &OpOrder,
2528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                                     std::map<std::string, bool> &OpContinuous)
2628eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman{
2728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman  for (unsigned f = 0, e = Vals.size(); f != e; ++f) {
2828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    if (Vals[f].getPrefix()) {
2928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
3028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman
3128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      // Scan through the field looking for bit initializers of the current
3228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      // variable...
3328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
3428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        Init *I = FieldInitializer->getBit(i);
3528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        if (BitInit *BI = dynamic_cast<BitInit*>(I)) {
3628eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman          DEBUG(o << "      // bit init: f: " << f << ", i: " << i << "\n");
3728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        } else if (UnsetInit *UI = dynamic_cast<UnsetInit*>(I)) {
3828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman          DEBUG(o << "      // unset init: f: " << f << ", i: " << i << "\n");
3928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        } else if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(I)) {
4028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman          TypedInit *TI = VBI->getVariable();
4128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman          if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
4228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            // If the bits of the field are laid out consecutively in the
4328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            // instruction, then instead of separately ORing in bits, just
4428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            // mask and shift the entire field for efficiency.
4528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            if (OpContinuous[VI->getName()]) {
4628eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman              // already taken care of in the loop above, thus there is no
4728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman              // need to individually OR in the bits
4828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman
4928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman              // for debugging, output the regular version anyway, commented
5028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman              DEBUG(o << "      // Value |= getValueBit(op"
5128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                      << OpOrder[VI->getName()] << ", " << VBI->getBitNum()
5228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                      << ")" << " << " << i << ";\n");
5328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            } else {
5428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman              o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
5528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                << ", " << VBI->getBitNum()
5628eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                << ")" << " << " << i << ";\n";
5728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            }
5828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman          } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
5928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            // FIXME: implement this!
6028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            std::cerr << "Error: FieldInit not implemented!\n";
6128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            abort();
6228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman          } else {
6328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            std::cerr << "Error: unimplemented case in "
6428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman                      << "CodeEmitterGen::emitInstrOpBits()\n";
6528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman            abort();
6628eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman          }
6728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        }
6828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      }
6928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    }
7028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman  }
7128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman}
7228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman
7328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman
74048c00db1cd05bbbd616e0eff71756eebd45f6b4Chris Lattnervoid CodeEmitterGen::run(std::ostream &o) {
75e2ba7787ba84513178611a0d44ca11494be62f51Misha Brukman  CodeGenTarget Target;
76048c00db1cd05bbbd616e0eff71756eebd45f6b4Chris Lattner  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
779fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
780e5e49e6888c354ff95fc9e56d0881af78cb4269Chris Lattner  EmitSourceFileHeader("Machine Code Emitter", o);
792c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner  o << "namespace llvm {\n\n";
80e2ba7787ba84513178611a0d44ca11494be62f51Misha Brukman  std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";
819fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
82ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman  // Emit function declaration
83e2ba7787ba84513178611a0d44ca11494be62f51Misha Brukman  o << "unsigned " << Target.getName() << "CodeEmitter::"
849fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
859fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "  unsigned Value = 0;\n"
86f4ef4c881f851ae019f9f48d5473f9f1586d1dbcMisha Brukman    << "  DEBUG(std::cerr << MI);\n"
879fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "  switch (MI.getOpcode()) {\n";
88ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman
89ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman  // Emit a case statement for each opcode
909fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
91cf1b5853127352096ea6c2f8ec130f809168da2fChris Lattner       I != E; ++I) {
929fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    Record *R = *I;
93ecc7fd3c56f482ecb4ea42d2cf83e54f73dfb69aMisha Brukman    o << "    case " << Namespace << R->getName() << ": {\n"
94f4ef4c881f851ae019f9f48d5473f9f1586d1dbcMisha Brukman      << "      DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n";
959fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
966f334ad8f5c9319b334e2ba68b89d0dd46156788Chris Lattner    BitsInit *BI = R->getValueAsBitsInit("Inst");
979fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
9828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    // For little-endian instruction bit encodings, reverse the bit order
9928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    if (Target.isLittleEndianEncoding()) {
10028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      unsigned numBits = BI->getNumBits();
10128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      BitsInit *NewBI = new BitsInit(numBits);
10228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
10328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        unsigned bitSwapIdx = numBits - bit - 1;
10428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        Init *OrigBit = BI->getBit(bit);
10528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        Init *BitSwap = BI->getBit(bitSwapIdx);
10628eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        NewBI->setBit(bit, BitSwap);
10728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        NewBI->setBit(bitSwapIdx, OrigBit);
10828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      }
10928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      if (numBits % 2) {
11028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        unsigned middle = (numBits + 1) / 2;
11128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        NewBI->setBit(middle, BI->getBit(middle));
11228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      }
11328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      BI = NewBI;
11428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    }
11528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman
1169fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    unsigned Value = 0;
1179fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    const std::vector<RecordVal> &Vals = R->getValues();
1189fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
119f6e5217b54441866dec596c1be20747036440cd4Misha Brukman    DEBUG(o << "      // prefilling: ");
1209fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    // Start by filling in fixed values...
121cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
122cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
123cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman        Value |= B->getValue() << (e-i-1);
124f6e5217b54441866dec596c1be20747036440cd4Misha Brukman        DEBUG(o << B->getValue());
125cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman      } else {
126f6e5217b54441866dec596c1be20747036440cd4Misha Brukman        DEBUG(o << "0");
127cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman      }
128cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    }
129f6e5217b54441866dec596c1be20747036440cd4Misha Brukman    DEBUG(o << "\n");
1309fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
1316f334ad8f5c9319b334e2ba68b89d0dd46156788Chris Lattner    DEBUG(o << "      // " << *R->getValue("Inst") << "\n");
132cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    o << "      Value = " << Value << "U;\n\n";
1339fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
13428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    // Loop over all of the fields in the instruction, determining which are the
135d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner    // operands to the instruction.
136cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    unsigned op = 0;
137d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner    std::map<std::string, unsigned> OpOrder;
138d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner    std::map<std::string, bool> OpContinuous;
1399fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
14028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman      if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) {
1417eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman        // Is the operand continuous? If so, we can just mask and OR it in
1427eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman        // instead of doing it bit-by-bit, saving a lot in runtime cost.
14328eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman        BitsInit *InstInit = BI;
144d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner        int beginBitInVar = -1, endBitInVar = -1;
145d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner        int beginBitInInst = -1, endBitInInst = -1;
1467eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman        bool continuous = true;
1477eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
1487eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman        for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) {
1497eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman          if (VarBitInit *VBI =
1507eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) {
1517eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman            TypedInit *TI = VBI->getVariable();
1527eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
1537eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              // only process the current variable
1547eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              if (VI->getName() != Vals[i].getName())
1557eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                continue;
1567eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
1577eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              if (beginBitInVar == -1)
1587eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                beginBitInVar = VBI->getBitNum();
1597eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
1607eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              if (endBitInVar == -1)
1617eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                endBitInVar = VBI->getBitNum();
1627eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              else {
1637eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                if (endBitInVar == (int)VBI->getBitNum() + 1)
1647eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                  endBitInVar = VBI->getBitNum();
1657eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                else {
1667eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                  continuous = false;
1677eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                  break;
1687eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                }
1697eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              }
1707eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
1717eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              if (beginBitInInst == -1)
1727eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                beginBitInInst = bit;
1737eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              if (endBitInInst == -1)
1747eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                endBitInInst = bit;
1757eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              else {
1767eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                if (endBitInInst == bit + 1)
1777eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                  endBitInInst = bit;
1787eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                else {
1797eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                  continuous = false;
1807eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                  break;
1817eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                }
1827eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              }
1837eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
1847eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              // maintain same distance between bits in field and bits in
1857eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              // instruction. if the relative distances stay the same
1867eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              // throughout,
187d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner              if (beginBitInVar - (int)VBI->getBitNum() !=
188d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner                  beginBitInInst - bit) {
1897eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                continuous = false;
1907eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman                break;
1917eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              }
1927eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman            }
1937eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman          }
1947eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman        }
1957eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
196ffaee3755604e8227cefb209d4741f108ae16b0eChris Lattner        // If we have found no bit in "Inst" which comes from this field, then
197ffaee3755604e8227cefb209d4741f108ae16b0eChris Lattner        // this is not an operand!!
198d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner        if (beginBitInInst != -1) {
199d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          o << "      // op" << op << ": " << Vals[i].getName() << "\n"
200d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            << "      int64_t op" << op
201d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
202d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          //<< "   MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
203d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          OpOrder[Vals[i].getName()] = op++;
2047eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
205d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          DEBUG(o << "      // Var: begin = " << beginBitInVar
206d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner                  << ", end = " << endBitInVar
207d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner                  << "; Inst: begin = " << beginBitInInst
208d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner                  << ", end = " << endBitInInst << "\n");
209d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner
210d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          if (continuous) {
211d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            DEBUG(o << "      // continuous: op" << OpOrder[Vals[i].getName()]
212d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner                    << "\n");
213d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner
214d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            // Mask off the right bits
215d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            // Low mask (ie. shift, if necessary)
216dfd414ab770a389d29b7294f20e38cbf74c9f9a9Misha Brukman            assert(endBitInVar >= 0 && "Negative shift amount in masking!");
217d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            if (endBitInVar != 0) {
218d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner              o << "      op" << OpOrder[Vals[i].getName()]
219d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner                << " >>= " << endBitInVar << ";\n";
220d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner              beginBitInVar -= endBitInVar;
221d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner              endBitInVar = 0;
222d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            }
223d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner
224d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            // High mask
2257eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman            o << "      op" << OpOrder[Vals[i].getName()]
226d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner              << " &= (1<<" << beginBitInVar+1 << ") - 1;\n";
227d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner
228d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            // Shift the value to the correct place (according to place in inst)
2294e4f8631f68862cfd725de66422bb867bda0efdfMisha Brukman            assert(endBitInInst >= 0 && "Negative shift amount!");
230d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            if (endBitInInst != 0)
231d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner              o << "      op" << OpOrder[Vals[i].getName()]
2327eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman              << " <<= " << endBitInInst << ";\n";
233d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner
234d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            // Just OR in the result
235d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner            o << "      Value |= op" << OpOrder[Vals[i].getName()] << ";\n";
236d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          }
237d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner
238d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          // otherwise, will be taken care of in the loop below using this
239d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          // value:
240d7efef9d1481a96425e09b8a37114c815ab5da1cChris Lattner          OpContinuous[Vals[i].getName()] = continuous;
2417eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman        }
2429fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      }
2439fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    }
2449fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
24528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    emitInstrOpBits(o, Vals, OpOrder, OpContinuous);
2469fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman
2479fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    o << "      break;\n"
2489fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman      << "    }\n";
2499fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman  }
2507eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman
25128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman  // Default case: unhandled opcode
252cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman  o << "  default:\n"
2530bb806bd9a707358261ab83ee025c7b969c2edf0Misha Brukman    << "    std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
254cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    << "    abort();\n"
255cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman    << "  }\n"
2569fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman    << "  return Value;\n"
25728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman    << "}\n\n";
258d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
2592c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner  o << "} // End llvm namespace \n";
2609fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman}
261