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