CodeEmitterGen.cpp revision 224145
165543Scg//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// 2137573Sru// 365543Scg// The LLVM Compiler Infrastructure 465543Scg// 565543Scg// This file is distributed under the University of Illinois Open Source 665543Scg// License. See LICENSE.TXT for details. 765543Scg// 865543Scg//===----------------------------------------------------------------------===// 965543Scg// 1065543Scg// CodeEmitterGen uses the descriptions of instructions and their fields to 1165543Scg// construct an automated code emitter: a function that, given a MachineInstr, 1265543Scg// returns the (currently, 32-bit unsigned) value of the instruction. 1365543Scg// 1465543Scg//===----------------------------------------------------------------------===// 1565543Scg 1665543Scg#include "CodeEmitterGen.h" 1765543Scg#include "CodeGenTarget.h" 1865543Scg#include "Record.h" 1965543Scg#include "llvm/ADT/StringExtras.h" 2065543Scg#include "llvm/Support/CommandLine.h" 2165543Scg#include "llvm/Support/Debug.h" 2265543Scg#include <map> 2365543Scgusing namespace llvm; 2465543Scg 2565543Scg// FIXME: Somewhat hackish to use a command line option for this. There should 26137500Sjulian// be a CodeEmitter class in the Target.td that controls this sort of thing 2765543Scg// instead. 2865543Scgstatic cl::opt<bool> 2965543ScgMCEmitter("mc-emitter", 3065543Scg cl::desc("Generate CodeEmitter for use with the MC library."), 3165543Scg cl::init(false)); 3265543Scg 3365543Scgvoid CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) { 3465543Scg for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end(); 3565543Scg I != E; ++I) { 3665543Scg Record *R = *I; 3765543Scg if (R->getValueAsString("Namespace") == "TargetOpcode" || 38119853Scg R->getValueAsBit("isPseudo")) 3965543Scg continue; 4065543Scg 4165543Scg BitsInit *BI = R->getValueAsBitsInit("Inst"); 4265543Scg 4365543Scg unsigned numBits = BI->getNumBits(); 4465543Scg BitsInit *NewBI = new BitsInit(numBits); 45137500Sjulian for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) { 46137500Sjulian unsigned bitSwapIdx = numBits - bit - 1; 47137500Sjulian Init *OrigBit = BI->getBit(bit); 4865543Scg Init *BitSwap = BI->getBit(bitSwapIdx); 4965543Scg NewBI->setBit(bit, BitSwap); 5065543Scg NewBI->setBit(bitSwapIdx, OrigBit); 5165543Scg } 52119287Simp if (numBits % 2) { 53119287Simp unsigned middle = (numBits + 1) / 2; 5465543Scg NewBI->setBit(middle, BI->getBit(middle)); 5565543Scg } 5665543Scg 5782180Scg // Update the bits in reversed order so that emitInstrOpBits will get the 5882180Scg // correct endianness. 59137500Sjulian R->getValue("Inst")->setValue(NewBI); 6065543Scg } 6165543Scg} 6265543Scg 6365543Scg// If the VarBitInit at position 'bit' matches the specified variable then 6465543Scg// return the variable bit position. Otherwise return -1. 6565543Scgint CodeEmitterGen::getVariableBit(const std::string &VarName, 6665543Scg BitsInit *BI, int bit) { 6765543Scg if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(BI->getBit(bit))) { 6865543Scg if (VarInit *VI = dynamic_cast<VarInit*>(VBI->getVariable())) 6965543Scg if (VI->getName() == VarName) 7065543Scg return VBI->getBitNum(); 7165543Scg } else if (VarInit *VI = dynamic_cast<VarInit*>(BI->getBit(bit))) { 7265543Scg if (VI->getName() == VarName) 7365543Scg return 0; 7465543Scg } 7565543Scg 7665543Scg return -1; 77137500Sjulian} 78137500Sjulian 79137500Sjulianvoid CodeEmitterGen:: 80137500SjulianAddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, 81137500Sjulian unsigned &NumberedOp, 82137500Sjulian std::string &Case, CodeGenTarget &Target) { 8365543Scg CodeGenInstruction &CGI = Target.getInstruction(R); 8465543Scg 8565543Scg // Determine if VarName actually contributes to the Inst encoding. 8684658Scg int bit = BI->getNumBits()-1; 8765543Scg 8865543Scg // Scan for a bit that this contributed to. 89137500Sjulian for (; bit >= 0; ) { 90137500Sjulian if (getVariableBit(VarName, BI, bit) != -1) 91137500Sjulian break; 92137500Sjulian 93137500Sjulian --bit; 94137500Sjulian } 95137500Sjulian 96137500Sjulian // If we found no bits, ignore this value, otherwise emit the call to get the 97137500Sjulian // operand encoding. 98137500Sjulian if (bit < 0) return; 99137500Sjulian 10065543Scg // If the operand matches by name, reference according to that 10165543Scg // operand number. Non-matching operands are assumed to be in 10265543Scg // order. 10365543Scg unsigned OpIdx; 104137500Sjulian if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) { 10565543Scg // Get the machine operand number for the indicated operand. 106137500Sjulian OpIdx = CGI.Operands[OpIdx].MIOperandNo; 107137500Sjulian assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) && 10874763Scg "Explicitly used operand also marked as not emitted!"); 10974763Scg } else { 110137500Sjulian /// If this operand is not supposed to be emitted by the 111137500Sjulian /// generated emitter, skip it. 112137500Sjulian while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp)) 113137500Sjulian ++NumberedOp; 114137500Sjulian OpIdx = NumberedOp++; 115137500Sjulian } 11670291Scg 117137500Sjulian std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx); 118137500Sjulian std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName; 119137500Sjulian 120137500Sjulian // If the source operand has a custom encoder, use it. This will 12165543Scg // get the encoding for all of the suboperands. 12265543Scg if (!EncoderMethodName.empty()) { 123137500Sjulian // A custom encoder has all of the information for the 124137500Sjulian // sub-operands, if there are more than one, so only 125137500Sjulian // query the encoder once per source operand. 126137500Sjulian if (SO.second == 0) { 127137500Sjulian Case += " // op: " + VarName + "\n" + 128137500Sjulian " op = " + EncoderMethodName + "(MI, " + utostr(OpIdx); 129137500Sjulian if (MCEmitter) 130137500Sjulian Case += ", Fixups"; 131137500Sjulian Case += ");\n"; 132137500Sjulian } 133137500Sjulian } else { 134137500Sjulian Case += " // op: " + VarName + "\n" + 135137500Sjulian " op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")"; 136137500Sjulian if (MCEmitter) 137137500Sjulian Case += ", Fixups"; 138137500Sjulian Case += ");\n"; 139137500Sjulian } 140137500Sjulian 141137500Sjulian for (; bit >= 0; ) { 142137500Sjulian int varBit = getVariableBit(VarName, BI, bit); 143137500Sjulian 144137500Sjulian // If this bit isn't from a variable, skip it. 14565543Scg if (varBit == -1) { 146137500Sjulian --bit; 14765543Scg continue; 148137500Sjulian } 149137500Sjulian 15065543Scg // Figure out the consecutive range of bits covered by this operand, in 15165543Scg // order to generate better encoding code. 15265543Scg int beginInstBit = bit; 15365543Scg int beginVarBit = varBit; 15465543Scg int N = 1; 15565543Scg for (--bit; bit >= 0;) { 15665543Scg varBit = getVariableBit(VarName, BI, bit); 15765543Scg if (varBit == -1 || varBit != (beginVarBit - N)) break; 15865543Scg ++N; 159137500Sjulian --bit; 160137500Sjulian } 16165543Scg 162137500Sjulian unsigned opMask = ~0U >> (32-N); 163137500Sjulian int opShift = beginVarBit - N + 1; 164137500Sjulian opMask <<= opShift; 165137500Sjulian opShift = beginInstBit - beginVarBit; 166137500Sjulian 16765543Scg if (opShift > 0) { 16865543Scg Case += " Value |= (op & " + utostr(opMask) + "U) << " + 169137500Sjulian itostr(opShift) + ";\n"; 170137500Sjulian } else if (opShift < 0) { 171137500Sjulian Case += " Value |= (op & " + utostr(opMask) + "U) >> " + 172137500Sjulian itostr(-opShift) + ";\n"; 173137500Sjulian } else { 174137500Sjulian Case += " Value |= op & " + utostr(opMask) + "U;\n"; 17565543Scg } 176137500Sjulian } 177137500Sjulian} 17865543Scg 17965543Scg 180137500Sjulianstd::string CodeEmitterGen::getInstructionCase(Record *R, 181137500Sjulian CodeGenTarget &Target) { 182137500Sjulian std::string Case; 183137500Sjulian 184137500Sjulian BitsInit *BI = R->getValueAsBitsInit("Inst"); 185137500Sjulian const std::vector<RecordVal> &Vals = R->getValues(); 186137500Sjulian unsigned NumberedOp = 0; 187137500Sjulian 188137500Sjulian // Loop over all of the fields in the instruction, determining which are the 189137500Sjulian // operands to the instruction. 190137500Sjulian for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 191137500Sjulian // Ignore fixed fields in the record, we're looking for values like: 192137500Sjulian // bits<5> RST = { ?, ?, ?, ?, ? }; 193137500Sjulian if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete()) 194137500Sjulian continue; 195137500Sjulian 196137500Sjulian AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, Case, Target); 197137500Sjulian } 198137500Sjulian 199137500Sjulian std::string PostEmitter = R->getValueAsString("PostEncoderMethod"); 200137500Sjulian if (!PostEmitter.empty()) 201137500Sjulian Case += " Value = " + PostEmitter + "(MI, Value);\n"; 202137500Sjulian 203137500Sjulian return Case; 204137500Sjulian} 205137500Sjulian 206137500Sjulianvoid CodeEmitterGen::run(raw_ostream &o) { 207137500Sjulian CodeGenTarget Target(Records); 208137500Sjulian std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 209137500Sjulian 210137500Sjulian // For little-endian instruction bit encodings, reverse the bit order 211137500Sjulian if (Target.isLittleEndianEncoding()) reverseBits(Insts); 212137500Sjulian 213137500Sjulian EmitSourceFileHeader("Machine Code Emitter", o); 214137500Sjulian 21565543Scg const std::vector<const CodeGenInstruction*> &NumberedInstructions = 21665543Scg Target.getInstructionsByEnumValue(); 21765543Scg 21865543Scg // Emit function declaration 219137500Sjulian o << "unsigned " << Target.getName(); 220137500Sjulian if (MCEmitter) 22165543Scg o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" 22265543Scg << " SmallVectorImpl<MCFixup> &Fixups) const {\n"; 22365543Scg else 22465543Scg o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n"; 22565543Scg 22665543Scg // Emit instruction base values 22765543Scg o << " static const unsigned InstBits[] = {\n"; 22865543Scg for (std::vector<const CodeGenInstruction*>::const_iterator 22965543Scg IN = NumberedInstructions.begin(), 230137500Sjulian EN = NumberedInstructions.end(); 23165543Scg IN != EN; ++IN) { 232137500Sjulian const CodeGenInstruction *CGI = *IN; 23365543Scg Record *R = CGI->TheDef; 234137500Sjulian 23565543Scg if (R->getValueAsString("Namespace") == "TargetOpcode" || 23665543Scg R->getValueAsBit("isPseudo")) { 23765543Scg o << " 0U,\n"; 238137500Sjulian continue; 239137500Sjulian } 240137500Sjulian 241137500Sjulian BitsInit *BI = R->getValueAsBitsInit("Inst"); 24265543Scg 24365543Scg // Start by filling in fixed values. 244137500Sjulian unsigned Value = 0; 24565543Scg for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 24665543Scg if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) 24765543Scg Value |= B->getValue() << (e-i-1); 24865543Scg } 24965543Scg o << " " << Value << "U," << '\t' << "// " << R->getName() << "\n"; 25065543Scg } 25165543Scg o << " 0U\n };\n"; 25265543Scg 25365543Scg // Map to accumulate all the cases. 25465543Scg std::map<std::string, std::vector<std::string> > CaseMap; 25565543Scg 256137500Sjulian // Construct all cases statement for each opcode 257137500Sjulian for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end(); 25865543Scg IC != EC; ++IC) { 259137500Sjulian Record *R = *IC; 26065543Scg if (R->getValueAsString("Namespace") == "TargetOpcode" || 26165543Scg R->getValueAsBit("isPseudo")) 26265543Scg continue; 26365543Scg const std::string &InstName = R->getValueAsString("Namespace") + "::" 264137500Sjulian + R->getName(); 26565543Scg std::string Case = getInstructionCase(R, Target); 266137500Sjulian 267137500Sjulian CaseMap[Case].push_back(InstName); 268137500Sjulian } 269137500Sjulian 270137500Sjulian // Emit initial function code 271137500Sjulian o << " const unsigned opcode = MI.getOpcode();\n" 272137500Sjulian << " unsigned Value = InstBits[opcode];\n" 273137500Sjulian << " unsigned op = 0;\n" 274137500Sjulian << " (void)op; // suppress warning\n" 275137500Sjulian << " switch (opcode) {\n"; 276137500Sjulian 277137500Sjulian // Emit each case statement 278137500Sjulian std::map<std::string, std::vector<std::string> >::iterator IE, EE; 279137500Sjulian for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) { 280137500Sjulian const std::string &Case = IE->first; 281137500Sjulian std::vector<std::string> &InstList = IE->second; 282137500Sjulian 283137500Sjulian for (int i = 0, N = InstList.size(); i < N; i++) { 284137500Sjulian if (i) o << "\n"; 285137500Sjulian o << " case " << InstList[i] << ":"; 286137500Sjulian } 287137500Sjulian o << " {\n"; 288137500Sjulian o << Case; 289137500Sjulian o << " break;\n" 290137500Sjulian << " }\n"; 291137500Sjulian } 292137500Sjulian 293137500Sjulian // Default case: unhandled opcode 294137500Sjulian o << " default:\n" 295137500Sjulian << " std::string msg;\n" 296137500Sjulian << " raw_string_ostream Msg(msg);\n" 297137500Sjulian << " Msg << \"Not supported instr: \" << MI;\n" 298137500Sjulian << " report_fatal_error(Msg.str());\n" 299137500Sjulian << " }\n" 300137500Sjulian << " return Value;\n" 301137500Sjulian << "}\n\n"; 302137500Sjulian} 303137500Sjulian