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