EDEmitter.cpp revision 127dc5e615390609540b07ce262ac368278ddb88
1//===- EDEmitter.cpp - Generate instruction descriptions for ED -*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This tablegen backend is responsible for emitting a description of each
11// instruction in a format that the enhanced disassembler can use to tokenize
12// and parse instructions.
13//
14//===----------------------------------------------------------------------===//
15
16#include "EDEmitter.h"
17
18#include "AsmWriterInst.h"
19#include "CodeGenTarget.h"
20#include "Record.h"
21
22#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/Format.h"
24#include "llvm/Support/raw_ostream.h"
25
26#include <map>
27#include <string>
28#include <vector>
29
30#define MAX_OPERANDS 13
31#define MAX_SYNTAXES 2
32
33using namespace llvm;
34
35///////////////////////////////////////////////////////////
36// Support classes for emitting nested C data structures //
37///////////////////////////////////////////////////////////
38
39namespace {
40
41  class EnumEmitter {
42  private:
43    std::string Name;
44    std::vector<std::string> Entries;
45  public:
46    EnumEmitter(const char *N) : Name(N) {
47    }
48    int addEntry(const char *e) {
49      Entries.push_back(std::string(e));
50      return Entries.size() - 1;
51    }
52    void emit(raw_ostream &o, unsigned int &i) {
53      o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
54      i += 2;
55
56      unsigned int index = 0;
57      unsigned int numEntries = Entries.size();
58      for (index = 0; index < numEntries; ++index) {
59        o.indent(i) << Entries[index];
60        if (index < (numEntries - 1))
61          o << ",";
62        o << "\n";
63      }
64
65      i -= 2;
66      o.indent(i) << "};" << "\n";
67    }
68
69    void emitAsFlags(raw_ostream &o, unsigned int &i) {
70      o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
71      i += 2;
72
73      unsigned int index = 0;
74      unsigned int numEntries = Entries.size();
75      unsigned int flag = 1;
76      for (index = 0; index < numEntries; ++index) {
77        o.indent(i) << Entries[index] << " = " << format("0x%x", flag);
78        if (index < (numEntries - 1))
79          o << ",";
80        o << "\n";
81        flag <<= 1;
82      }
83
84      i -= 2;
85      o.indent(i) << "};" << "\n";
86    }
87  };
88
89  class StructEmitter {
90  private:
91    std::string Name;
92    typedef std::pair<const char*, const char*> member;
93    std::vector< member > Members;
94  public:
95    StructEmitter(const char *N) : Name(N) {
96    }
97    void addMember(const char *t, const char *n) {
98      member m(t, n);
99      Members.push_back(m);
100    }
101    void emit(raw_ostream &o, unsigned int &i) {
102      o.indent(i) << "struct " << Name.c_str() << " {" << "\n";
103      i += 2;
104
105      unsigned int index = 0;
106      unsigned int numMembers = Members.size();
107      for (index = 0; index < numMembers; ++index) {
108        o.indent(i) << Members[index].first << " ";
109        o.indent(i) << Members[index].second << ";" << "\n";
110      }
111
112      i -= 2;
113      o.indent(i) << "};" << "\n";
114    }
115  };
116
117  class ConstantEmitter {
118  public:
119    virtual ~ConstantEmitter() { }
120    virtual void emit(raw_ostream &o, unsigned int &i) = 0;
121  };
122
123  class LiteralConstantEmitter : public ConstantEmitter {
124  private:
125    bool IsNumber;
126    union {
127      int Number;
128      const char* String;
129    };
130  public:
131    LiteralConstantEmitter(const char *string) :
132      IsNumber(false),
133      String(string) {
134    }
135    LiteralConstantEmitter(int number = 0) :
136      IsNumber(true),
137      Number(number) {
138    }
139    void set(const char *string) {
140      IsNumber = false;
141      Number = 0;
142      String = string;
143    }
144    void set(int number) {
145      IsNumber = true;
146      String = NULL;
147      Number = number;
148    }
149    bool is(const char *string) {
150      return !strcmp(String, string);
151    }
152    void emit(raw_ostream &o, unsigned int &i) {
153      if (IsNumber)
154        o << Number;
155      else
156        o << String;
157    }
158  };
159
160  class CompoundConstantEmitter : public ConstantEmitter {
161  private:
162    unsigned int Padding;
163    std::vector<ConstantEmitter *> Entries;
164  public:
165    CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) {
166    }
167    CompoundConstantEmitter &addEntry(ConstantEmitter *e) {
168      Entries.push_back(e);
169
170      return *this;
171    }
172    ~CompoundConstantEmitter() {
173      while (Entries.size()) {
174        ConstantEmitter *entry = Entries.back();
175        Entries.pop_back();
176        delete entry;
177      }
178    }
179    void emit(raw_ostream &o, unsigned int &i) {
180      o << "{" << "\n";
181      i += 2;
182
183      unsigned int index;
184      unsigned int numEntries = Entries.size();
185
186      unsigned int numToPrint;
187
188      if (Padding) {
189        if (numEntries > Padding) {
190          fprintf(stderr, "%u entries but %u padding\n", numEntries, Padding);
191          llvm_unreachable("More entries than padding");
192        }
193        numToPrint = Padding;
194      } else {
195        numToPrint = numEntries;
196      }
197
198      for (index = 0; index < numToPrint; ++index) {
199        o.indent(i);
200        if (index < numEntries)
201          Entries[index]->emit(o, i);
202        else
203          o << "-1";
204
205        if (index < (numToPrint - 1))
206          o << ",";
207        o << "\n";
208      }
209
210      i -= 2;
211      o.indent(i) << "}";
212    }
213  };
214
215  class FlagsConstantEmitter : public ConstantEmitter {
216  private:
217    std::vector<std::string> Flags;
218  public:
219    FlagsConstantEmitter() {
220    }
221    FlagsConstantEmitter &addEntry(const char *f) {
222      Flags.push_back(std::string(f));
223      return *this;
224    }
225    void emit(raw_ostream &o, unsigned int &i) {
226      unsigned int index;
227      unsigned int numFlags = Flags.size();
228      if (numFlags == 0)
229        o << "0";
230
231      for (index = 0; index < numFlags; ++index) {
232        o << Flags[index].c_str();
233        if (index < (numFlags - 1))
234          o << " | ";
235      }
236    }
237  };
238}
239
240EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) {
241}
242
243/// populateOperandOrder - Accepts a CodeGenInstruction and generates its
244///   AsmWriterInst for the desired assembly syntax, giving an ordered list of
245///   operands in the order they appear in the printed instruction.  Then, for
246///   each entry in that list, determines the index of the same operand in the
247///   CodeGenInstruction, and emits the resulting mapping into an array, filling
248///   in unused slots with -1.
249///
250/// @arg operandOrder - The array that will be populated with the operand
251///                     mapping.  Each entry will contain -1 (invalid index
252///                     into the operands present in the AsmString) or a number
253///                     representing an index in the operand descriptor array.
254/// @arg inst         - The instruction to use when looking up the operands
255/// @arg syntax       - The syntax to use, according to LLVM's enumeration
256void populateOperandOrder(CompoundConstantEmitter *operandOrder,
257                          const CodeGenInstruction &inst,
258                          unsigned syntax) {
259  unsigned int numArgs = 0;
260
261  AsmWriterInst awInst(inst, syntax, -1, -1);
262
263  std::vector<AsmWriterOperand>::iterator operandIterator;
264
265  for (operandIterator = awInst.Operands.begin();
266       operandIterator != awInst.Operands.end();
267       ++operandIterator) {
268    if (operandIterator->OperandType ==
269        AsmWriterOperand::isMachineInstrOperand) {
270      operandOrder->addEntry(
271        new LiteralConstantEmitter(operandIterator->CGIOpNo));
272      numArgs++;
273    }
274  }
275}
276
277/////////////////////////////////////////////////////
278// Support functions for handling X86 instructions //
279/////////////////////////////////////////////////////
280
281#define SET(flag) { type->set(flag); return 0; }
282
283#define REG(str) if (name == str) SET("kOperandTypeRegister");
284#define MEM(str) if (name == str) SET("kOperandTypeX86Memory");
285#define LEA(str) if (name == str) SET("kOperandTypeX86EffectiveAddress");
286#define IMM(str) if (name == str) SET("kOperandTypeImmediate");
287#define PCR(str) if (name == str) SET("kOperandTypeX86PCRelative");
288
289/// X86TypeFromOpName - Processes the name of a single X86 operand (which is
290///   actually its type) and translates it into an operand type
291///
292/// @arg flags    - The type object to set
293/// @arg name     - The name of the operand
294static int X86TypeFromOpName(LiteralConstantEmitter *type,
295                             const std::string &name) {
296  REG("GR8");
297  REG("GR8_NOREX");
298  REG("GR16");
299  REG("GR32");
300  REG("GR32_NOREX");
301  REG("GR32_TC");
302  REG("FR32");
303  REG("RFP32");
304  REG("GR64");
305  REG("GR64_TC");
306  REG("FR64");
307  REG("VR64");
308  REG("RFP64");
309  REG("RFP80");
310  REG("VR128");
311  REG("RST");
312  REG("SEGMENT_REG");
313  REG("DEBUG_REG");
314  REG("CONTROL_REG_32");
315  REG("CONTROL_REG_64");
316
317  IMM("i8imm");
318  IMM("i16imm");
319  IMM("i16i8imm");
320  IMM("i32imm");
321  IMM("i32imm_pcrel");
322  IMM("i32i8imm");
323  IMM("i64imm");
324  IMM("i64i8imm");
325  IMM("i64i32imm");
326  IMM("i64i32imm_pcrel");
327  IMM("SSECC");
328
329  // all R, I, R, I, R
330  MEM("i8mem");
331  MEM("i8mem_NOREX");
332  MEM("i16mem");
333  MEM("i32mem");
334  MEM("i32mem_TC");
335  MEM("f32mem");
336  MEM("ssmem");
337  MEM("opaque32mem");
338  MEM("opaque48mem");
339  MEM("i64mem");
340  MEM("i64mem_TC");
341  MEM("f64mem");
342  MEM("sdmem");
343  MEM("f80mem");
344  MEM("opaque80mem");
345  MEM("i128mem");
346  MEM("f128mem");
347  MEM("opaque512mem");
348
349  // all R, I, R, I
350  LEA("lea32mem");
351  LEA("lea64_32mem");
352  LEA("lea64mem");
353
354  // all I
355  PCR("brtarget8");
356  PCR("offset8");
357  PCR("offset16");
358  PCR("offset32");
359  PCR("offset64");
360  PCR("brtarget");
361
362  return 1;
363}
364
365#undef REG
366#undef MEM
367#undef LEA
368#undef IMM
369#undef PCR
370
371#undef SET
372
373/// X86PopulateOperands - Handles all the operands in an X86 instruction, adding
374///   the appropriate flags to their descriptors
375///
376/// @operandFlags - A reference the array of operand flag objects
377/// @inst         - The instruction to use as a source of information
378static void X86PopulateOperands(
379  LiteralConstantEmitter *(&operandTypes)[MAX_OPERANDS],
380  const CodeGenInstruction &inst) {
381  if (!inst.TheDef->isSubClassOf("X86Inst"))
382    return;
383
384  unsigned int index;
385  unsigned int numOperands = inst.OperandList.size();
386
387  for (index = 0; index < numOperands; ++index) {
388    const CodeGenInstruction::OperandInfo &operandInfo =
389      inst.OperandList[index];
390    Record &rec = *operandInfo.Rec;
391
392    if (X86TypeFromOpName(operandTypes[index], rec.getName())) {
393      errs() << "Operand type: " << rec.getName().c_str() << "\n";
394      errs() << "Operand name: " << operandInfo.Name.c_str() << "\n";
395      errs() << "Instruction mame: " << inst.TheDef->getName().c_str() << "\n";
396      llvm_unreachable("Unhandled type");
397    }
398  }
399}
400
401/// decorate1 - Decorates a named operand with a new flag
402///
403/// @operandFlags - The array of operand flag objects, which don't have names
404/// @inst         - The CodeGenInstruction, which provides a way to translate
405///                 between names and operand indices
406/// @opName       - The name of the operand
407/// @flag         - The name of the flag to add
408static inline void decorate1(
409  FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
410  const CodeGenInstruction &inst,
411  const char *opName,
412  const char *opFlag) {
413  unsigned opIndex;
414
415  opIndex = inst.getOperandNamed(std::string(opName));
416
417  operandFlags[opIndex]->addEntry(opFlag);
418}
419
420#define DECORATE1(opName, opFlag) decorate1(operandFlags, inst, opName, opFlag)
421
422#define MOV(source, target) {               \
423  instType.set("kInstructionTypeMove");     \
424  DECORATE1(source, "kOperandFlagSource");  \
425  DECORATE1(target, "kOperandFlagTarget");  \
426}
427
428#define BRANCH(target) {                    \
429  instType.set("kInstructionTypeBranch");   \
430  DECORATE1(target, "kOperandFlagTarget");  \
431}
432
433#define PUSH(source) {                      \
434  instType.set("kInstructionTypePush");     \
435  DECORATE1(source, "kOperandFlagSource");  \
436}
437
438#define POP(target) {                       \
439  instType.set("kInstructionTypePop");      \
440  DECORATE1(target, "kOperandFlagTarget");  \
441}
442
443#define CALL(target) {                      \
444  instType.set("kInstructionTypeCall");     \
445  DECORATE1(target, "kOperandFlagTarget");  \
446}
447
448#define RETURN() {                          \
449  instType.set("kInstructionTypeReturn");   \
450}
451
452/// X86ExtractSemantics - Performs various checks on the name of an X86
453///   instruction to determine what sort of an instruction it is and then adds
454///   the appropriate flags to the instruction and its operands
455///
456/// @arg instType     - A reference to the type for the instruction as a whole
457/// @arg operandFlags - A reference to the array of operand flag object pointers
458/// @arg inst         - A reference to the original instruction
459static void X86ExtractSemantics(
460  LiteralConstantEmitter &instType,
461  FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
462  const CodeGenInstruction &inst) {
463  const std::string &name = inst.TheDef->getName();
464
465  if (name.find("MOV") != name.npos) {
466    if (name.find("MOV_V") != name.npos) {
467      // ignore (this is a pseudoinstruction)
468    } else if (name.find("MASK") != name.npos) {
469      // ignore (this is a masking move)
470    } else if (name.find("r0") != name.npos) {
471      // ignore (this is a pseudoinstruction)
472    } else if (name.find("PS") != name.npos ||
473             name.find("PD") != name.npos) {
474      // ignore (this is a shuffling move)
475    } else if (name.find("MOVS") != name.npos) {
476      // ignore (this is a string move)
477    } else if (name.find("_F") != name.npos) {
478      // TODO handle _F moves to ST(0)
479    } else if (name.find("a") != name.npos) {
480      // TODO handle moves to/from %ax
481    } else if (name.find("CMOV") != name.npos) {
482      MOV("src2", "dst");
483    } else if (name.find("PC") != name.npos) {
484      MOV("label", "reg")
485    } else {
486      MOV("src", "dst");
487    }
488  }
489
490  if (name.find("JMP") != name.npos ||
491      name.find("J") == 0) {
492    if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
493      BRANCH("off");
494    } else {
495      BRANCH("dst");
496    }
497  }
498
499  if (name.find("PUSH") != name.npos) {
500    if (name.find("FS") != name.npos ||
501        name.find("GS") != name.npos) {
502      instType.set("kInstructionTypePush");
503      // TODO add support for fixed operands
504    } else if (name.find("F") != name.npos) {
505      // ignore (this pushes onto the FP stack)
506    } else if (name[name.length() - 1] == 'm') {
507      PUSH("src");
508    } else if (name.find("i") != name.npos) {
509      PUSH("imm");
510    } else {
511      PUSH("reg");
512    }
513  }
514
515  if (name.find("POP") != name.npos) {
516    if (name.find("POPCNT") != name.npos) {
517      // ignore (not a real pop)
518    } else if (name.find("FS") != name.npos ||
519             name.find("GS") != name.npos) {
520      instType.set("kInstructionTypePop");
521      // TODO add support for fixed operands
522    } else if (name.find("F") != name.npos) {
523      // ignore (this pops from the FP stack)
524    } else if (name[name.length() - 1] == 'm') {
525      POP("dst");
526    } else {
527      POP("reg");
528    }
529  }
530
531  if (name.find("CALL") != name.npos) {
532    if (name.find("ADJ") != name.npos) {
533      // ignore (not a call)
534    } else if (name.find("SYSCALL") != name.npos) {
535      // ignore (doesn't go anywhere we know about)
536    } else if (name.find("VMCALL") != name.npos) {
537      // ignore (rather different semantics than a regular call)
538    } else if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
539      CALL("off");
540    } else {
541      CALL("dst");
542    }
543  }
544
545  if (name.find("RET") != name.npos) {
546    RETURN();
547  }
548}
549
550#undef MOV
551#undef BRANCH
552#undef PUSH
553#undef POP
554#undef CALL
555#undef RETURN
556
557/////////////////////////////////////////////////////
558// Support functions for handling ARM instructions //
559/////////////////////////////////////////////////////
560
561#define SET(flag) { type->set(flag); return 0; }
562
563#define REG(str)    if (name == str) SET("kOperandTypeRegister");
564#define IMM(str)    if (name == str) SET("kOperandTypeImmediate");
565
566#define MISC(str, type)   if (name == str) SET(type);
567
568/// ARMFlagFromOpName - Processes the name of a single ARM operand (which is
569///   actually its type) and translates it into an operand type
570///
571/// @arg type     - The type object to set
572/// @arg name     - The name of the operand
573static int ARMFlagFromOpName(LiteralConstantEmitter *type,
574                             const std::string &name) {
575  REG("GPR");
576  REG("cc_out");
577  REG("s_cc_out");
578  REG("tGPR");
579  REG("DPR");
580  REG("SPR");
581  REG("QPR");
582  REG("DPR_VFP2");
583  REG("DPR_8");
584
585  IMM("i32imm");
586  IMM("bf_inv_mask_imm");
587  IMM("jtblock_operand");
588  IMM("nohash_imm");
589  IMM("cpinst_operand");
590  IMM("cps_opt");
591  IMM("vfp_f64imm");
592  IMM("vfp_f32imm");
593  IMM("msr_mask");
594  IMM("neg_zero");
595  IMM("imm0_31");
596  IMM("h8imm");
597  IMM("h16imm");
598  IMM("h32imm");
599  IMM("h64imm");
600  IMM("imm0_4095");
601  IMM("jt2block_operand");
602  IMM("t_imm_s4");
603  IMM("pclabel");
604
605  MISC("brtarget", "kOperandTypeARMBranchTarget");                // ?
606  MISC("so_reg", "kOperandTypeARMSoReg");                         // R, R, I
607  MISC("t2_so_reg", "kOperandTypeThumb2SoReg");                   // R, I
608  MISC("so_imm", "kOperandTypeARMSoImm");                         // I
609  MISC("t2_so_imm", "kOperandTypeThumb2SoImm");                   // I
610  MISC("so_imm2part", "kOperandTypeARMSoImm2Part");               // I
611  MISC("pred", "kOperandTypeARMPredicate");                       // I, R
612  MISC("it_pred", "kOperandTypeARMPredicate");                    // I
613  MISC("addrmode2", "kOperandTypeARMAddrMode2");                  // R, R, I
614  MISC("am2offset", "kOperandTypeARMAddrMode2Offset");            // R, I
615  MISC("addrmode3", "kOperandTypeARMAddrMode3");                  // R, R, I
616  MISC("am3offset", "kOperandTypeARMAddrMode3Offset");            // R, I
617  MISC("addrmode4", "kOperandTypeARMAddrMode4");                  // R, I
618  MISC("addrmode5", "kOperandTypeARMAddrMode5");                  // R, I
619  MISC("addrmode6", "kOperandTypeARMAddrMode6");                  // R, R, I, I
620  MISC("am6offset", "kOperandTypeARMAddrMode6Offset");            // R, I, I
621  MISC("addrmodepc", "kOperandTypeARMAddrModePC");                // R, I
622  MISC("reglist", "kOperandTypeARMRegisterList");                 // I, R, ...
623  MISC("it_mask", "kOperandTypeThumbITMask");                     // I
624  MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8");      // R, I
625  MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I
626  MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12");    // R, I
627  MISC("t2addrmode_so_reg", "kOperandTypeThumb2AddrModeSoReg");   // R, R, I
628  MISC("t2addrmode_imm8s4", "kOperandTypeThumb2AddrModeImm8s4");  // R, I
629  MISC("t2am_imm8s4_offset", "kOperandTypeThumb2AddrModeImm8s4Offset");
630                                                                  // R, I
631  MISC("tb_addrmode", "kOperandTypeARMTBAddrMode");               // I
632  MISC("t_addrmode_s1", "kOperandTypeThumbAddrModeS1");           // R, I, R
633  MISC("t_addrmode_s2", "kOperandTypeThumbAddrModeS2");           // R, I, R
634  MISC("t_addrmode_s4", "kOperandTypeThumbAddrModeS4");           // R, I, R
635  MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR");           // R, R
636  MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP");           // R, I
637
638  return 1;
639}
640
641#undef SOREG
642#undef SOIMM
643#undef PRED
644#undef REG
645#undef MEM
646#undef LEA
647#undef IMM
648#undef PCR
649
650#undef SET
651
652/// ARMPopulateOperands - Handles all the operands in an ARM instruction, adding
653///   the appropriate flags to their descriptors
654///
655/// @operandFlags - A reference the array of operand flag objects
656/// @inst         - The instruction to use as a source of information
657static void ARMPopulateOperands(
658  LiteralConstantEmitter *(&operandTypes)[MAX_OPERANDS],
659  const CodeGenInstruction &inst) {
660  if (!inst.TheDef->isSubClassOf("InstARM") &&
661      !inst.TheDef->isSubClassOf("InstThumb"))
662    return;
663
664  unsigned int index;
665  unsigned int numOperands = inst.OperandList.size();
666
667  if (numOperands > MAX_OPERANDS) {
668    errs() << "numOperands == " << numOperands << " > " << MAX_OPERANDS << '\n';
669    llvm_unreachable("Too many operands");
670  }
671
672  for (index = 0; index < numOperands; ++index) {
673    const CodeGenInstruction::OperandInfo &operandInfo =
674    inst.OperandList[index];
675    Record &rec = *operandInfo.Rec;
676
677    if (ARMFlagFromOpName(operandTypes[index], rec.getName())) {
678      errs() << "Operand type: " << rec.getName() << '\n';
679      errs() << "Operand name: " << operandInfo.Name << '\n';
680      errs() << "Instruction mame: " << inst.TheDef->getName() << '\n';
681      llvm_unreachable("Unhandled type");
682    }
683  }
684}
685
686#define BRANCH(target) {                    \
687  instType.set("kInstructionTypeBranch");   \
688  DECORATE1(target, "kOperandFlagTarget");  \
689}
690
691/// ARMExtractSemantics - Performs various checks on the name of an ARM
692///   instruction to determine what sort of an instruction it is and then adds
693///   the appropriate flags to the instruction and its operands
694///
695/// @arg instType     - A reference to the type for the instruction as a whole
696/// @arg operandTypes - A reference to the array of operand type object pointers
697/// @arg operandFlags - A reference to the array of operand flag object pointers
698/// @arg inst         - A reference to the original instruction
699static void ARMExtractSemantics(
700  LiteralConstantEmitter &instType,
701  LiteralConstantEmitter *(&operandTypes)[MAX_OPERANDS],
702  FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
703  const CodeGenInstruction &inst) {
704  const std::string &name = inst.TheDef->getName();
705
706  if (name == "tBcc"   ||
707      name == "tB"     ||
708      name == "t2Bcc"  ||
709      name == "Bcc"    ||
710      name == "tCBZ"   ||
711      name == "tCBNZ") {
712    BRANCH("target");
713  }
714
715  if (name == "tBLr9"      ||
716      name == "BLr9_pred"  ||
717      name == "tBLXi_r9"   ||
718      name == "tBLXr_r9"   ||
719      name == "BLXr9"      ||
720      name == "t2BXJ"      ||
721      name == "BXJ") {
722    BRANCH("func");
723
724    unsigned opIndex;
725    opIndex = inst.getOperandNamed("func");
726    if (operandTypes[opIndex]->is("kOperandTypeImmediate"))
727      operandTypes[opIndex]->set("kOperandTypeARMBranchTarget");
728  }
729}
730
731#undef BRANCH
732
733/// populateInstInfo - Fills an array of InstInfos with information about each
734///   instruction in a target
735///
736/// @arg infoArray  - The array of InstInfo objects to populate
737/// @arg target     - The CodeGenTarget to use as a source of instructions
738static void populateInstInfo(CompoundConstantEmitter &infoArray,
739                             CodeGenTarget &target) {
740  const std::vector<const CodeGenInstruction*> &numberedInstructions =
741    target.getInstructionsByEnumValue();
742
743  unsigned int index;
744  unsigned int numInstructions = numberedInstructions.size();
745
746  for (index = 0; index < numInstructions; ++index) {
747    const CodeGenInstruction& inst = *numberedInstructions[index];
748
749    CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter;
750    infoArray.addEntry(infoStruct);
751
752    LiteralConstantEmitter *instType = new LiteralConstantEmitter;
753    infoStruct->addEntry(instType);
754
755    LiteralConstantEmitter *numOperandsEmitter =
756      new LiteralConstantEmitter(inst.OperandList.size());
757    infoStruct->addEntry(numOperandsEmitter);
758
759    CompoundConstantEmitter *operandTypeArray = new CompoundConstantEmitter;
760    infoStruct->addEntry(operandTypeArray);
761
762    LiteralConstantEmitter *operandTypes[MAX_OPERANDS];
763
764    CompoundConstantEmitter *operandFlagArray = new CompoundConstantEmitter;
765    infoStruct->addEntry(operandFlagArray);
766
767    FlagsConstantEmitter *operandFlags[MAX_OPERANDS];
768
769    for (unsigned operandIndex = 0;
770         operandIndex < MAX_OPERANDS;
771         ++operandIndex) {
772      operandTypes[operandIndex] = new LiteralConstantEmitter;
773      operandTypeArray->addEntry(operandTypes[operandIndex]);
774
775      operandFlags[operandIndex] = new FlagsConstantEmitter;
776      operandFlagArray->addEntry(operandFlags[operandIndex]);
777    }
778
779    unsigned numSyntaxes = 0;
780
781    if (target.getName() == "X86") {
782      X86PopulateOperands(operandTypes, inst);
783      X86ExtractSemantics(*instType, operandFlags, inst);
784      numSyntaxes = 2;
785    }
786    else if (target.getName() == "ARM") {
787      ARMPopulateOperands(operandTypes, inst);
788      ARMExtractSemantics(*instType, operandTypes, operandFlags, inst);
789      numSyntaxes = 1;
790    }
791
792    CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter;
793
794    infoStruct->addEntry(operandOrderArray);
795
796    for (unsigned syntaxIndex = 0; syntaxIndex < MAX_SYNTAXES; ++syntaxIndex) {
797      CompoundConstantEmitter *operandOrder =
798        new CompoundConstantEmitter(MAX_OPERANDS);
799
800      operandOrderArray->addEntry(operandOrder);
801
802      if (syntaxIndex < numSyntaxes) {
803        populateOperandOrder(operandOrder, inst, syntaxIndex);
804      }
805    }
806
807    infoStruct = NULL;
808  }
809}
810
811void EDEmitter::run(raw_ostream &o) {
812  unsigned int i = 0;
813
814  CompoundConstantEmitter infoArray;
815  CodeGenTarget target;
816
817  populateInstInfo(infoArray, target);
818
819  o << "InstInfo instInfo" << target.getName().c_str() << "[] = ";
820  infoArray.emit(o, i);
821  o << ";" << "\n";
822}
823
824void EDEmitter::runHeader(raw_ostream &o) {
825  EmitSourceFileHeader("Enhanced Disassembly Info Header", o);
826
827  o << "#ifndef EDInfo_" << "\n";
828  o << "#define EDInfo_" << "\n";
829  o << "\n";
830  o << "#include <inttypes.h>" << "\n";
831  o << "\n";
832  o << "#define MAX_OPERANDS " << format("%d", MAX_OPERANDS) << "\n";
833  o << "#define MAX_SYNTAXES " << format("%d", MAX_SYNTAXES) << "\n";
834  o << "\n";
835
836  unsigned int i = 0;
837
838  EnumEmitter operandTypes("OperandTypes");
839  operandTypes.addEntry("kOperandTypeNone");
840  operandTypes.addEntry("kOperandTypeImmediate");
841  operandTypes.addEntry("kOperandTypeRegister");
842  operandTypes.addEntry("kOperandTypeX86Memory");
843  operandTypes.addEntry("kOperandTypeX86EffectiveAddress");
844  operandTypes.addEntry("kOperandTypeX86PCRelative");
845  operandTypes.addEntry("kOperandTypeARMBranchTarget");
846  operandTypes.addEntry("kOperandTypeARMSoReg");
847  operandTypes.addEntry("kOperandTypeARMSoImm");
848  operandTypes.addEntry("kOperandTypeARMSoImm2Part");
849  operandTypes.addEntry("kOperandTypeARMPredicate");
850  operandTypes.addEntry("kOperandTypeARMAddrMode2");
851  operandTypes.addEntry("kOperandTypeARMAddrMode2Offset");
852  operandTypes.addEntry("kOperandTypeARMAddrMode3");
853  operandTypes.addEntry("kOperandTypeARMAddrMode3Offset");
854  operandTypes.addEntry("kOperandTypeARMAddrMode4");
855  operandTypes.addEntry("kOperandTypeARMAddrMode5");
856  operandTypes.addEntry("kOperandTypeARMAddrMode6");
857  operandTypes.addEntry("kOperandTypeARMAddrMode6Offset");
858  operandTypes.addEntry("kOperandTypeARMAddrModePC");
859  operandTypes.addEntry("kOperandTypeARMRegisterList");
860  operandTypes.addEntry("kOperandTypeARMTBAddrMode");
861  operandTypes.addEntry("kOperandTypeThumbITMask");
862  operandTypes.addEntry("kOperandTypeThumbAddrModeS1");
863  operandTypes.addEntry("kOperandTypeThumbAddrModeS2");
864  operandTypes.addEntry("kOperandTypeThumbAddrModeS4");
865  operandTypes.addEntry("kOperandTypeThumbAddrModeRR");
866  operandTypes.addEntry("kOperandTypeThumbAddrModeSP");
867  operandTypes.addEntry("kOperandTypeThumb2SoReg");
868  operandTypes.addEntry("kOperandTypeThumb2SoImm");
869  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8");
870  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8Offset");
871  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm12");
872  operandTypes.addEntry("kOperandTypeThumb2AddrModeSoReg");
873  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4");
874  operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4Offset");
875
876  operandTypes.emit(o, i);
877
878  o << "\n";
879
880  EnumEmitter operandFlags("OperandFlags");
881  operandFlags.addEntry("kOperandFlagSource");
882  operandFlags.addEntry("kOperandFlagTarget");
883  operandFlags.emitAsFlags(o, i);
884
885  o << "\n";
886
887  EnumEmitter instructionTypes("InstructionTypes");
888  instructionTypes.addEntry("kInstructionTypeNone");
889  instructionTypes.addEntry("kInstructionTypeMove");
890  instructionTypes.addEntry("kInstructionTypeBranch");
891  instructionTypes.addEntry("kInstructionTypePush");
892  instructionTypes.addEntry("kInstructionTypePop");
893  instructionTypes.addEntry("kInstructionTypeCall");
894  instructionTypes.addEntry("kInstructionTypeReturn");
895  instructionTypes.emit(o, i);
896
897  o << "\n";
898
899  StructEmitter instInfo("InstInfo");
900  instInfo.addMember("uint8_t", "instructionType");
901  instInfo.addMember("uint8_t", "numOperands");
902  instInfo.addMember("uint8_t", "operandTypes[MAX_OPERANDS]");
903  instInfo.addMember("uint8_t", "operandFlags[MAX_OPERANDS]");
904  instInfo.addMember("const char", "operandOrders[MAX_SYNTAXES][MAX_OPERANDS]");
905  instInfo.emit(o, i);
906
907  o << "\n";
908  o << "#endif" << "\n";
909}
910