CodeEmitterGen.cpp revision f65027842e82027dd6e8020586a299aaa548e355
1c9670ef17d43a6c20fcc0f6765988216754419a0Chris Lattner//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// The LLVM Compiler Infrastructure 401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// 53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source 63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 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" 19f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey#include "llvm/ADT/StringExtras.h" 20551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h" 212082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm; 22d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 23f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskeyvoid CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) { 24f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end(); 25f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey I != E; ++I) { 26f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Record *R = *I; 27a683f9ba1356e92a5e7243d9f80fe8a8b6f737c8Jim Laskey if (R->getName() == "PHI" || 28a683f9ba1356e92a5e7243d9f80fe8a8b6f737c8Jim Laskey R->getName() == "INLINEASM" || 294406604047423576e36657c7ede266ca42e79642Dan Gohman R->getName() == "DBG_LABEL" || 304406604047423576e36657c7ede266ca42e79642Dan Gohman R->getName() == "EH_LABEL" || 314406604047423576e36657c7ede266ca42e79642Dan Gohman R->getName() == "GC_LABEL" || 3226207e5bf1123a793bd9b38bcda2f569a6b45ef2Jakob Stoklund Olesen R->getName() == "KILL" || 3308d52071bae2f8cc2e9aa6a451118b83d043813bChristopher Lamb R->getName() == "EXTRACT_SUBREG" || 34da47e6e0d003c873da960361549e57ee4617c301Evan Cheng R->getName() == "INSERT_SUBREG" || 35c9298235251b014e86a7368d92b589d093acb64aChristopher Lamb R->getName() == "IMPLICIT_DEF" || 36f8c7394781f7cf27ac52ca087e289436d36844daDan Gohman R->getName() == "SUBREG_TO_REG" || 3787563b39370d7adfd42b0f531409ff9bc2bfcc56Dale Johannesen R->getName() == "COPY_TO_REGCLASS" || 38518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner R->getName() == "DBG_VALUE") continue; 39f8c7394781f7cf27ac52ca087e289436d36844daDan Gohman 40f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey BitsInit *BI = R->getValueAsBitsInit("Inst"); 4128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman 42f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey unsigned numBits = BI->getNumBits(); 43f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey BitsInit *NewBI = new BitsInit(numBits); 44f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) { 45f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey unsigned bitSwapIdx = numBits - bit - 1; 46f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Init *OrigBit = BI->getBit(bit); 47f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Init *BitSwap = BI->getBit(bitSwapIdx); 48f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey NewBI->setBit(bit, BitSwap); 49f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey NewBI->setBit(bitSwapIdx, OrigBit); 50f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 51f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (numBits % 2) { 52f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey unsigned middle = (numBits + 1) / 2; 53f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey NewBI->setBit(middle, BI->getBit(middle)); 5428eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman } 55f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 56f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Update the bits in reversed order so that emitInstrOpBits will get the 57f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // correct endianness. 58f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey R->getValue("Inst")->setValue(NewBI); 5928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman } 6028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman} 6128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman 6228eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman 63cb129031479dfb5583cce6d77fcbb0b68098693aJim Laskey// If the VarBitInit at position 'bit' matches the specified variable then 64cb129031479dfb5583cce6d77fcbb0b68098693aJim Laskey// return the variable bit position. Otherwise return -1. 659b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohmanint CodeEmitterGen::getVariableBit(const std::string &VarName, 66cb129031479dfb5583cce6d77fcbb0b68098693aJim Laskey BitsInit *BI, int bit) { 67f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(BI->getBit(bit))) { 68f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey TypedInit *TI = VBI->getVariable(); 699b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman 709b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman if (VarInit *VI = dynamic_cast<VarInit*>(TI)) { 719b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman if (VI->getName() == VarName) return VBI->getBitNum(); 729b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman } 73f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 74f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 75f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey return -1; 76f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey} 77f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 78f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 791a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid CodeEmitterGen::run(raw_ostream &o) { 80e2ba7787ba84513178611a0d44ca11494be62f51Misha Brukman CodeGenTarget Target; 81048c00db1cd05bbbd616e0eff71756eebd45f6b4Chris Lattner std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 82f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 83f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // For little-endian instruction bit encodings, reverse the bit order 84f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (Target.isLittleEndianEncoding()) reverseBits(Insts); 859fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman 860e5e49e6888c354ff95fc9e56d0881af78cb4269Chris Lattner EmitSourceFileHeader("Machine Code Emitter", o); 87e2ba7787ba84513178611a0d44ca11494be62f51Misha Brukman std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::"; 88ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey 89f65027842e82027dd6e8020586a299aaa548e355Chris Lattner const std::vector<const CodeGenInstruction*> &NumberedInstructions = 90f65027842e82027dd6e8020586a299aaa548e355Chris Lattner Target.getInstructionsByEnumValue(); 919fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman 92ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman // Emit function declaration 93e2ba7787ba84513178611a0d44ca11494be62f51Misha Brukman o << "unsigned " << Target.getName() << "CodeEmitter::" 94acff339e391d23e748b69f61ae5c27fd5620c69fEvan Cheng << "getBinaryCodeForInstr(const MachineInstr &MI) {\n"; 95ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman 96ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey // Emit instruction base values 97ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey o << " static const unsigned InstBits[] = {\n"; 98f65027842e82027dd6e8020586a299aaa548e355Chris Lattner for (std::vector<const CodeGenInstruction*>::const_iterator 99ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey IN = NumberedInstructions.begin(), 100ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey EN = NumberedInstructions.end(); 101ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey IN != EN; ++IN) { 102ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey const CodeGenInstruction *CGI = *IN; 103ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey Record *R = CGI->TheDef; 104ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey 105a683f9ba1356e92a5e7243d9f80fe8a8b6f737c8Jim Laskey if (R->getName() == "PHI" || 106a683f9ba1356e92a5e7243d9f80fe8a8b6f737c8Jim Laskey R->getName() == "INLINEASM" || 1074406604047423576e36657c7ede266ca42e79642Dan Gohman R->getName() == "DBG_LABEL" || 1084406604047423576e36657c7ede266ca42e79642Dan Gohman R->getName() == "EH_LABEL" || 1094406604047423576e36657c7ede266ca42e79642Dan Gohman R->getName() == "GC_LABEL" || 11026207e5bf1123a793bd9b38bcda2f569a6b45ef2Jakob Stoklund Olesen R->getName() == "KILL" || 11108d52071bae2f8cc2e9aa6a451118b83d043813bChristopher Lamb R->getName() == "EXTRACT_SUBREG" || 112da47e6e0d003c873da960361549e57ee4617c301Evan Cheng R->getName() == "INSERT_SUBREG" || 113c9298235251b014e86a7368d92b589d093acb64aChristopher Lamb R->getName() == "IMPLICIT_DEF" || 114f8c7394781f7cf27ac52ca087e289436d36844daDan Gohman R->getName() == "SUBREG_TO_REG" || 11587563b39370d7adfd42b0f531409ff9bc2bfcc56Dale Johannesen R->getName() == "COPY_TO_REGCLASS" || 116518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner R->getName() == "DBG_VALUE") { 117bc95b23156058ab3820d03c56709308e604a981bEvan Cheng o << " 0U,\n"; 118ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey continue; 119ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey } 120188454ae2b36e9130ab01e2e5649e3805edb8154Chris Lattner 1216f334ad8f5c9319b334e2ba68b89d0dd46156788Chris Lattner BitsInit *BI = R->getValueAsBitsInit("Inst"); 1229fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman 1239fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman // Start by filling in fixed values... 124fa3e3b9427a643dae2a54f5b2869eb09ad705831Reid Spencer unsigned Value = 0; 125cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 126cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) { 127cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman Value |= B->getValue() << (e-i-1); 128cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman } 129cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman } 130bc95b23156058ab3820d03c56709308e604a981bEvan Cheng o << " " << Value << "U," << '\t' << "// " << R->getName() << "\n"; 131ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey } 132bc95b23156058ab3820d03c56709308e604a981bEvan Cheng o << " 0U\n };\n"; 133f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 134f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Map to accumulate all the cases. 135f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::map<std::string, std::vector<std::string> > CaseMap; 136f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 137f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Construct all cases statement for each opcode 138f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end(); 139f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey IC != EC; ++IC) { 140f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Record *R = *IC; 141f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey const std::string &InstName = R->getName(); 142f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::string Case(""); 143f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 144a683f9ba1356e92a5e7243d9f80fe8a8b6f737c8Jim Laskey if (InstName == "PHI" || 145a683f9ba1356e92a5e7243d9f80fe8a8b6f737c8Jim Laskey InstName == "INLINEASM" || 1464406604047423576e36657c7ede266ca42e79642Dan Gohman InstName == "DBG_LABEL"|| 1474406604047423576e36657c7ede266ca42e79642Dan Gohman InstName == "EH_LABEL"|| 1484406604047423576e36657c7ede266ca42e79642Dan Gohman InstName == "GC_LABEL"|| 14926207e5bf1123a793bd9b38bcda2f569a6b45ef2Jakob Stoklund Olesen InstName == "KILL"|| 15008d52071bae2f8cc2e9aa6a451118b83d043813bChristopher Lamb InstName == "EXTRACT_SUBREG" || 151da47e6e0d003c873da960361549e57ee4617c301Evan Cheng InstName == "INSERT_SUBREG" || 152c9298235251b014e86a7368d92b589d093acb64aChristopher Lamb InstName == "IMPLICIT_DEF" || 153f8c7394781f7cf27ac52ca087e289436d36844daDan Gohman InstName == "SUBREG_TO_REG" || 15487563b39370d7adfd42b0f531409ff9bc2bfcc56Dale Johannesen InstName == "COPY_TO_REGCLASS" || 155518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner InstName == "DBG_VALUE") continue; 156f8c7394781f7cf27ac52ca087e289436d36844daDan Gohman 157ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey BitsInit *BI = R->getValueAsBitsInit("Inst"); 158ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey const std::vector<RecordVal> &Vals = R->getValues(); 159f30187a36324fb75042d9ffd20c3fb70aff7763dChris Lattner CodeGenInstruction &CGI = Target.getInstruction(R); 160f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner 16128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman // Loop over all of the fields in the instruction, determining which are the 1623da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman // operands to the instruction. 163cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman unsigned op = 0; 1649fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 16528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) { 1667eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman // Is the operand continuous? If so, we can just mask and OR it in 1673da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman // instead of doing it bit-by-bit, saving a lot in runtime cost. 1689b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman const std::string &VarName = Vals[i].getName(); 169f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey bool gotOp = false; 170f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 171f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (int bit = BI->getNumBits()-1; bit >= 0; ) { 1729b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman int varBit = getVariableBit(VarName, BI, bit); 173f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 174f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (varBit == -1) { 175f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey --bit; 176f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } else { 177f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey int beginInstBit = bit; 178f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey int beginVarBit = varBit; 179f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey int N = 1; 180f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 181f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (--bit; bit >= 0;) { 1829b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman varBit = getVariableBit(VarName, BI, bit); 183f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (varBit == -1 || varBit != (beginVarBit - N)) break; 184f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey ++N; 185f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey --bit; 186f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 1877eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman 188f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (!gotOp) { 189f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner /// If this operand is not supposed to be emitted by the generated 190f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner /// emitter, skip it. 191f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner while (CGI.isFlatOperandNotEmitted(op)) 192f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner ++op; 193f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner 1949b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohman Case += " // op: " + VarName + "\n" 195f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey + " op = getMachineOpValue(MI, MI.getOperand(" 196f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner + utostr(op++) + "));\n"; 197f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey gotOp = true; 198f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 199f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 2001cfa0776c3053b894bcc8c74610e09118340aad3Chris Lattner unsigned opMask = ~0U >> (32-N); 201f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey int opShift = beginVarBit - N + 1; 202f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey opMask <<= opShift; 203f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey opShift = beginInstBit - beginVarBit; 204f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 205f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (opShift > 0) { 206f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Case += " Value |= (op & " + utostr(opMask) + "U) << " 207f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey + itostr(opShift) + ";\n"; 208f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } else if (opShift < 0) { 209f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Case += " Value |= (op & " + utostr(opMask) + "U) >> " 210f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey + itostr(-opShift) + ";\n"; 211f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } else { 212f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Case += " Value |= op & " + utostr(opMask) + "U;\n"; 2137eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman } 2147eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman } 2157eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman } 216f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 217f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 2187eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman 219f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner std::vector<std::string> &InstList = CaseMap[Case]; 220f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey InstList.push_back(InstName); 221f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 2223da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 2233da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 224f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Emit initial function code 225f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << " const unsigned opcode = MI.getOpcode();\n" 226f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey << " unsigned Value = InstBits[opcode];\n" 227e3e36263384a7f4662f2eafa090507602a5c391eEvan Cheng << " unsigned op = 0;\n" 228acff339e391d23e748b69f61ae5c27fd5620c69fEvan Cheng << " op = op; // suppress warning\n" 229f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey << " switch (opcode) {\n"; 2303da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 231f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Emit each case statement 232f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::map<std::string, std::vector<std::string> >::iterator IE, EE; 233f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) { 234f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey const std::string &Case = IE->first; 235f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::vector<std::string> &InstList = IE->second; 2363da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 237f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (int i = 0, N = InstList.size(); i < N; i++) { 238f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (i) o << "\n"; 239f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << " case " << Namespace << InstList[i] << ":"; 2409fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman } 241f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << " {\n"; 242f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << Case; 2439fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman o << " break;\n" 2449fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman << " }\n"; 2459fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman } 2467eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman 24728eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman // Default case: unhandled opcode 248cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman o << " default:\n" 249804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " std::string msg;\n" 250804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " raw_string_ostream Msg(msg);\n" 251804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " Msg << \"Not supported instr: \" << MI;\n" 252804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " llvm_report_error(Msg.str());\n" 253cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman << " }\n" 2549fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman << " return Value;\n" 25528eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman << "}\n\n"; 2569fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman} 257