InstrInfoEmitter.cpp revision 366080c5e6b4b8e1f07829a2489cc5d21f51bf3b
1//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This tablegen backend is responsible for emitting a description of the target
11// instruction set for the code generator.
12//
13//===----------------------------------------------------------------------===//
14
15#include "InstrInfoEmitter.h"
16#include "CodeGenTarget.h"
17#include "Record.h"
18using namespace llvm;
19
20// runEnums - Print out enum values for all of the instructions.
21void InstrInfoEmitter::runEnums(std::ostream &OS) {
22  EmitSourceFileHeader("Target Instruction Enum Values", OS);
23  OS << "namespace llvm {\n\n";
24
25  CodeGenTarget Target;
26
27  // We must emit the PHI opcode first...
28  Record *InstrInfo = Target.getInstructionSet();
29
30  std::string Namespace = Target.inst_begin()->second.Namespace;
31
32  if (!Namespace.empty())
33    OS << "namespace " << Namespace << " {\n";
34  OS << "  enum {\n";
35
36  std::vector<const CodeGenInstruction*> NumberedInstructions;
37  Target.getInstructionsByEnumValue(NumberedInstructions);
38
39  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
40    OS << "    " << NumberedInstructions[i]->TheDef->getName()
41       << ", \t// " << i << "\n";
42  }
43  OS << "    INSTRUCTION_LIST_END\n";
44  OS << "  };\n";
45  if (!Namespace.empty())
46    OS << "}\n";
47  OS << "} // End llvm namespace \n";
48}
49
50void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses,
51                                    unsigned Num, std::ostream &OS) const {
52  OS << "static const unsigned ImplicitList" << Num << "[] = { ";
53  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
54    OS << getQualifiedName(Uses[i]) << ", ";
55  OS << "0 };\n";
56}
57
58static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) {
59  std::vector<Record*> Result;
60  if (Inst.hasVariableNumberOfOperands)
61    return Result;  // No info for variable operand instrs.
62
63  for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
64    if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass"))
65      Result.push_back(Inst.OperandList[i].Rec);
66    else {
67      // This might be a multiple operand thing.
68      // FIXME: Targets like X86 have registers in their multi-operand operands.
69      for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j)
70        Result.push_back(0);
71    }
72  }
73  return Result;
74}
75
76
77// run - Emit the main instruction description records for the target...
78void InstrInfoEmitter::run(std::ostream &OS) {
79  EmitSourceFileHeader("Target Instruction Descriptors", OS);
80  OS << "namespace llvm {\n\n";
81
82  CodeGenTarget Target;
83  const std::string &TargetName = Target.getName();
84  Record *InstrInfo = Target.getInstructionSet();
85  Record *PHI = InstrInfo->getValueAsDef("PHIInst");
86
87  // Emit empty implicit uses and defs lists
88  OS << "static const unsigned EmptyImpList[] = { 0 };\n";
89
90  // Keep track of all of the def lists we have emitted already.
91  std::map<std::vector<Record*>, unsigned> EmittedLists;
92  unsigned ListNumber = 0;
93
94  // Emit all of the instruction's implicit uses and defs.
95  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
96         E = Target.inst_end(); II != E; ++II) {
97    Record *Inst = II->second.TheDef;
98    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
99    if (!Uses.empty()) {
100      unsigned &IL = EmittedLists[Uses];
101      if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
102    }
103    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
104    if (!Defs.empty()) {
105      unsigned &IL = EmittedLists[Defs];
106      if (!IL) printDefList(Defs, IL = ++ListNumber, OS);
107    }
108  }
109
110  std::map<std::vector<Record*>, unsigned> OperandInfosEmitted;
111  unsigned OperandListNum = 0;
112  OperandInfosEmitted[std::vector<Record*>()] = ++OperandListNum;
113
114  // Emit all of the operand info records.
115  OS << "\n";
116  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
117       E = Target.inst_end(); II != E; ++II) {
118    std::vector<Record*> OperandInfo = GetOperandInfo(II->second);
119    unsigned &N = OperandInfosEmitted[OperandInfo];
120    if (N == 0) {
121      N = ++OperandListNum;
122      OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { ";
123      for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) {
124        if (Record *RC = OperandInfo[i]) {
125          OS << "{ &" << getQualifiedName(RC) << "RegClass }, ";
126        } else {
127          OS << "{ 0 }, ";
128        }
129      }
130      OS << "};\n";
131    }
132  }
133
134  // Emit all of the TargetInstrDescriptor records.
135  //
136  OS << "\nstatic const TargetInstrDescriptor " << TargetName
137     << "Insts[] = {\n";
138  emitRecord(Target.getPHIInstruction(), 0, InstrInfo, EmittedLists,
139             OperandInfosEmitted, OS);
140
141  unsigned i = 0;
142  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
143         E = Target.inst_end(); II != E; ++II)
144    if (II->second.TheDef != PHI)
145      emitRecord(II->second, ++i, InstrInfo, EmittedLists,
146                 OperandInfosEmitted, OS);
147  OS << "};\n";
148  OS << "} // End llvm namespace \n";
149}
150
151void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
152                                  Record *InstrInfo,
153                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
154                               std::map<std::vector<Record*>, unsigned> &OpInfo,
155                                  std::ostream &OS) {
156  int NumOperands;
157  if (Inst.hasVariableNumberOfOperands)
158    NumOperands = -1;
159  else if (!Inst.OperandList.empty())
160    // Each logical operand can be multiple MI operands.
161    NumOperands = Inst.OperandList.back().MIOperandNo +
162                  Inst.OperandList.back().MINumOperands;
163  else
164    NumOperands = 0;
165
166  OS << "  { \"";
167  if (Inst.Name.empty())
168    OS << Inst.TheDef->getName();
169  else
170    OS << Inst.Name;
171  OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, 0, 0";
172
173  // Emit all of the target indepedent flags...
174  if (Inst.isReturn)     OS << "|M_RET_FLAG";
175  if (Inst.isBranch)     OS << "|M_BRANCH_FLAG";
176  if (Inst.isBarrier)    OS << "|M_BARRIER_FLAG";
177  if (Inst.hasDelaySlot) OS << "|M_DELAY_SLOT_FLAG";
178  if (Inst.isCall)       OS << "|M_CALL_FLAG";
179  if (Inst.isLoad)       OS << "|M_LOAD_FLAG";
180  if (Inst.isStore)      OS << "|M_STORE_FLAG";
181  if (Inst.isTwoAddress) OS << "|M_2_ADDR_FLAG";
182  if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR";
183  if (Inst.isCommutable) OS << "|M_COMMUTABLE";
184  if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG";
185  if (Inst.usesCustomDAGSchedInserter)
186    OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION";
187  OS << ", 0";
188
189  // Emit all of the target-specific flags...
190  ListInit *LI    = InstrInfo->getValueAsListInit("TSFlagsFields");
191  ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts");
192  if (LI->getSize() != Shift->getSize())
193    throw "Lengths of " + InstrInfo->getName() +
194          ":(TargetInfoFields, TargetInfoPositions) must be equal!";
195
196  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
197    emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)),
198                     dynamic_cast<IntInit*>(Shift->getElement(i)), OS);
199
200  OS << ", ";
201
202  // Emit the implicit uses and defs lists...
203  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
204  if (UseList.empty())
205    OS << "EmptyImpList, ";
206  else
207    OS << "ImplicitList" << EmittedLists[UseList] << ", ";
208
209  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
210  if (DefList.empty())
211    OS << "EmptyImpList, ";
212  else
213    OS << "ImplicitList" << EmittedLists[DefList] << ", ";
214
215  // Emit the operand info.
216  std::vector<Record*> OperandInfo = GetOperandInfo(Inst);
217  if (OperandInfo.empty())
218    OS << "0";
219  else
220    OS << "OperandInfo" << OpInfo[OperandInfo];
221
222  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
223}
224
225void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
226                                        IntInit *ShiftInt, std::ostream &OS) {
227  if (Val == 0 || ShiftInt == 0)
228    throw std::string("Illegal value or shift amount in TargetInfo*!");
229  RecordVal *RV = R->getValue(Val->getValue());
230  int Shift = ShiftInt->getValue();
231
232  if (RV == 0 || RV->getValue() == 0)
233    throw R->getName() + " doesn't have a field named '" + Val->getValue()+"'!";
234
235  Init *Value = RV->getValue();
236  if (BitInit *BI = dynamic_cast<BitInit*>(Value)) {
237    if (BI->getValue()) OS << "|(1<<" << Shift << ")";
238    return;
239  } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) {
240    // Convert the Bits to an integer to print...
241    Init *I = BI->convertInitializerTo(new IntRecTy());
242    if (I)
243      if (IntInit *II = dynamic_cast<IntInit*>(I)) {
244        if (II->getValue())
245          OS << "|(" << II->getValue() << "<<" << Shift << ")";
246        return;
247      }
248
249  } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) {
250    if (II->getValue()) OS << "|(" << II->getValue() << "<<" << Shift << ")";
251    return;
252  }
253
254  std::cerr << "Unhandled initializer: " << *Val << "\n";
255  throw "In record '" + R->getName() + "' for TSFlag emission.";
256}
257
258