1193323Sed//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
2193323Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed//
9193323Sed// CodeEmitterGen uses the descriptions of instructions and their fields to
10193323Sed// construct an automated code emitter: a function that, given a MachineInstr,
11193323Sed// returns the (currently, 32-bit unsigned) value of the instruction.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15314564Sdim#include "CodeGenInstruction.h"
16193323Sed#include "CodeGenTarget.h"
17314564Sdim#include "SubtargetFeatureInfo.h"
18353358Sdim#include "Types.h"
19360784Sdim#include "llvm/ADT/APInt.h"
20314564Sdim#include "llvm/ADT/ArrayRef.h"
21193323Sed#include "llvm/ADT/StringExtras.h"
22314564Sdim#include "llvm/Support/Casting.h"
23314564Sdim#include "llvm/Support/raw_ostream.h"
24249423Sdim#include "llvm/TableGen/Record.h"
25239462Sdim#include "llvm/TableGen/TableGenBackend.h"
26314564Sdim#include <cassert>
27314564Sdim#include <cstdint>
28218893Sdim#include <map>
29314564Sdim#include <set>
30239462Sdim#include <string>
31314564Sdim#include <utility>
32239462Sdim#include <vector>
33314564Sdim
34193323Sedusing namespace llvm;
35193323Sed
36239462Sdimnamespace {
37239462Sdim
38239462Sdimclass CodeEmitterGen {
39239462Sdim  RecordKeeper &Records;
40314564Sdim
41239462Sdimpublic:
42239462Sdim  CodeEmitterGen(RecordKeeper &R) : Records(R) {}
43239462Sdim
44239462Sdim  void run(raw_ostream &o);
45314564Sdim
46239462Sdimprivate:
47239462Sdim  int getVariableBit(const std::string &VarName, BitsInit *BI, int bit);
48239462Sdim  std::string getInstructionCase(Record *R, CodeGenTarget &Target);
49360784Sdim  std::string getInstructionCaseForEncoding(Record *R, Record *EncodingDef,
50360784Sdim                                            CodeGenTarget &Target);
51239462Sdim  void AddCodeToMergeInOperand(Record *R, BitsInit *BI,
52239462Sdim                               const std::string &VarName,
53239462Sdim                               unsigned &NumberedOp,
54276479Sdim                               std::set<unsigned> &NamedOpIndices,
55239462Sdim                               std::string &Case, CodeGenTarget &Target);
56239462Sdim
57360784Sdim  void emitInstructionBaseValues(
58360784Sdim      raw_ostream &o, ArrayRef<const CodeGenInstruction *> NumberedInstructions,
59360784Sdim      CodeGenTarget &Target, int HwMode = -1);
60360784Sdim  unsigned BitWidth;
61360784Sdim  bool UseAPInt;
62239462Sdim};
63239462Sdim
64193323Sed// If the VarBitInit at position 'bit' matches the specified variable then
65193323Sed// return the variable bit position.  Otherwise return -1.
66201360Srdivackyint CodeEmitterGen::getVariableBit(const std::string &VarName,
67218893Sdim                                   BitsInit *BI, int bit) {
68243830Sdim  if (VarBitInit *VBI = dyn_cast<VarBitInit>(BI->getBit(bit))) {
69243830Sdim    if (VarInit *VI = dyn_cast<VarInit>(VBI->getBitVar()))
70218893Sdim      if (VI->getName() == VarName)
71218893Sdim        return VBI->getBitNum();
72243830Sdim  } else if (VarInit *VI = dyn_cast<VarInit>(BI->getBit(bit))) {
73221345Sdim    if (VI->getName() == VarName)
74221345Sdim      return 0;
75221345Sdim  }
76218893Sdim
77218893Sdim  return -1;
78218893Sdim}
79218893Sdim
80218893Sdimvoid CodeEmitterGen::
81218893SdimAddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
82218893Sdim                        unsigned &NumberedOp,
83276479Sdim                        std::set<unsigned> &NamedOpIndices,
84218893Sdim                        std::string &Case, CodeGenTarget &Target) {
85218893Sdim  CodeGenInstruction &CGI = Target.getInstruction(R);
86218893Sdim
87218893Sdim  // Determine if VarName actually contributes to the Inst encoding.
88218893Sdim  int bit = BI->getNumBits()-1;
89218893Sdim
90218893Sdim  // Scan for a bit that this contributed to.
91218893Sdim  for (; bit >= 0; ) {
92218893Sdim    if (getVariableBit(VarName, BI, bit) != -1)
93218893Sdim      break;
94201360Srdivacky
95218893Sdim    --bit;
96218893Sdim  }
97218893Sdim
98218893Sdim  // If we found no bits, ignore this value, otherwise emit the call to get the
99218893Sdim  // operand encoding.
100218893Sdim  if (bit < 0) return;
101218893Sdim
102218893Sdim  // If the operand matches by name, reference according to that
103218893Sdim  // operand number. Non-matching operands are assumed to be in
104218893Sdim  // order.
105218893Sdim  unsigned OpIdx;
106218893Sdim  if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
107218893Sdim    // Get the machine operand number for the indicated operand.
108218893Sdim    OpIdx = CGI.Operands[OpIdx].MIOperandNo;
109218893Sdim    assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
110218893Sdim           "Explicitly used operand also marked as not emitted!");
111218893Sdim  } else {
112243830Sdim    unsigned NumberOps = CGI.Operands.size();
113218893Sdim    /// If this operand is not supposed to be emitted by the
114218893Sdim    /// generated emitter, skip it.
115243830Sdim    while (NumberedOp < NumberOps &&
116276479Sdim           (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
117288943Sdim              (!NamedOpIndices.empty() && NamedOpIndices.count(
118276479Sdim                CGI.Operands.getSubOperandNumber(NumberedOp).first)))) {
119218893Sdim      ++NumberedOp;
120243830Sdim
121276479Sdim      if (NumberedOp >= CGI.Operands.back().MIOperandNo +
122276479Sdim                        CGI.Operands.back().MINumOperands) {
123276479Sdim        errs() << "Too few operands in record " << R->getName() <<
124276479Sdim                  " (no match for variable " << VarName << "):\n";
125276479Sdim        errs() << *R;
126276479Sdim        errs() << '\n';
127276479Sdim
128276479Sdim        return;
129276479Sdim      }
130276479Sdim    }
131276479Sdim
132218893Sdim    OpIdx = NumberedOp++;
133218893Sdim  }
134218893Sdim
135218893Sdim  std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx);
136218893Sdim  std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName;
137360784Sdim
138360784Sdim  if (UseAPInt)
139360784Sdim    Case += "      op.clearAllBits();\n";
140360784Sdim
141218893Sdim  // If the source operand has a custom encoder, use it. This will
142218893Sdim  // get the encoding for all of the suboperands.
143218893Sdim  if (!EncoderMethodName.empty()) {
144218893Sdim    // A custom encoder has all of the information for the
145218893Sdim    // sub-operands, if there are more than one, so only
146218893Sdim    // query the encoder once per source operand.
147218893Sdim    if (SO.second == 0) {
148360784Sdim      Case += "      // op: " + VarName + "\n";
149360784Sdim      if (UseAPInt) {
150360784Sdim        Case += "      " + EncoderMethodName + "(MI, " + utostr(OpIdx);
151360784Sdim        Case += ", op";
152360784Sdim      } else {
153360784Sdim        Case += "      op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
154360784Sdim      }
155360784Sdim      Case += ", Fixups, STI);\n";
156360784Sdim    }
157360784Sdim  } else {
158360784Sdim    Case += "      // op: " + VarName + "\n";
159360784Sdim    if (UseAPInt) {
160360784Sdim      Case += "      getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
161360784Sdim      Case += ", op, Fixups, STI";
162360784Sdim    } else {
163360784Sdim      Case += "      op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
164280031Sdim      Case += ", Fixups, STI";
165201360Srdivacky    }
166218893Sdim    Case += ");\n";
167193323Sed  }
168360784Sdim
169360784Sdim  // Precalculate the number of lits this variable contributes to in the
170360784Sdim  // operand. If there is a single lit (consecutive range of bits) we can use a
171360784Sdim  // destructive sequence on APInt that reduces memory allocations.
172360784Sdim  int numOperandLits = 0;
173360784Sdim  for (int tmpBit = bit; tmpBit >= 0;) {
174360784Sdim    int varBit = getVariableBit(VarName, BI, tmpBit);
175360784Sdim
176360784Sdim    // If this bit isn't from a variable, skip it.
177360784Sdim    if (varBit == -1) {
178360784Sdim      --tmpBit;
179360784Sdim      continue;
180360784Sdim    }
181360784Sdim
182360784Sdim    // Figure out the consecutive range of bits covered by this operand, in
183360784Sdim    // order to generate better encoding code.
184360784Sdim    int beginVarBit = varBit;
185360784Sdim    int N = 1;
186360784Sdim    for (--tmpBit; tmpBit >= 0;) {
187360784Sdim      varBit = getVariableBit(VarName, BI, tmpBit);
188360784Sdim      if (varBit == -1 || varBit != (beginVarBit - N))
189360784Sdim        break;
190360784Sdim      ++N;
191360784Sdim      --tmpBit;
192360784Sdim    }
193360784Sdim    ++numOperandLits;
194360784Sdim  }
195360784Sdim
196218893Sdim  for (; bit >= 0; ) {
197218893Sdim    int varBit = getVariableBit(VarName, BI, bit);
198218893Sdim
199218893Sdim    // If this bit isn't from a variable, skip it.
200218893Sdim    if (varBit == -1) {
201218893Sdim      --bit;
202218893Sdim      continue;
203218893Sdim    }
204218893Sdim
205218893Sdim    // Figure out the consecutive range of bits covered by this operand, in
206218893Sdim    // order to generate better encoding code.
207218893Sdim    int beginInstBit = bit;
208218893Sdim    int beginVarBit = varBit;
209218893Sdim    int N = 1;
210218893Sdim    for (--bit; bit >= 0;) {
211218893Sdim      varBit = getVariableBit(VarName, BI, bit);
212218893Sdim      if (varBit == -1 || varBit != (beginVarBit - N)) break;
213218893Sdim      ++N;
214218893Sdim      --bit;
215218893Sdim    }
216360784Sdim
217360784Sdim    std::string maskStr;
218360784Sdim    int opShift;
219360784Sdim
220360784Sdim    unsigned loBit = beginVarBit - N + 1;
221360784Sdim    unsigned hiBit = loBit + N;
222360784Sdim    unsigned loInstBit = beginInstBit - N + 1;
223360784Sdim    if (UseAPInt) {
224360784Sdim      std::string extractStr;
225360784Sdim      if (N >= 64) {
226360784Sdim        extractStr = "op.extractBits(" + itostr(hiBit - loBit) + ", " +
227360784Sdim                     itostr(loBit) + ")";
228360784Sdim        Case += "      Value.insertBits(" + extractStr + ", " +
229360784Sdim                itostr(loInstBit) + ");\n";
230360784Sdim      } else {
231360784Sdim        extractStr = "op.extractBitsAsZExtValue(" + itostr(hiBit - loBit) +
232360784Sdim                     ", " + itostr(loBit) + ")";
233360784Sdim        Case += "      Value.insertBits(" + extractStr + ", " +
234360784Sdim                itostr(loInstBit) + ", " + itostr(hiBit - loBit) + ");\n";
235360784Sdim      }
236218893Sdim    } else {
237360784Sdim      uint64_t opMask = ~(uint64_t)0 >> (64 - N);
238360784Sdim      opShift = beginVarBit - N + 1;
239360784Sdim      opMask <<= opShift;
240360784Sdim      maskStr = "UINT64_C(" + utostr(opMask) + ")";
241360784Sdim      opShift = beginInstBit - beginVarBit;
242360784Sdim
243360784Sdim      if (numOperandLits == 1) {
244360784Sdim        Case += "      op &= " + maskStr + ";\n";
245360784Sdim        if (opShift > 0) {
246360784Sdim          Case += "      op <<= " + itostr(opShift) + ";\n";
247360784Sdim        } else if (opShift < 0) {
248360784Sdim          Case += "      op >>= " + itostr(-opShift) + ";\n";
249360784Sdim        }
250360784Sdim        Case += "      Value |= op;\n";
251360784Sdim      } else {
252360784Sdim        if (opShift > 0) {
253360784Sdim          Case += "      Value |= (op & " + maskStr + ") << " +
254360784Sdim                  itostr(opShift) + ";\n";
255360784Sdim        } else if (opShift < 0) {
256360784Sdim          Case += "      Value |= (op & " + maskStr + ") >> " +
257360784Sdim                  itostr(-opShift) + ";\n";
258360784Sdim        } else {
259360784Sdim          Case += "      Value |= (op & " + maskStr + ");\n";
260360784Sdim        }
261360784Sdim      }
262218893Sdim    }
263218893Sdim  }
264218893Sdim}
265193323Sed
266218893Sdimstd::string CodeEmitterGen::getInstructionCase(Record *R,
267218893Sdim                                               CodeGenTarget &Target) {
268218893Sdim  std::string Case;
269360784Sdim  if (const RecordVal *RV = R->getValue("EncodingInfos")) {
270360784Sdim    if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
271360784Sdim      const CodeGenHwModes &HWM = Target.getHwModes();
272360784Sdim      EncodingInfoByHwMode EBM(DI->getDef(), HWM);
273360784Sdim      Case += "      switch (HwMode) {\n";
274360784Sdim      Case += "      default: llvm_unreachable(\"Unhandled HwMode\");\n";
275360784Sdim      for (auto &KV : EBM.Map) {
276360784Sdim        Case += "      case " + itostr(KV.first) + ": {\n";
277360784Sdim        Case += getInstructionCaseForEncoding(R, KV.second, Target);
278360784Sdim        Case += "      break;\n";
279360784Sdim        Case += "      }\n";
280360784Sdim      }
281360784Sdim      Case += "      }\n";
282360784Sdim      return Case;
283360784Sdim    }
284360784Sdim  }
285360784Sdim  return getInstructionCaseForEncoding(R, R, Target);
286360784Sdim}
287360784Sdim
288360784Sdimstd::string CodeEmitterGen::getInstructionCaseForEncoding(Record *R, Record *EncodingDef,
289360784Sdim                                                          CodeGenTarget &Target) {
290360784Sdim  std::string Case;
291360784Sdim  BitsInit *BI = EncodingDef->getValueAsBitsInit("Inst");
292218893Sdim  unsigned NumberedOp = 0;
293321369Sdim  std::set<unsigned> NamedOpIndices;
294218893Sdim
295276479Sdim  // Collect the set of operand indices that might correspond to named
296276479Sdim  // operand, and skip these when assigning operands based on position.
297276479Sdim  if (Target.getInstructionSet()->
298276479Sdim       getValueAsBit("noNamedPositionallyEncodedOperands")) {
299276479Sdim    CodeGenInstruction &CGI = Target.getInstruction(R);
300321369Sdim    for (const RecordVal &RV : R->getValues()) {
301276479Sdim      unsigned OpIdx;
302321369Sdim      if (!CGI.Operands.hasOperandNamed(RV.getName(), OpIdx))
303276479Sdim        continue;
304276479Sdim
305276479Sdim      NamedOpIndices.insert(OpIdx);
306276479Sdim    }
307276479Sdim  }
308276479Sdim
309218893Sdim  // Loop over all of the fields in the instruction, determining which are the
310218893Sdim  // operands to the instruction.
311360784Sdim  for (const RecordVal &RV : EncodingDef->getValues()) {
312218893Sdim    // Ignore fixed fields in the record, we're looking for values like:
313218893Sdim    //    bits<5> RST = { ?, ?, ?, ?, ? };
314321369Sdim    if (RV.getPrefix() || RV.getValue()->isComplete())
315218893Sdim      continue;
316218893Sdim
317321369Sdim    AddCodeToMergeInOperand(R, BI, RV.getName(), NumberedOp,
318276479Sdim                            NamedOpIndices, Case, Target);
319218893Sdim  }
320321369Sdim
321321369Sdim  StringRef PostEmitter = R->getValueAsString("PostEncoderMethod");
322276479Sdim  if (!PostEmitter.empty()) {
323321369Sdim    Case += "      Value = ";
324321369Sdim    Case += PostEmitter;
325321369Sdim    Case += "(MI, Value";
326280031Sdim    Case += ", STI";
327276479Sdim    Case += ");\n";
328276479Sdim  }
329218893Sdim
330218893Sdim  return Case;
331218893Sdim}
332218893Sdim
333353358Sdimstatic std::string
334353358SdimgetNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
335353358Sdim  std::string Name = "CEFBS";
336353358Sdim  for (const auto &Feature : FeatureBitset)
337353358Sdim    Name += ("_" + Feature->getName()).str();
338353358Sdim  return Name;
339353358Sdim}
340353358Sdim
341360784Sdimstatic void emitInstBits(raw_ostream &OS, const APInt &Bits) {
342360784Sdim  for (unsigned I = 0; I < Bits.getNumWords(); ++I)
343360784Sdim    OS << ((I > 0) ? ", " : "") << "UINT64_C(" << utostr(Bits.getRawData()[I])
344360784Sdim       << ")";
345360784Sdim}
346360784Sdim
347360784Sdimvoid CodeEmitterGen::emitInstructionBaseValues(
348360784Sdim    raw_ostream &o, ArrayRef<const CodeGenInstruction *> NumberedInstructions,
349360784Sdim    CodeGenTarget &Target, int HwMode) {
350360784Sdim  const CodeGenHwModes &HWM = Target.getHwModes();
351360784Sdim  if (HwMode == -1)
352360784Sdim    o << "  static const uint64_t InstBits[] = {\n";
353360784Sdim  else
354360784Sdim    o << "  static const uint64_t InstBits_" << HWM.getMode(HwMode).Name
355360784Sdim      << "[] = {\n";
356360784Sdim
357360784Sdim  for (const CodeGenInstruction *CGI : NumberedInstructions) {
358360784Sdim    Record *R = CGI->TheDef;
359360784Sdim
360360784Sdim    if (R->getValueAsString("Namespace") == "TargetOpcode" ||
361360784Sdim        R->getValueAsBit("isPseudo")) {
362360784Sdim      o << "    "; emitInstBits(o, APInt(BitWidth, 0)); o << ",\n";
363360784Sdim      continue;
364360784Sdim    }
365360784Sdim
366360784Sdim    Record *EncodingDef = R;
367360784Sdim    if (const RecordVal *RV = R->getValue("EncodingInfos")) {
368360784Sdim      if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
369360784Sdim        EncodingInfoByHwMode EBM(DI->getDef(), HWM);
370360784Sdim        if (EBM.hasMode(HwMode))
371360784Sdim          EncodingDef = EBM.get(HwMode);
372360784Sdim      }
373360784Sdim    }
374360784Sdim    BitsInit *BI = EncodingDef->getValueAsBitsInit("Inst");
375360784Sdim
376360784Sdim    // Start by filling in fixed values.
377360784Sdim    APInt Value(BitWidth, 0);
378360784Sdim    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
379360784Sdim      if (BitInit *B = dyn_cast<BitInit>(BI->getBit(e - i - 1)))
380360784Sdim        Value |= APInt(BitWidth, (uint64_t)B->getValue()) << (e - i - 1);
381360784Sdim    }
382360784Sdim    o << "    ";
383360784Sdim    emitInstBits(o, Value);
384360784Sdim    o << "," << '\t' << "// " << R->getName() << "\n";
385360784Sdim  }
386360784Sdim  o << "    UINT64_C(0)\n  };\n";
387360784Sdim}
388360784Sdim
389195340Sedvoid CodeEmitterGen::run(raw_ostream &o) {
390218893Sdim  CodeGenTarget Target(Records);
391193323Sed  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
392218893Sdim
393193323Sed  // For little-endian instruction bit encodings, reverse the bit order
394276479Sdim  Target.reverseBitsForLittleEndianEncoding();
395193323Sed
396309124Sdim  ArrayRef<const CodeGenInstruction*> NumberedInstructions =
397205407Srdivacky    Target.getInstructionsByEnumValue();
398193323Sed
399360784Sdim  const CodeGenHwModes &HWM = Target.getHwModes();
400360784Sdim  // The set of HwModes used by instruction encodings.
401360784Sdim  std::set<unsigned> HwModes;
402360784Sdim  BitWidth = 0;
403309124Sdim  for (const CodeGenInstruction *CGI : NumberedInstructions) {
404193323Sed    Record *R = CGI->TheDef;
405224145Sdim    if (R->getValueAsString("Namespace") == "TargetOpcode" ||
406360784Sdim        R->getValueAsBit("isPseudo"))
407193323Sed      continue;
408360784Sdim
409360784Sdim    if (const RecordVal *RV = R->getValue("EncodingInfos")) {
410360784Sdim      if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
411360784Sdim        EncodingInfoByHwMode EBM(DI->getDef(), HWM);
412360784Sdim        for (auto &KV : EBM.Map) {
413360784Sdim          BitsInit *BI = KV.second->getValueAsBitsInit("Inst");
414360784Sdim          BitWidth = std::max(BitWidth, BI->getNumBits());
415360784Sdim          HwModes.insert(KV.first);
416360784Sdim        }
417360784Sdim        continue;
418360784Sdim      }
419193323Sed    }
420193323Sed    BitsInit *BI = R->getValueAsBitsInit("Inst");
421360784Sdim    BitWidth = std::max(BitWidth, BI->getNumBits());
422360784Sdim  }
423360784Sdim  UseAPInt = BitWidth > 64;
424360784Sdim
425360784Sdim  // Emit function declaration
426360784Sdim  if (UseAPInt) {
427360784Sdim    o << "void " << Target.getName()
428360784Sdim      << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
429360784Sdim      << "    SmallVectorImpl<MCFixup> &Fixups,\n"
430360784Sdim      << "    APInt &Inst,\n"
431360784Sdim      << "    APInt &Scratch,\n"
432360784Sdim      << "    const MCSubtargetInfo &STI) const {\n";
433360784Sdim  } else {
434360784Sdim    o << "uint64_t " << Target.getName();
435360784Sdim    o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
436360784Sdim      << "    SmallVectorImpl<MCFixup> &Fixups,\n"
437360784Sdim      << "    const MCSubtargetInfo &STI) const {\n";
438360784Sdim  }
439360784Sdim
440360784Sdim  // Emit instruction base values
441360784Sdim  if (HwModes.empty()) {
442360784Sdim    emitInstructionBaseValues(o, NumberedInstructions, Target, -1);
443360784Sdim  } else {
444360784Sdim    for (unsigned HwMode : HwModes)
445360784Sdim      emitInstructionBaseValues(o, NumberedInstructions, Target, (int)HwMode);
446360784Sdim  }
447193323Sed
448360784Sdim  if (!HwModes.empty()) {
449360784Sdim    o << "  const uint64_t *InstBits;\n";
450360784Sdim    o << "  unsigned HwMode = STI.getHwMode();\n";
451360784Sdim    o << "  switch (HwMode) {\n";
452360784Sdim    o << "  default: llvm_unreachable(\"Unknown hardware mode!\"); break;\n";
453360784Sdim    for (unsigned I : HwModes) {
454360784Sdim      o << "  case " << I << ": InstBits = InstBits_" << HWM.getMode(I).Name
455360784Sdim        << "; break;\n";
456193323Sed    }
457360784Sdim    o << "  };\n";
458193323Sed  }
459218893Sdim
460193323Sed  // Map to accumulate all the cases.
461314564Sdim  std::map<std::string, std::vector<std::string>> CaseMap;
462218893Sdim
463193323Sed  // Construct all cases statement for each opcode
464193323Sed  for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end();
465193323Sed        IC != EC; ++IC) {
466193323Sed    Record *R = *IC;
467224145Sdim    if (R->getValueAsString("Namespace") == "TargetOpcode" ||
468224145Sdim        R->getValueAsBit("isPseudo"))
469210299Sed      continue;
470321369Sdim    std::string InstName =
471321369Sdim        (R->getValueAsString("Namespace") + "::" + R->getName()).str();
472218893Sdim    std::string Case = getInstructionCase(R, Target);
473193323Sed
474321369Sdim    CaseMap[Case].push_back(std::move(InstName));
475193323Sed  }
476193323Sed
477193323Sed  // Emit initial function code
478360784Sdim  if (UseAPInt) {
479360784Sdim    int NumWords = APInt::getNumWords(BitWidth);
480360784Sdim    int NumBytes = (BitWidth + 7) / 8;
481360784Sdim    o << "  const unsigned opcode = MI.getOpcode();\n"
482360784Sdim      << "  if (Inst.getBitWidth() != " << BitWidth << ")\n"
483360784Sdim      << "    Inst = Inst.zext(" << BitWidth << ");\n"
484360784Sdim      << "  if (Scratch.getBitWidth() != " << BitWidth << ")\n"
485360784Sdim      << "    Scratch = Scratch.zext(" << BitWidth << ");\n"
486360784Sdim      << "  LoadIntFromMemory(Inst, (uint8_t*)&InstBits[opcode * " << NumWords
487360784Sdim      << "], " << NumBytes << ");\n"
488360784Sdim      << "  APInt &Value = Inst;\n"
489360784Sdim      << "  APInt &op = Scratch;\n"
490360784Sdim      << "  switch (opcode) {\n";
491360784Sdim  } else {
492360784Sdim    o << "  const unsigned opcode = MI.getOpcode();\n"
493360784Sdim      << "  uint64_t Value = InstBits[opcode];\n"
494360784Sdim      << "  uint64_t op = 0;\n"
495360784Sdim      << "  (void)op;  // suppress warning\n"
496360784Sdim      << "  switch (opcode) {\n";
497360784Sdim  }
498193323Sed
499193323Sed  // Emit each case statement
500314564Sdim  std::map<std::string, std::vector<std::string>>::iterator IE, EE;
501193323Sed  for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) {
502193323Sed    const std::string &Case = IE->first;
503193323Sed    std::vector<std::string> &InstList = IE->second;
504193323Sed
505193323Sed    for (int i = 0, N = InstList.size(); i < N; i++) {
506193323Sed      if (i) o << "\n";
507218893Sdim      o << "    case " << InstList[i]  << ":";
508193323Sed    }
509193323Sed    o << " {\n";
510193323Sed    o << Case;
511193323Sed    o << "      break;\n"
512193323Sed      << "    }\n";
513193323Sed  }
514193323Sed
515193323Sed  // Default case: unhandled opcode
516193323Sed  o << "  default:\n"
517198090Srdivacky    << "    std::string msg;\n"
518198090Srdivacky    << "    raw_string_ostream Msg(msg);\n"
519198090Srdivacky    << "    Msg << \"Not supported instr: \" << MI;\n"
520207618Srdivacky    << "    report_fatal_error(Msg.str());\n"
521360784Sdim    << "  }\n";
522360784Sdim  if (UseAPInt)
523360784Sdim    o << "  Inst = Value;\n";
524360784Sdim  else
525360784Sdim    o << "  return Value;\n";
526360784Sdim  o << "}\n\n";
527314564Sdim
528314564Sdim  const auto &All = SubtargetFeatureInfo::getAll(Records);
529314564Sdim  std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
530314564Sdim  SubtargetFeatures.insert(All.begin(), All.end());
531314564Sdim
532314564Sdim  o << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
533314564Sdim    << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
534314564Sdim    << "#include <sstream>\n\n";
535314564Sdim
536314564Sdim  // Emit the subtarget feature enumeration.
537353358Sdim  SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
538353358Sdim                                                           o);
539314564Sdim
540314564Sdim  // Emit the name table for error messages.
541314564Sdim  o << "#ifndef NDEBUG\n";
542314564Sdim  SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, o);
543314564Sdim  o << "#endif // NDEBUG\n";
544314564Sdim
545314564Sdim  // Emit the available features compute function.
546321369Sdim  SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
547314564Sdim      Target.getName(), "MCCodeEmitter", "computeAvailableFeatures",
548314564Sdim      SubtargetFeatures, o);
549314564Sdim
550353358Sdim  std::vector<std::vector<Record *>> FeatureBitsets;
551353358Sdim  for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
552353358Sdim    FeatureBitsets.emplace_back();
553353358Sdim    for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
554353358Sdim      const auto &I = SubtargetFeatures.find(Predicate);
555353358Sdim      if (I != SubtargetFeatures.end())
556353358Sdim        FeatureBitsets.back().push_back(I->second.TheDef);
557353358Sdim    }
558353358Sdim  }
559353358Sdim
560353358Sdim  llvm::sort(FeatureBitsets, [&](const std::vector<Record *> &A,
561353358Sdim                                 const std::vector<Record *> &B) {
562353358Sdim    if (A.size() < B.size())
563353358Sdim      return true;
564353358Sdim    if (A.size() > B.size())
565353358Sdim      return false;
566360784Sdim    for (auto Pair : zip(A, B)) {
567353358Sdim      if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
568353358Sdim        return true;
569353358Sdim      if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
570353358Sdim        return false;
571353358Sdim    }
572353358Sdim    return false;
573353358Sdim  });
574353358Sdim  FeatureBitsets.erase(
575353358Sdim      std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
576353358Sdim      FeatureBitsets.end());
577353358Sdim  o << "#ifndef NDEBUG\n"
578353358Sdim    << "// Feature bitsets.\n"
579353358Sdim    << "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
580353358Sdim    << "  CEFBS_None,\n";
581353358Sdim  for (const auto &FeatureBitset : FeatureBitsets) {
582353358Sdim    if (FeatureBitset.empty())
583353358Sdim      continue;
584353358Sdim    o << "  " << getNameForFeatureBitset(FeatureBitset) << ",\n";
585353358Sdim  }
586353358Sdim  o << "};\n\n"
587360784Sdim    << "static constexpr FeatureBitset FeatureBitsets[] = {\n"
588360784Sdim    << "  {}, // CEFBS_None\n";
589353358Sdim  for (const auto &FeatureBitset : FeatureBitsets) {
590353358Sdim    if (FeatureBitset.empty())
591353358Sdim      continue;
592353358Sdim    o << "  {";
593353358Sdim    for (const auto &Feature : FeatureBitset) {
594353358Sdim      const auto &I = SubtargetFeatures.find(Feature);
595353358Sdim      assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
596353358Sdim      o << I->second.getEnumBitName() << ", ";
597353358Sdim    }
598353358Sdim    o << "},\n";
599353358Sdim  }
600353358Sdim  o << "};\n"
601353358Sdim    << "#endif // NDEBUG\n\n";
602353358Sdim
603353358Sdim
604314564Sdim  // Emit the predicate verifier.
605314564Sdim  o << "void " << Target.getName()
606314564Sdim    << "MCCodeEmitter::verifyInstructionPredicates(\n"
607353358Sdim    << "    const MCInst &Inst, const FeatureBitset &AvailableFeatures) const {\n"
608314564Sdim    << "#ifndef NDEBUG\n"
609353358Sdim    << "  static " << getMinimalTypeForRange(FeatureBitsets.size())
610353358Sdim    << " RequiredFeaturesRefs[] = {\n";
611314564Sdim  unsigned InstIdx = 0;
612314564Sdim  for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
613353358Sdim    o << "    CEFBS";
614353358Sdim    unsigned NumPredicates = 0;
615314564Sdim    for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
616314564Sdim      const auto &I = SubtargetFeatures.find(Predicate);
617353358Sdim      if (I != SubtargetFeatures.end()) {
618353358Sdim        o << '_' << I->second.TheDef->getName();
619353358Sdim        NumPredicates++;
620353358Sdim      }
621314564Sdim    }
622353358Sdim    if (!NumPredicates)
623353358Sdim      o << "_None";
624353358Sdim    o << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
625314564Sdim    InstIdx++;
626314564Sdim  }
627314564Sdim  o << "  };\n\n";
628314564Sdim  o << "  assert(Inst.getOpcode() < " << InstIdx << ");\n";
629353358Sdim  o << "  const FeatureBitset &RequiredFeatures = "
630353358Sdim       "FeatureBitsets[RequiredFeaturesRefs[Inst.getOpcode()]];\n";
631353358Sdim  o << "  FeatureBitset MissingFeatures =\n"
632353358Sdim    << "      (AvailableFeatures & RequiredFeatures) ^\n"
633353358Sdim    << "      RequiredFeatures;\n"
634353358Sdim    << "  if (MissingFeatures.any()) {\n"
635314564Sdim    << "    std::ostringstream Msg;\n"
636314564Sdim    << "    Msg << \"Attempting to emit \" << "
637314564Sdim       "MCII.getName(Inst.getOpcode()).str()\n"
638314564Sdim    << "        << \" instruction but the \";\n"
639353358Sdim    << "    for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
640353358Sdim    << "      if (MissingFeatures.test(i))\n"
641314564Sdim    << "        Msg << SubtargetFeatureNames[i] << \" \";\n"
642314564Sdim    << "    Msg << \"predicate(s) are not met\";\n"
643314564Sdim    << "    report_fatal_error(Msg.str());\n"
644314564Sdim    << "  }\n"
645314564Sdim    << "#else\n"
646314564Sdim    << "// Silence unused variable warning on targets that don't use MCII for "
647314564Sdim       "other purposes (e.g. BPF).\n"
648314564Sdim    << "(void)MCII;\n"
649314564Sdim    << "#endif // NDEBUG\n";
650314564Sdim  o << "}\n";
651314564Sdim  o << "#endif\n";
652193323Sed}
653239462Sdim
654314564Sdim} // end anonymous namespace
655239462Sdim
656239462Sdimnamespace llvm {
657239462Sdim
658239462Sdimvoid EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) {
659239462Sdim  emitSourceFileHeader("Machine Code Emitter", OS);
660239462Sdim  CodeEmitterGen(RK).run(OS);
661239462Sdim}
662239462Sdim
663314564Sdim} // end namespace llvm
664