CodeEmitterGen.cpp revision 221345
1193323Sed//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// CodeEmitterGen uses the descriptions of instructions and their fields to
11193323Sed// construct an automated code emitter: a function that, given a MachineInstr,
12193323Sed// returns the (currently, 32-bit unsigned) value of the instruction.
13193323Sed//
14193323Sed//===----------------------------------------------------------------------===//
15193323Sed
16193323Sed#include "CodeEmitterGen.h"
17193323Sed#include "CodeGenTarget.h"
18193323Sed#include "Record.h"
19193323Sed#include "llvm/ADT/StringExtras.h"
20218893Sdim#include "llvm/Support/CommandLine.h"
21193323Sed#include "llvm/Support/Debug.h"
22218893Sdim#include <map>
23193323Sedusing namespace llvm;
24193323Sed
25218893Sdim// FIXME: Somewhat hackish to use a command line option for this. There should
26218893Sdim// be a CodeEmitter class in the Target.td that controls this sort of thing
27218893Sdim// instead.
28218893Sdimstatic cl::opt<bool>
29218893SdimMCEmitter("mc-emitter",
30218893Sdim          cl::desc("Generate CodeEmitter for use with the MC library."),
31218893Sdim          cl::init(false));
32218893Sdim
33193323Sedvoid CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
34193323Sed  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
35193323Sed       I != E; ++I) {
36193323Sed    Record *R = *I;
37210299Sed    if (R->getValueAsString("Namespace") == "TargetOpcode")
38210299Sed      continue;
39193323Sed
40193323Sed    BitsInit *BI = R->getValueAsBitsInit("Inst");
41193323Sed
42193323Sed    unsigned numBits = BI->getNumBits();
43193323Sed    BitsInit *NewBI = new BitsInit(numBits);
44193323Sed    for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
45193323Sed      unsigned bitSwapIdx = numBits - bit - 1;
46193323Sed      Init *OrigBit = BI->getBit(bit);
47193323Sed      Init *BitSwap = BI->getBit(bitSwapIdx);
48193323Sed      NewBI->setBit(bit, BitSwap);
49193323Sed      NewBI->setBit(bitSwapIdx, OrigBit);
50193323Sed    }
51193323Sed    if (numBits % 2) {
52193323Sed      unsigned middle = (numBits + 1) / 2;
53193323Sed      NewBI->setBit(middle, BI->getBit(middle));
54193323Sed    }
55218893Sdim
56193323Sed    // Update the bits in reversed order so that emitInstrOpBits will get the
57193323Sed    // correct endianness.
58193323Sed    R->getValue("Inst")->setValue(NewBI);
59193323Sed  }
60193323Sed}
61193323Sed
62193323Sed// If the VarBitInit at position 'bit' matches the specified variable then
63193323Sed// return the variable bit position.  Otherwise return -1.
64201360Srdivackyint CodeEmitterGen::getVariableBit(const std::string &VarName,
65218893Sdim                                   BitsInit *BI, int bit) {
66221345Sdim  if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(BI->getBit(bit))) {
67218893Sdim    if (VarInit *VI = dynamic_cast<VarInit*>(VBI->getVariable()))
68218893Sdim      if (VI->getName() == VarName)
69218893Sdim        return VBI->getBitNum();
70221345Sdim  } else if (VarInit *VI = dynamic_cast<VarInit*>(BI->getBit(bit))) {
71221345Sdim    if (VI->getName() == VarName)
72221345Sdim      return 0;
73221345Sdim  }
74218893Sdim
75218893Sdim  return -1;
76218893Sdim}
77218893Sdim
78218893Sdimvoid CodeEmitterGen::
79218893SdimAddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
80218893Sdim                        unsigned &NumberedOp,
81218893Sdim                        std::string &Case, CodeGenTarget &Target) {
82218893Sdim  CodeGenInstruction &CGI = Target.getInstruction(R);
83218893Sdim
84218893Sdim  // Determine if VarName actually contributes to the Inst encoding.
85218893Sdim  int bit = BI->getNumBits()-1;
86218893Sdim
87218893Sdim  // Scan for a bit that this contributed to.
88218893Sdim  for (; bit >= 0; ) {
89218893Sdim    if (getVariableBit(VarName, BI, bit) != -1)
90218893Sdim      break;
91201360Srdivacky
92218893Sdim    --bit;
93218893Sdim  }
94218893Sdim
95218893Sdim  // If we found no bits, ignore this value, otherwise emit the call to get the
96218893Sdim  // operand encoding.
97218893Sdim  if (bit < 0) return;
98218893Sdim
99218893Sdim  // If the operand matches by name, reference according to that
100218893Sdim  // operand number. Non-matching operands are assumed to be in
101218893Sdim  // order.
102218893Sdim  unsigned OpIdx;
103218893Sdim  if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
104218893Sdim    // Get the machine operand number for the indicated operand.
105218893Sdim    OpIdx = CGI.Operands[OpIdx].MIOperandNo;
106218893Sdim    assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
107218893Sdim           "Explicitly used operand also marked as not emitted!");
108218893Sdim  } else {
109218893Sdim    /// If this operand is not supposed to be emitted by the
110218893Sdim    /// generated emitter, skip it.
111218893Sdim    while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
112218893Sdim      ++NumberedOp;
113218893Sdim    OpIdx = NumberedOp++;
114218893Sdim  }
115218893Sdim
116218893Sdim  std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx);
117218893Sdim  std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName;
118218893Sdim
119218893Sdim  // If the source operand has a custom encoder, use it. This will
120218893Sdim  // get the encoding for all of the suboperands.
121218893Sdim  if (!EncoderMethodName.empty()) {
122218893Sdim    // A custom encoder has all of the information for the
123218893Sdim    // sub-operands, if there are more than one, so only
124218893Sdim    // query the encoder once per source operand.
125218893Sdim    if (SO.second == 0) {
126218893Sdim      Case += "      // op: " + VarName + "\n" +
127218893Sdim              "      op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
128218893Sdim      if (MCEmitter)
129218893Sdim        Case += ", Fixups";
130218893Sdim      Case += ");\n";
131201360Srdivacky    }
132218893Sdim  } else {
133218893Sdim    Case += "      // op: " + VarName + "\n" +
134218893Sdim      "      op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
135218893Sdim    if (MCEmitter)
136218893Sdim      Case += ", Fixups";
137218893Sdim    Case += ");\n";
138193323Sed  }
139193323Sed
140218893Sdim  for (; bit >= 0; ) {
141218893Sdim    int varBit = getVariableBit(VarName, BI, bit);
142218893Sdim
143218893Sdim    // If this bit isn't from a variable, skip it.
144218893Sdim    if (varBit == -1) {
145218893Sdim      --bit;
146218893Sdim      continue;
147218893Sdim    }
148218893Sdim
149218893Sdim    // Figure out the consecutive range of bits covered by this operand, in
150218893Sdim    // order to generate better encoding code.
151218893Sdim    int beginInstBit = bit;
152218893Sdim    int beginVarBit = varBit;
153218893Sdim    int N = 1;
154218893Sdim    for (--bit; bit >= 0;) {
155218893Sdim      varBit = getVariableBit(VarName, BI, bit);
156218893Sdim      if (varBit == -1 || varBit != (beginVarBit - N)) break;
157218893Sdim      ++N;
158218893Sdim      --bit;
159218893Sdim    }
160218893Sdim
161218893Sdim    unsigned opMask = ~0U >> (32-N);
162218893Sdim    int opShift = beginVarBit - N + 1;
163218893Sdim    opMask <<= opShift;
164218893Sdim    opShift = beginInstBit - beginVarBit;
165218893Sdim
166218893Sdim    if (opShift > 0) {
167218893Sdim      Case += "      Value |= (op & " + utostr(opMask) + "U) << " +
168218893Sdim              itostr(opShift) + ";\n";
169218893Sdim    } else if (opShift < 0) {
170218893Sdim      Case += "      Value |= (op & " + utostr(opMask) + "U) >> " +
171218893Sdim              itostr(-opShift) + ";\n";
172218893Sdim    } else {
173218893Sdim      Case += "      Value |= op & " + utostr(opMask) + "U;\n";
174218893Sdim    }
175218893Sdim  }
176218893Sdim}
177193323Sed
178193323Sed
179218893Sdimstd::string CodeEmitterGen::getInstructionCase(Record *R,
180218893Sdim                                               CodeGenTarget &Target) {
181218893Sdim  std::string Case;
182218893Sdim
183218893Sdim  BitsInit *BI = R->getValueAsBitsInit("Inst");
184218893Sdim  const std::vector<RecordVal> &Vals = R->getValues();
185218893Sdim  unsigned NumberedOp = 0;
186218893Sdim
187218893Sdim  // Loop over all of the fields in the instruction, determining which are the
188218893Sdim  // operands to the instruction.
189218893Sdim  for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
190218893Sdim    // Ignore fixed fields in the record, we're looking for values like:
191218893Sdim    //    bits<5> RST = { ?, ?, ?, ?, ? };
192218893Sdim    if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
193218893Sdim      continue;
194218893Sdim
195218893Sdim    AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, Case, Target);
196218893Sdim  }
197218893Sdim
198218893Sdim  std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
199218893Sdim  if (!PostEmitter.empty())
200218893Sdim    Case += "      Value = " + PostEmitter + "(MI, Value);\n";
201218893Sdim
202218893Sdim  return Case;
203218893Sdim}
204218893Sdim
205195340Sedvoid CodeEmitterGen::run(raw_ostream &o) {
206218893Sdim  CodeGenTarget Target(Records);
207193323Sed  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
208218893Sdim
209193323Sed  // For little-endian instruction bit encodings, reverse the bit order
210193323Sed  if (Target.isLittleEndianEncoding()) reverseBits(Insts);
211193323Sed
212193323Sed  EmitSourceFileHeader("Machine Code Emitter", o);
213218893Sdim
214205407Srdivacky  const std::vector<const CodeGenInstruction*> &NumberedInstructions =
215205407Srdivacky    Target.getInstructionsByEnumValue();
216193323Sed
217193323Sed  // Emit function declaration
218218893Sdim  o << "unsigned " << Target.getName();
219218893Sdim  if (MCEmitter)
220218893Sdim    o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
221218893Sdim      << "    SmallVectorImpl<MCFixup> &Fixups) const {\n";
222218893Sdim  else
223218893Sdim    o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n";
224193323Sed
225193323Sed  // Emit instruction base values
226193323Sed  o << "  static const unsigned InstBits[] = {\n";
227205407Srdivacky  for (std::vector<const CodeGenInstruction*>::const_iterator
228193323Sed          IN = NumberedInstructions.begin(),
229193323Sed          EN = NumberedInstructions.end();
230193323Sed       IN != EN; ++IN) {
231193323Sed    const CodeGenInstruction *CGI = *IN;
232193323Sed    Record *R = CGI->TheDef;
233218893Sdim
234210299Sed    if (R->getValueAsString("Namespace") == "TargetOpcode") {
235193323Sed      o << "    0U,\n";
236193323Sed      continue;
237193323Sed    }
238218893Sdim
239193323Sed    BitsInit *BI = R->getValueAsBitsInit("Inst");
240193323Sed
241218893Sdim    // Start by filling in fixed values.
242193323Sed    unsigned Value = 0;
243193323Sed    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
244218893Sdim      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1)))
245193323Sed        Value |= B->getValue() << (e-i-1);
246193323Sed    }
247193323Sed    o << "    " << Value << "U," << '\t' << "// " << R->getName() << "\n";
248193323Sed  }
249193323Sed  o << "    0U\n  };\n";
250218893Sdim
251193323Sed  // Map to accumulate all the cases.
252193323Sed  std::map<std::string, std::vector<std::string> > CaseMap;
253218893Sdim
254193323Sed  // Construct all cases statement for each opcode
255193323Sed  for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end();
256193323Sed        IC != EC; ++IC) {
257193323Sed    Record *R = *IC;
258210299Sed    if (R->getValueAsString("Namespace") == "TargetOpcode")
259210299Sed      continue;
260218893Sdim    const std::string &InstName = R->getValueAsString("Namespace") + "::"
261218893Sdim      + R->getName();
262218893Sdim    std::string Case = getInstructionCase(R, Target);
263193323Sed
264218893Sdim    CaseMap[Case].push_back(InstName);
265193323Sed  }
266193323Sed
267193323Sed  // Emit initial function code
268193323Sed  o << "  const unsigned opcode = MI.getOpcode();\n"
269193323Sed    << "  unsigned Value = InstBits[opcode];\n"
270193323Sed    << "  unsigned op = 0;\n"
271218893Sdim    << "  (void)op;  // suppress warning\n"
272193323Sed    << "  switch (opcode) {\n";
273193323Sed
274193323Sed  // Emit each case statement
275193323Sed  std::map<std::string, std::vector<std::string> >::iterator IE, EE;
276193323Sed  for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) {
277193323Sed    const std::string &Case = IE->first;
278193323Sed    std::vector<std::string> &InstList = IE->second;
279193323Sed
280193323Sed    for (int i = 0, N = InstList.size(); i < N; i++) {
281193323Sed      if (i) o << "\n";
282218893Sdim      o << "    case " << InstList[i]  << ":";
283193323Sed    }
284193323Sed    o << " {\n";
285193323Sed    o << Case;
286193323Sed    o << "      break;\n"
287193323Sed      << "    }\n";
288193323Sed  }
289193323Sed
290193323Sed  // Default case: unhandled opcode
291193323Sed  o << "  default:\n"
292198090Srdivacky    << "    std::string msg;\n"
293198090Srdivacky    << "    raw_string_ostream Msg(msg);\n"
294198090Srdivacky    << "    Msg << \"Not supported instr: \" << MI;\n"
295207618Srdivacky    << "    report_fatal_error(Msg.str());\n"
296193323Sed    << "  }\n"
297193323Sed    << "  return Value;\n"
298193323Sed    << "}\n\n";
299193323Sed}
300