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 16d7a5b2826cbef9d980893a41f39bab6948e9c852Misha Brukman#include "CodeGenTarget.h" 17f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey#include "llvm/ADT/StringExtras.h" 18551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h" 194ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Record.h" 206f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 21eac8f35da8935cb5e5d6f6f0f02d0648fd8f130bBill Wendling#include <map> 226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <string> 236f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <vector> 242082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm; 25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 266f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 276f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass CodeEmitterGen { 296f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen RecordKeeper &Records; 306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeEmitterGen(RecordKeeper &R) : Records(R) {} 326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void run(raw_ostream &o); 346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate: 356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen int getVariableBit(const std::string &VarName, BitsInit *BI, int bit); 366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string getInstructionCase(Record *R, CodeGenTarget &Target); 376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void AddCodeToMergeInOperand(Record *R, BitsInit *BI, 386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen const std::string &VarName, 396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned &NumberedOp, 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<unsigned> &NamedOpIndices, 416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string &Case, CodeGenTarget &Target); 426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 45cb129031479dfb5583cce6d77fcbb0b68098693aJim Laskey// If the VarBitInit at position 'bit' matches the specified variable then 46cb129031479dfb5583cce6d77fcbb0b68098693aJim Laskey// return the variable bit position. Otherwise return -1. 479b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohmanint CodeEmitterGen::getVariableBit(const std::string &VarName, 48d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher BitsInit *BI, int bit) { 496cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (VarBitInit *VBI = dyn_cast<VarBitInit>(BI->getBit(bit))) { 506cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (VarInit *VI = dyn_cast<VarInit>(VBI->getBitVar())) 5198e969ae20352c0255edf25def392577de61e693Chris Lattner if (VI->getName() == VarName) 5298e969ae20352c0255edf25def392577de61e693Chris Lattner return VBI->getBitNum(); 536cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva } else if (VarInit *VI = dyn_cast<VarInit>(BI->getBit(bit))) { 544cdcb4772d95b9e801a0f3cd43776cef3af3b530Owen Anderson if (VI->getName() == VarName) 554cdcb4772d95b9e801a0f3cd43776cef3af3b530Owen Anderson return 0; 564cdcb4772d95b9e801a0f3cd43776cef3af3b530Owen Anderson } 578b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 58f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey return -1; 598b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach} 60f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 611620117f76b99560406ed90197173b72a9b8b66eChris Lattnervoid CodeEmitterGen:: 62d568b3f55294917d1cc701da14a8a7daeb6563e6Eric ChristopherAddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, 63d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher unsigned &NumberedOp, 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<unsigned> &NamedOpIndices, 651620117f76b99560406ed90197173b72a9b8b66eChris Lattner std::string &Case, CodeGenTarget &Target) { 661620117f76b99560406ed90197173b72a9b8b66eChris Lattner CodeGenInstruction &CGI = Target.getInstruction(R); 671620117f76b99560406ed90197173b72a9b8b66eChris Lattner 688ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // Determine if VarName actually contributes to the Inst encoding. 698ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner int bit = BI->getNumBits()-1; 708ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 718ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // Scan for a bit that this contributed to. 728ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner for (; bit >= 0; ) { 738ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (getVariableBit(VarName, BI, bit) != -1) 748ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner break; 758ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 768ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner --bit; 778ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 788ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 798ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // If we found no bits, ignore this value, otherwise emit the call to get the 808ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // operand encoding. 818ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (bit < 0) return; 828ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 838ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // If the operand matches by name, reference according to that 848ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // operand number. Non-matching operands are assumed to be in 858ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // order. 868ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner unsigned OpIdx; 878ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) { 888ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // Get the machine operand number for the indicated operand. 898ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner OpIdx = CGI.Operands[OpIdx].MIOperandNo; 908ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) && 918ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner "Explicitly used operand also marked as not emitted!"); 928ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } else { 93f1bb42152a0375f2889bd7329eada2b6422c837eEvandro Menezes unsigned NumberOps = CGI.Operands.size(); 948ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner /// If this operand is not supposed to be emitted by the 958ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner /// generated emitter, skip it. 96f1bb42152a0375f2889bd7329eada2b6422c837eEvandro Menezes while (NumberedOp < NumberOps && 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) || 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (!NamedOpIndices.empty() && NamedOpIndices.count( 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.getSubOperandNumber(NumberedOp).first)))) { 1008ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner ++NumberedOp; 101f1adbfe4e23ce08d1afa1245f2515e863813a6acEvandro Menezes 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (NumberedOp >= CGI.Operands.back().MIOperandNo + 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.back().MINumOperands) { 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << "Too few operands in record " << R->getName() << 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines " (no match for variable " << VarName << "):\n"; 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << *R; 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << '\n'; 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1138ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner OpIdx = NumberedOp++; 1148ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 1158ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 1168ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx); 1178ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName; 1188ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 1198ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // If the source operand has a custom encoder, use it. This will 1208ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // get the encoding for all of the suboperands. 1218ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (!EncoderMethodName.empty()) { 1228ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // A custom encoder has all of the information for the 1238ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // sub-operands, if there are more than one, so only 1248ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // query the encoder once per source operand. 1258ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (SO.second == 0) { 1268ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += " // op: " + VarName + "\n" + 1278ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner " op = " + EncoderMethodName + "(MI, " + utostr(OpIdx); 12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Case += ", Fixups, STI"; 1298ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += ");\n"; 1308ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 1318ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } else { 1328ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += " // op: " + VarName + "\n" + 1338ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner " op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")"; 13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Case += ", Fixups, STI"; 1358ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += ");\n"; 1368ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 1378ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 1388ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner for (; bit >= 0; ) { 1391620117f76b99560406ed90197173b72a9b8b66eChris Lattner int varBit = getVariableBit(VarName, BI, bit); 1401620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1411620117f76b99560406ed90197173b72a9b8b66eChris Lattner // If this bit isn't from a variable, skip it. 1421620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (varBit == -1) { 1431620117f76b99560406ed90197173b72a9b8b66eChris Lattner --bit; 1441620117f76b99560406ed90197173b72a9b8b66eChris Lattner continue; 1451620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1461620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1479b8c3530cca906727f573234c783cdbf2499373fBob Wilson // Figure out the consecutive range of bits covered by this operand, in 1481620117f76b99560406ed90197173b72a9b8b66eChris Lattner // order to generate better encoding code. 1491620117f76b99560406ed90197173b72a9b8b66eChris Lattner int beginInstBit = bit; 1501620117f76b99560406ed90197173b72a9b8b66eChris Lattner int beginVarBit = varBit; 1511620117f76b99560406ed90197173b72a9b8b66eChris Lattner int N = 1; 1521620117f76b99560406ed90197173b72a9b8b66eChris Lattner for (--bit; bit >= 0;) { 1531620117f76b99560406ed90197173b72a9b8b66eChris Lattner varBit = getVariableBit(VarName, BI, bit); 1541620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (varBit == -1 || varBit != (beginVarBit - N)) break; 1551620117f76b99560406ed90197173b72a9b8b66eChris Lattner ++N; 1561620117f76b99560406ed90197173b72a9b8b66eChris Lattner --bit; 1571620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1588ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 15989d8139d3706270ec99b3722f273a34af61b4644NAKAMURA Takumi uint64_t opMask = ~(uint64_t)0 >> (64-N); 1601620117f76b99560406ed90197173b72a9b8b66eChris Lattner int opShift = beginVarBit - N + 1; 1611620117f76b99560406ed90197173b72a9b8b66eChris Lattner opMask <<= opShift; 1621620117f76b99560406ed90197173b72a9b8b66eChris Lattner opShift = beginInstBit - beginVarBit; 1631620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1641620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (opShift > 0) { 1654f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) << " + 1661620117f76b99560406ed90197173b72a9b8b66eChris Lattner itostr(opShift) + ";\n"; 1671620117f76b99560406ed90197173b72a9b8b66eChris Lattner } else if (opShift < 0) { 1684f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) >> " + 1691620117f76b99560406ed90197173b72a9b8b66eChris Lattner itostr(-opShift) + ";\n"; 1701620117f76b99560406ed90197173b72a9b8b66eChris Lattner } else { 1714f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson Case += " Value |= op & UINT64_C(" + utostr(opMask) + ");\n"; 1721620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1731620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1741620117f76b99560406ed90197173b72a9b8b66eChris Lattner} 1751620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1761620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1771620117f76b99560406ed90197173b72a9b8b66eChris Lattnerstd::string CodeEmitterGen::getInstructionCase(Record *R, 1781620117f76b99560406ed90197173b72a9b8b66eChris Lattner CodeGenTarget &Target) { 1791620117f76b99560406ed90197173b72a9b8b66eChris Lattner std::string Case; 1801620117f76b99560406ed90197173b72a9b8b66eChris Lattner 181d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher BitsInit *BI = R->getValueAsBitsInit("Inst"); 1821620117f76b99560406ed90197173b72a9b8b66eChris Lattner const std::vector<RecordVal> &Vals = R->getValues(); 1831620117f76b99560406ed90197173b72a9b8b66eChris Lattner unsigned NumberedOp = 0; 1841620117f76b99560406ed90197173b72a9b8b66eChris Lattner 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<unsigned> NamedOpIndices; 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect the set of operand indices that might correspond to named 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // operand, and skip these when assigning operands based on position. 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Target.getInstructionSet()-> 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getValueAsBit("noNamedPositionallyEncodedOperands")) { 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CodeGenInstruction &CGI = Target.getInstruction(R); 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned OpIdx; 19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx)) 19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NamedOpIndices.insert(OpIdx); 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2001620117f76b99560406ed90197173b72a9b8b66eChris Lattner // Loop over all of the fields in the instruction, determining which are the 2011620117f76b99560406ed90197173b72a9b8b66eChris Lattner // operands to the instruction. 2021620117f76b99560406ed90197173b72a9b8b66eChris Lattner for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 2031620117f76b99560406ed90197173b72a9b8b66eChris Lattner // Ignore fixed fields in the record, we're looking for values like: 2041620117f76b99560406ed90197173b72a9b8b66eChris Lattner // bits<5> RST = { ?, ?, ?, ?, ? }; 2051620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete()) 2061620117f76b99560406ed90197173b72a9b8b66eChris Lattner continue; 2071620117f76b99560406ed90197173b72a9b8b66eChris Lattner 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NamedOpIndices, Case, Target); 2101620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 2111620117f76b99560406ed90197173b72a9b8b66eChris Lattner 2121620117f76b99560406ed90197173b72a9b8b66eChris Lattner std::string PostEmitter = R->getValueAsString("PostEncoderMethod"); 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!PostEmitter.empty()) { 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Case += " Value = " + PostEmitter + "(MI, Value"; 21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Case += ", STI"; 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Case += ");\n"; 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 2181620117f76b99560406ed90197173b72a9b8b66eChris Lattner 2191620117f76b99560406ed90197173b72a9b8b66eChris Lattner return Case; 2201620117f76b99560406ed90197173b72a9b8b66eChris Lattner} 2211620117f76b99560406ed90197173b72a9b8b66eChris Lattner 2221a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid CodeEmitterGen::run(raw_ostream &o) { 22367db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 224048c00db1cd05bbbd616e0eff71756eebd45f6b4Chris Lattner std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 2258b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 226f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // For little-endian instruction bit encodings, reverse the bit order 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Target.reverseBitsForLittleEndianEncoding(); 2288b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 229de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ArrayRef<const CodeGenInstruction*> NumberedInstructions = 230f65027842e82027dd6e8020586a299aaa548e355Chris Lattner Target.getInstructionsByEnumValue(); 2319fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman 232ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman // Emit function declaration 2334f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << "uint64_t " << Target.getName(); 23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" 23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << " SmallVectorImpl<MCFixup> &Fixups,\n" 23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << " const MCSubtargetInfo &STI) const {\n"; 237ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman 238ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey // Emit instruction base values 23940530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson o << " static const uint64_t InstBits[] = {\n"; 240de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (const CodeGenInstruction *CGI : NumberedInstructions) { 241ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey Record *R = CGI->TheDef; 2428b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 243806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (R->getValueAsString("Namespace") == "TargetOpcode" || 244806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach R->getValueAsBit("isPseudo")) { 2454f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << " UINT64_C(0),\n"; 246ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey continue; 247ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey } 2488b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 249d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher BitsInit *BI = R->getValueAsBitsInit("Inst"); 2509fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman 2511620117f76b99560406ed90197173b72a9b8b66eChris Lattner // Start by filling in fixed values. 25240530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson uint64_t Value = 0; 253cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 2546cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (BitInit *B = dyn_cast<BitInit>(BI->getBit(e-i-1))) 25540530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson Value |= (uint64_t)B->getValue() << (e-i-1); 256cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman } 2574f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << " UINT64_C(" << Value << ")," << '\t' << "// " << R->getName() << "\n"; 258ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey } 2594f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << " UINT64_C(0)\n };\n"; 2608b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 261f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Map to accumulate all the cases. 262f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::map<std::string, std::vector<std::string> > CaseMap; 2638b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 264f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Construct all cases statement for each opcode 265f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end(); 266f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey IC != EC; ++IC) { 267f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Record *R = *IC; 268806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (R->getValueAsString("Namespace") == "TargetOpcode" || 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines R->getValueAsBit("isPseudo")) 27065766ce7df779ac0e7f6ee0171562b56769ae1ddJakob Stoklund Olesen continue; 2710ed92f2de3b424416b140eec3df9c9342848bfadJim Grosbach const std::string &InstName = R->getValueAsString("Namespace") + "::" 2720ed92f2de3b424416b140eec3df9c9342848bfadJim Grosbach + R->getName(); 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string Case = getInstructionCase(R, Target); 274336b8b42445920a3f59e42c61f2ccd9fbdfc497eOwen Anderson 2751620117f76b99560406ed90197173b72a9b8b66eChris Lattner CaseMap[Case].push_back(InstName); 276f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 2773da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 278f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Emit initial function code 279f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << " const unsigned opcode = MI.getOpcode();\n" 28040530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson << " uint64_t Value = InstBits[opcode];\n" 28140530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson << " uint64_t op = 0;\n" 2828e68c3873549ca31533e2e3e40dda3a43cb79566Jeffrey Yasskin << " (void)op; // suppress warning\n" 283f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey << " switch (opcode) {\n"; 2843da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 285f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Emit each case statement 286f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::map<std::string, std::vector<std::string> >::iterator IE, EE; 287f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) { 288f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey const std::string &Case = IE->first; 289f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::vector<std::string> &InstList = IE->second; 2903da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 291f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (int i = 0, N = InstList.size(); i < N; i++) { 292f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (i) o << "\n"; 2930ed92f2de3b424416b140eec3df9c9342848bfadJim Grosbach o << " case " << InstList[i] << ":"; 2949fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman } 295f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << " {\n"; 296f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << Case; 2979fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman o << " break;\n" 2989fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman << " }\n"; 2999fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman } 3007eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman 30128eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman // Default case: unhandled opcode 302cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman o << " default:\n" 303804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " std::string msg;\n" 304804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " raw_string_ostream Msg(msg);\n" 305804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " Msg << \"Not supported instr: \" << MI;\n" 30675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner << " report_fatal_error(Msg.str());\n" 307cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman << " }\n" 3089fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman << " return Value;\n" 30928eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman << "}\n\n"; 3109fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman} 3116f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3126f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 3136f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3146f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 3156f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) { 3176f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen emitSourceFileHeader("Machine Code Emitter", OS); 3186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeEmitterGen(RK).run(OS); 3196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 3206f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 322