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