CodeEmitterGen.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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" 18ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach#include "llvm/Support/CommandLine.h" 19551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h" 204ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Record.h" 216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 22eac8f35da8935cb5e5d6f6f0f02d0648fd8f130bBill Wendling#include <map> 236f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <string> 246f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <vector> 252082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm; 26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 2760aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim Grosbach// FIXME: Somewhat hackish to use a command line option for this. There should 2860aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim Grosbach// be a CodeEmitter class in the Target.td that controls this sort of thing 2960aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim Grosbach// instead. 30ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbachstatic cl::opt<bool> 3160aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim GrosbachMCEmitter("mc-emitter", 32ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach cl::desc("Generate CodeEmitter for use with the MC library."), 33ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach cl::init(false)); 34ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach 356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass CodeEmitterGen { 386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen RecordKeeper &Records; 396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeEmitterGen(RecordKeeper &R) : Records(R) {} 416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void run(raw_ostream &o); 436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate: 446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen int getVariableBit(const std::string &VarName, BitsInit *BI, int bit); 456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string getInstructionCase(Record *R, CodeGenTarget &Target); 466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void AddCodeToMergeInOperand(Record *R, BitsInit *BI, 476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen const std::string &VarName, 486f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned &NumberedOp, 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<unsigned> &NamedOpIndices, 506f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string &Case, CodeGenTarget &Target); 516f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 526f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 536f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 54cb129031479dfb5583cce6d77fcbb0b68098693aJim Laskey// If the VarBitInit at position 'bit' matches the specified variable then 55cb129031479dfb5583cce6d77fcbb0b68098693aJim Laskey// return the variable bit position. Otherwise return -1. 569b03da6824372f3b6cb961ecf88de949cb10b450Dan Gohmanint CodeEmitterGen::getVariableBit(const std::string &VarName, 57d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher BitsInit *BI, int bit) { 586cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (VarBitInit *VBI = dyn_cast<VarBitInit>(BI->getBit(bit))) { 596cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (VarInit *VI = dyn_cast<VarInit>(VBI->getBitVar())) 6098e969ae20352c0255edf25def392577de61e693Chris Lattner if (VI->getName() == VarName) 6198e969ae20352c0255edf25def392577de61e693Chris Lattner return VBI->getBitNum(); 626cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva } else if (VarInit *VI = dyn_cast<VarInit>(BI->getBit(bit))) { 634cdcb4772d95b9e801a0f3cd43776cef3af3b530Owen Anderson if (VI->getName() == VarName) 644cdcb4772d95b9e801a0f3cd43776cef3af3b530Owen Anderson return 0; 654cdcb4772d95b9e801a0f3cd43776cef3af3b530Owen Anderson } 668b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 67f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey return -1; 688b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach} 69f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey 701620117f76b99560406ed90197173b72a9b8b66eChris Lattnervoid CodeEmitterGen:: 71d568b3f55294917d1cc701da14a8a7daeb6563e6Eric ChristopherAddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, 72d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher unsigned &NumberedOp, 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<unsigned> &NamedOpIndices, 741620117f76b99560406ed90197173b72a9b8b66eChris Lattner std::string &Case, CodeGenTarget &Target) { 751620117f76b99560406ed90197173b72a9b8b66eChris Lattner CodeGenInstruction &CGI = Target.getInstruction(R); 761620117f76b99560406ed90197173b72a9b8b66eChris Lattner 778ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // Determine if VarName actually contributes to the Inst encoding. 788ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner int bit = BI->getNumBits()-1; 798ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 808ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // Scan for a bit that this contributed to. 818ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner for (; bit >= 0; ) { 828ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (getVariableBit(VarName, BI, bit) != -1) 838ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner break; 848ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 858ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner --bit; 868ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 878ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 888ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // If we found no bits, ignore this value, otherwise emit the call to get the 898ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // operand encoding. 908ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (bit < 0) return; 918ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 928ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // If the operand matches by name, reference according to that 938ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // operand number. Non-matching operands are assumed to be in 948ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // order. 958ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner unsigned OpIdx; 968ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) { 978ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // Get the machine operand number for the indicated operand. 988ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner OpIdx = CGI.Operands[OpIdx].MIOperandNo; 998ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) && 1008ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner "Explicitly used operand also marked as not emitted!"); 1018ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } else { 102f1bb42152a0375f2889bd7329eada2b6422c837eEvandro Menezes unsigned NumberOps = CGI.Operands.size(); 1038ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner /// If this operand is not supposed to be emitted by the 1048ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner /// generated emitter, skip it. 105f1bb42152a0375f2889bd7329eada2b6422c837eEvandro Menezes while (NumberedOp < NumberOps && 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) || 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (NamedOpIndices.size() && NamedOpIndices.count( 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.getSubOperandNumber(NumberedOp).first)))) { 1098ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner ++NumberedOp; 110f1adbfe4e23ce08d1afa1245f2515e863813a6acEvandro Menezes 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (NumberedOp >= CGI.Operands.back().MIOperandNo + 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.back().MINumOperands) { 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << "Too few operands in record " << R->getName() << 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines " (no match for variable " << VarName << "):\n"; 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << *R; 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << '\n'; 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1228ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner OpIdx = NumberedOp++; 1238ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 1248ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 1258ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx); 1268ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName; 1278ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 1288ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // If the source operand has a custom encoder, use it. This will 1298ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // get the encoding for all of the suboperands. 1308ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (!EncoderMethodName.empty()) { 1318ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // A custom encoder has all of the information for the 1328ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // sub-operands, if there are more than one, so only 1338ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner // query the encoder once per source operand. 1348ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (SO.second == 0) { 1358ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += " // op: " + VarName + "\n" + 1368ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner " op = " + EncoderMethodName + "(MI, " + utostr(OpIdx); 1378ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (MCEmitter) 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Case += ", Fixups, STI"; 1398ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += ");\n"; 1408ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 1418ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } else { 1428ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += " // op: " + VarName + "\n" + 1438ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner " op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")"; 1448ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner if (MCEmitter) 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Case += ", Fixups, STI"; 1468ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner Case += ");\n"; 1478ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner } 1488ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 1498ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner for (; bit >= 0; ) { 1501620117f76b99560406ed90197173b72a9b8b66eChris Lattner int varBit = getVariableBit(VarName, BI, bit); 1511620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1521620117f76b99560406ed90197173b72a9b8b66eChris Lattner // If this bit isn't from a variable, skip it. 1531620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (varBit == -1) { 1541620117f76b99560406ed90197173b72a9b8b66eChris Lattner --bit; 1551620117f76b99560406ed90197173b72a9b8b66eChris Lattner continue; 1561620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1571620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1589b8c3530cca906727f573234c783cdbf2499373fBob Wilson // Figure out the consecutive range of bits covered by this operand, in 1591620117f76b99560406ed90197173b72a9b8b66eChris Lattner // order to generate better encoding code. 1601620117f76b99560406ed90197173b72a9b8b66eChris Lattner int beginInstBit = bit; 1611620117f76b99560406ed90197173b72a9b8b66eChris Lattner int beginVarBit = varBit; 1621620117f76b99560406ed90197173b72a9b8b66eChris Lattner int N = 1; 1631620117f76b99560406ed90197173b72a9b8b66eChris Lattner for (--bit; bit >= 0;) { 1641620117f76b99560406ed90197173b72a9b8b66eChris Lattner varBit = getVariableBit(VarName, BI, bit); 1651620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (varBit == -1 || varBit != (beginVarBit - N)) break; 1661620117f76b99560406ed90197173b72a9b8b66eChris Lattner ++N; 1671620117f76b99560406ed90197173b72a9b8b66eChris Lattner --bit; 1681620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1698ae082bf19a746324b7c6c781831b926e28afcf0Chris Lattner 17089d8139d3706270ec99b3722f273a34af61b4644NAKAMURA Takumi uint64_t opMask = ~(uint64_t)0 >> (64-N); 1711620117f76b99560406ed90197173b72a9b8b66eChris Lattner int opShift = beginVarBit - N + 1; 1721620117f76b99560406ed90197173b72a9b8b66eChris Lattner opMask <<= opShift; 1731620117f76b99560406ed90197173b72a9b8b66eChris Lattner opShift = beginInstBit - beginVarBit; 1741620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1751620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (opShift > 0) { 1764f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) << " + 1771620117f76b99560406ed90197173b72a9b8b66eChris Lattner itostr(opShift) + ";\n"; 1781620117f76b99560406ed90197173b72a9b8b66eChris Lattner } else if (opShift < 0) { 1794f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) >> " + 1801620117f76b99560406ed90197173b72a9b8b66eChris Lattner itostr(-opShift) + ";\n"; 1811620117f76b99560406ed90197173b72a9b8b66eChris Lattner } else { 1824f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson Case += " Value |= op & UINT64_C(" + utostr(opMask) + ");\n"; 1831620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1841620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 1851620117f76b99560406ed90197173b72a9b8b66eChris Lattner} 1861620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1871620117f76b99560406ed90197173b72a9b8b66eChris Lattner 1881620117f76b99560406ed90197173b72a9b8b66eChris Lattnerstd::string CodeEmitterGen::getInstructionCase(Record *R, 1891620117f76b99560406ed90197173b72a9b8b66eChris Lattner CodeGenTarget &Target) { 1901620117f76b99560406ed90197173b72a9b8b66eChris Lattner std::string Case; 1911620117f76b99560406ed90197173b72a9b8b66eChris Lattner 192d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher BitsInit *BI = R->getValueAsBitsInit("Inst"); 1931620117f76b99560406ed90197173b72a9b8b66eChris Lattner const std::vector<RecordVal> &Vals = R->getValues(); 1941620117f76b99560406ed90197173b72a9b8b66eChris Lattner unsigned NumberedOp = 0; 1951620117f76b99560406ed90197173b72a9b8b66eChris Lattner 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<unsigned> NamedOpIndices; 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect the set of operand indices that might correspond to named 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // operand, and skip these when assigning operands based on position. 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Target.getInstructionSet()-> 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getValueAsBit("noNamedPositionallyEncodedOperands")) { 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CodeGenInstruction &CGI = Target.getInstruction(R); 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned OpIdx; 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx)) 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NamedOpIndices.insert(OpIdx); 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2111620117f76b99560406ed90197173b72a9b8b66eChris Lattner // Loop over all of the fields in the instruction, determining which are the 2121620117f76b99560406ed90197173b72a9b8b66eChris Lattner // operands to the instruction. 2131620117f76b99560406ed90197173b72a9b8b66eChris Lattner for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 2141620117f76b99560406ed90197173b72a9b8b66eChris Lattner // Ignore fixed fields in the record, we're looking for values like: 2151620117f76b99560406ed90197173b72a9b8b66eChris Lattner // bits<5> RST = { ?, ?, ?, ?, ? }; 2161620117f76b99560406ed90197173b72a9b8b66eChris Lattner if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete()) 2171620117f76b99560406ed90197173b72a9b8b66eChris Lattner continue; 2181620117f76b99560406ed90197173b72a9b8b66eChris Lattner 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NamedOpIndices, Case, Target); 2211620117f76b99560406ed90197173b72a9b8b66eChris Lattner } 2221620117f76b99560406ed90197173b72a9b8b66eChris Lattner 2231620117f76b99560406ed90197173b72a9b8b66eChris Lattner std::string PostEmitter = R->getValueAsString("PostEncoderMethod"); 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!PostEmitter.empty()) { 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Case += " Value = " + PostEmitter + "(MI, Value"; 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MCEmitter) 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Case += ", STI"; 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Case += ");\n"; 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 2301620117f76b99560406ed90197173b72a9b8b66eChris Lattner 2311620117f76b99560406ed90197173b72a9b8b66eChris Lattner return Case; 2321620117f76b99560406ed90197173b72a9b8b66eChris Lattner} 2331620117f76b99560406ed90197173b72a9b8b66eChris Lattner 2341a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid CodeEmitterGen::run(raw_ostream &o) { 23567db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 236048c00db1cd05bbbd616e0eff71756eebd45f6b4Chris Lattner std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 2378b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 238f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // For little-endian instruction bit encodings, reverse the bit order 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Target.reverseBitsForLittleEndianEncoding(); 2408b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 241f65027842e82027dd6e8020586a299aaa548e355Chris Lattner const std::vector<const CodeGenInstruction*> &NumberedInstructions = 242f65027842e82027dd6e8020586a299aaa548e355Chris Lattner Target.getInstructionsByEnumValue(); 2439fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman 244ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman // Emit function declaration 2454f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << "uint64_t " << Target.getName(); 24660aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim Grosbach if (MCEmitter) 24760aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim Grosbach o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " SmallVectorImpl<MCFixup> &Fixups,\n" 24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " const MCSubtargetInfo &STI) const {\n"; 25060aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim Grosbach else 25160aaa761963e1967dfb21d69d0b4a6a0c9f39c57Jim Grosbach o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n"; 252ad346ad17058d9e1463ab1fe5bfa78444e5d3e9cMisha Brukman 253ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey // Emit instruction base values 25440530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson o << " static const uint64_t InstBits[] = {\n"; 255f65027842e82027dd6e8020586a299aaa548e355Chris Lattner for (std::vector<const CodeGenInstruction*>::const_iterator 256ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey IN = NumberedInstructions.begin(), 257ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey EN = NumberedInstructions.end(); 258ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey IN != EN; ++IN) { 259ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey const CodeGenInstruction *CGI = *IN; 260ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey Record *R = CGI->TheDef; 2618b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 262806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (R->getValueAsString("Namespace") == "TargetOpcode" || 263806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach R->getValueAsBit("isPseudo")) { 2644f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << " UINT64_C(0),\n"; 265ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey continue; 266ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey } 2678b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 268d568b3f55294917d1cc701da14a8a7daeb6563e6Eric Christopher BitsInit *BI = R->getValueAsBitsInit("Inst"); 2699fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman 2701620117f76b99560406ed90197173b72a9b8b66eChris Lattner // Start by filling in fixed values. 27140530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson uint64_t Value = 0; 272cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 2736cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (BitInit *B = dyn_cast<BitInit>(BI->getBit(e-i-1))) 27440530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson Value |= (uint64_t)B->getValue() << (e-i-1); 275cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman } 2764f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << " UINT64_C(" << Value << ")," << '\t' << "// " << R->getName() << "\n"; 277ed393433d2fd0d680ac5c18ad78e6ebe9afda034Jim Laskey } 2784f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson o << " UINT64_C(0)\n };\n"; 2798b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 280f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Map to accumulate all the cases. 281f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::map<std::string, std::vector<std::string> > CaseMap; 2828b892ae3d6a23c2370ef64f6d4fe0a6abed94d39Jim Grosbach 283f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Construct all cases statement for each opcode 284f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end(); 285f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey IC != EC; ++IC) { 286f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey Record *R = *IC; 287806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (R->getValueAsString("Namespace") == "TargetOpcode" || 28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines R->getValueAsBit("isPseudo")) 28965766ce7df779ac0e7f6ee0171562b56769ae1ddJakob Stoklund Olesen continue; 2900ed92f2de3b424416b140eec3df9c9342848bfadJim Grosbach const std::string &InstName = R->getValueAsString("Namespace") + "::" 2910ed92f2de3b424416b140eec3df9c9342848bfadJim Grosbach + R->getName(); 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string Case = getInstructionCase(R, Target); 293336b8b42445920a3f59e42c61f2ccd9fbdfc497eOwen Anderson 2941620117f76b99560406ed90197173b72a9b8b66eChris Lattner CaseMap[Case].push_back(InstName); 295f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey } 2963da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 297f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Emit initial function code 298f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << " const unsigned opcode = MI.getOpcode();\n" 29940530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson << " uint64_t Value = InstBits[opcode];\n" 30040530ad3a8384e597b7a80d04c2ab80ac0232e0cOwen Anderson << " uint64_t op = 0;\n" 3018e68c3873549ca31533e2e3e40dda3a43cb79566Jeffrey Yasskin << " (void)op; // suppress warning\n" 302f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey << " switch (opcode) {\n"; 3033da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 304f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey // Emit each case statement 305f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::map<std::string, std::vector<std::string> >::iterator IE, EE; 306f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) { 307f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey const std::string &Case = IE->first; 308f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey std::vector<std::string> &InstList = IE->second; 3093da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 310f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey for (int i = 0, N = InstList.size(); i < N; i++) { 311f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey if (i) o << "\n"; 3120ed92f2de3b424416b140eec3df9c9342848bfadJim Grosbach o << " case " << InstList[i] << ":"; 3139fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman } 314f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << " {\n"; 315f1b05bf755c3a083944f03fbf6a83892bc051065Jim Laskey o << Case; 3169fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman o << " break;\n" 3179fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman << " }\n"; 3189fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman } 3197eac4766b156ad2965125a7ee3f1f4834dfbb00bMisha Brukman 32028eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman // Default case: unhandled opcode 321cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman o << " default:\n" 322804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " std::string msg;\n" 323804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " raw_string_ostream Msg(msg);\n" 324804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin << " Msg << \"Not supported instr: \" << MI;\n" 32575361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner << " report_fatal_error(Msg.str());\n" 326cbfde0a6128bd7049433e03bba69911d55288fb1Misha Brukman << " }\n" 3279fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman << " return Value;\n" 32828eefa5464ca6415fcee577d5c47f739535d7e6cMisha Brukman << "}\n\n"; 3299fff7e194a2d8aa3abe92efa506b1fbe83583f53Misha Brukman} 3306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 3326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 3346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) { 3366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen emitSourceFileHeader("Machine Code Emitter", OS); 3376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeEmitterGen(RK).run(OS); 3386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 3396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 3406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 341