~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/utils/TableGen/EDEmitter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <vector>
 
27
#include <string>
 
28
 
 
29
#define MAX_OPERANDS 5
 
30
#define MAX_SYNTAXES 2
 
31
 
 
32
using namespace llvm;
 
33
 
 
34
///////////////////////////////////////////////////////////
 
35
// Support classes for emitting nested C data structures //
 
36
///////////////////////////////////////////////////////////
 
37
 
 
38
namespace {
 
39
  
 
40
  class EnumEmitter {
 
41
  private:
 
42
    std::string Name;
 
43
    std::vector<std::string> Entries;
 
44
  public:
 
45
    EnumEmitter(const char *N) : Name(N) { 
 
46
    }
 
47
    int addEntry(const char *e) { 
 
48
      Entries.push_back(std::string(e));
 
49
      return Entries.size() - 1; 
 
50
    }
 
51
    void emit(raw_ostream &o, unsigned int &i) {
 
52
      o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
 
53
      i += 2;
 
54
      
 
55
      unsigned int index = 0;
 
56
      unsigned int numEntries = Entries.size();
 
57
      for(index = 0; index < numEntries; ++index) {
 
58
        o.indent(i) << Entries[index];
 
59
        if(index < (numEntries - 1))
 
60
          o << ",";
 
61
        o << "\n";
 
62
      }
 
63
      
 
64
      i -= 2;
 
65
      o.indent(i) << "};" << "\n";
 
66
    }
 
67
    
 
68
    void emitAsFlags(raw_ostream &o, unsigned int &i) {
 
69
      o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
 
70
      i += 2;
 
71
      
 
72
      unsigned int index = 0;
 
73
      unsigned int numEntries = Entries.size();
 
74
      unsigned int flag = 1;
 
75
      for (index = 0; index < numEntries; ++index) {
 
76
        o.indent(i) << Entries[index] << " = " << format("0x%x", flag);
 
77
        if (index < (numEntries - 1))
 
78
          o << ",";
 
79
        o << "\n";
 
80
        flag <<= 1;
 
81
      }
 
82
      
 
83
      i -= 2;
 
84
      o.indent(i) << "};" << "\n";
 
85
    }
 
86
  };
 
87
 
 
88
  class StructEmitter {
 
89
  private:
 
90
    std::string Name;
 
91
    std::vector<std::string> MemberTypes;
 
92
    std::vector<std::string> MemberNames;
 
93
  public:
 
94
    StructEmitter(const char *N) : Name(N) {
 
95
    }
 
96
    void addMember(const char *t, const char *n) {
 
97
      MemberTypes.push_back(std::string(t));
 
98
      MemberNames.push_back(std::string(n));
 
99
    }
 
100
    void emit(raw_ostream &o, unsigned int &i) {
 
101
      o.indent(i) << "struct " << Name.c_str() << " {" << "\n";
 
102
      i += 2;
 
103
      
 
104
      unsigned int index = 0;
 
105
      unsigned int numMembers = MemberTypes.size();
 
106
      for (index = 0; index < numMembers; ++index) {
 
107
        o.indent(i) << MemberTypes[index] << " " << MemberNames[index] << ";";
 
108
        o << "\n";
 
109
      }
 
110
      
 
111
      i -= 2;
 
112
      o.indent(i) << "};" << "\n";
 
113
    }
 
114
  };
 
115
  
 
116
  class ConstantEmitter {
 
117
  public:
 
118
    virtual ~ConstantEmitter() { }
 
119
    virtual void emit(raw_ostream &o, unsigned int &i) = 0;
 
120
  };
 
121
  
 
122
  class LiteralConstantEmitter : public ConstantEmitter {
 
123
  private:
 
124
    std::string Literal;
 
125
  public:
 
126
    LiteralConstantEmitter(const char *literal) : Literal(literal) {
 
127
    }
 
128
    LiteralConstantEmitter(int literal) {
 
129
      char buf[256];
 
130
      snprintf(buf, 256, "%d", literal);
 
131
      Literal = buf;
 
132
    }
 
133
    void emit(raw_ostream &o, unsigned int &i) {
 
134
      o << Literal;
 
135
    }
 
136
  };
 
137
  
 
138
  class CompoundConstantEmitter : public ConstantEmitter {
 
139
  private:
 
140
    std::vector<ConstantEmitter*> Entries;
 
141
  public:
 
142
    CompoundConstantEmitter() {
 
143
    }
 
144
    ~CompoundConstantEmitter() {
 
145
      unsigned int index;
 
146
      unsigned int numEntries = Entries.size();
 
147
      for (index = 0; index < numEntries; ++index) {
 
148
        delete Entries[index];
 
149
      }
 
150
    }
 
151
    CompoundConstantEmitter &addEntry(ConstantEmitter *e) {
 
152
      Entries.push_back(e);
 
153
      return *this;
 
154
    }
 
155
    void emit(raw_ostream &o, unsigned int &i) {
 
156
      o << "{" << "\n";
 
157
      i += 2;
 
158
  
 
159
      unsigned int index;
 
160
      unsigned int numEntries = Entries.size();
 
161
      for (index = 0; index < numEntries; ++index) {
 
162
        o.indent(i);
 
163
        Entries[index]->emit(o, i);
 
164
        if (index < (numEntries - 1))
 
165
          o << ",";
 
166
        o << "\n";
 
167
      }
 
168
      
 
169
      i -= 2;
 
170
      o.indent(i) << "}";
 
171
    }
 
172
  };
 
173
  
 
174
  class FlagsConstantEmitter : public ConstantEmitter {
 
175
  private:
 
176
    std::vector<std::string> Flags;
 
177
  public:
 
178
    FlagsConstantEmitter() {
 
179
    }
 
180
    FlagsConstantEmitter &addEntry(const char *f) {
 
181
      Flags.push_back(std::string(f));
 
182
      return *this;
 
183
    }
 
184
    void emit(raw_ostream &o, unsigned int &i) {
 
185
      unsigned int index;
 
186
      unsigned int numFlags = Flags.size();
 
187
      if (numFlags == 0)
 
188
        o << "0";
 
189
      
 
190
      for (index = 0; index < numFlags; ++index) {
 
191
        o << Flags[index].c_str();
 
192
        if (index < (numFlags - 1))
 
193
          o << " | ";
 
194
      }
 
195
    }
 
196
  };
 
197
}
 
198
 
 
199
EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) {
 
200
}
 
201
 
 
202
/// populateOperandOrder - Accepts a CodeGenInstruction and generates its
 
203
///   AsmWriterInst for the desired assembly syntax, giving an ordered list of
 
204
///   operands in the order they appear in the printed instruction.  Then, for
 
205
///   each entry in that list, determines the index of the same operand in the
 
206
///   CodeGenInstruction, and emits the resulting mapping into an array, filling
 
207
///   in unused slots with -1.
 
208
///
 
209
/// @arg operandOrder - The array that will be populated with the operand
 
210
///                     mapping.  Each entry will contain -1 (invalid index
 
211
///                     into the operands present in the AsmString) or a number
 
212
///                     representing an index in the operand descriptor array.
 
213
/// @arg inst         - The instruction to use when looking up the operands
 
214
/// @arg syntax       - The syntax to use, according to LLVM's enumeration
 
215
void populateOperandOrder(CompoundConstantEmitter *operandOrder,
 
216
                          const CodeGenInstruction &inst,
 
217
                          unsigned syntax) {
 
218
  unsigned int numArgs = 0;
 
219
  
 
220
  AsmWriterInst awInst(inst, syntax, -1, -1);
 
221
  
 
222
  std::vector<AsmWriterOperand>::iterator operandIterator;
 
223
  
 
224
  for (operandIterator = awInst.Operands.begin();
 
225
       operandIterator != awInst.Operands.end();
 
226
       ++operandIterator) {
 
227
    if (operandIterator->OperandType == 
 
228
        AsmWriterOperand::isMachineInstrOperand) {
 
229
      char buf[2];
 
230
      snprintf(buf, sizeof(buf), "%u", operandIterator->CGIOpNo);
 
231
      operandOrder->addEntry(new LiteralConstantEmitter(buf));
 
232
      numArgs++;
 
233
    }
 
234
  }
 
235
  
 
236
  for(; numArgs < MAX_OPERANDS; numArgs++) {
 
237
    operandOrder->addEntry(new LiteralConstantEmitter("-1"));
 
238
  }
 
239
}
 
240
 
 
241
/////////////////////////////////////////////////////
 
242
// Support functions for handling X86 instructions //
 
243
/////////////////////////////////////////////////////
 
244
 
 
245
#define ADDFLAG(flag) flags->addEntry(flag)
 
246
 
 
247
#define REG(str) if (name == str) { ADDFLAG("kOperandFlagRegister"); return 0; }
 
248
#define MEM(str) if (name == str) { ADDFLAG("kOperandFlagMemory"); return 0; }
 
249
#define LEA(str) if (name == str) { ADDFLAG("kOperandFlagEffectiveAddress"); \
 
250
                                    return 0; }
 
251
#define IMM(str) if (name == str) { ADDFLAG("kOperandFlagImmediate"); \
 
252
                                    return 0; }
 
253
#define PCR(str) if (name == str) { ADDFLAG("kOperandFlagMemory"); \
 
254
                                    ADDFLAG("kOperandFlagPCRelative"); \
 
255
                                    return 0; }
 
256
 
 
257
/// X86FlagFromOpName - Processes the name of a single X86 operand (which is
 
258
///   actually its type) and translates it into an operand flag
 
259
///
 
260
/// @arg flags    - The flags object to add the flag to
 
261
/// @arg name     - The name of the operand
 
262
static int X86FlagFromOpName(FlagsConstantEmitter *flags,
 
263
                             const std::string &name) {
 
264
  REG("GR8");
 
265
  REG("GR8_NOREX");
 
266
  REG("GR16");
 
267
  REG("GR32");
 
268
  REG("GR32_NOREX");
 
269
  REG("FR32");
 
270
  REG("RFP32");
 
271
  REG("GR64");
 
272
  REG("FR64");
 
273
  REG("VR64");
 
274
  REG("RFP64");
 
275
  REG("RFP80");
 
276
  REG("VR128");
 
277
  REG("RST");
 
278
  REG("SEGMENT_REG");
 
279
  REG("DEBUG_REG");
 
280
  REG("CONTROL_REG_32");
 
281
  REG("CONTROL_REG_64");
 
282
  
 
283
  MEM("i8mem");
 
284
  MEM("i8mem_NOREX");
 
285
  MEM("i16mem");
 
286
  MEM("i32mem");
 
287
  MEM("f32mem");
 
288
  MEM("ssmem");
 
289
  MEM("opaque32mem");
 
290
  MEM("opaque48mem");
 
291
  MEM("i64mem");
 
292
  MEM("f64mem");
 
293
  MEM("sdmem");
 
294
  MEM("f80mem");
 
295
  MEM("opaque80mem");
 
296
  MEM("i128mem");
 
297
  MEM("f128mem");
 
298
  MEM("opaque512mem");
 
299
  
 
300
  LEA("lea32mem");
 
301
  LEA("lea64_32mem");
 
302
  LEA("lea64mem");
 
303
  
 
304
  IMM("i8imm");
 
305
  IMM("i16imm");
 
306
  IMM("i16i8imm");
 
307
  IMM("i32imm");
 
308
  IMM("i32imm_pcrel");
 
309
  IMM("i32i8imm");
 
310
  IMM("i64imm");
 
311
  IMM("i64i8imm");
 
312
  IMM("i64i32imm");
 
313
  IMM("i64i32imm_pcrel");
 
314
  IMM("SSECC");
 
315
  
 
316
  PCR("brtarget8");
 
317
  PCR("offset8");
 
318
  PCR("offset16");
 
319
  PCR("offset32");
 
320
  PCR("offset64");
 
321
  PCR("brtarget");
 
322
  
 
323
  return 1;
 
324
}
 
325
 
 
326
#undef REG
 
327
#undef MEM
 
328
#undef LEA
 
329
#undef IMM
 
330
#undef PCR
 
331
#undef ADDFLAG
 
332
 
 
333
/// X86PopulateOperands - Handles all the operands in an X86 instruction, adding
 
334
///   the appropriate flags to their descriptors
 
335
///
 
336
/// @operandFlags - A reference the array of operand flag objects
 
337
/// @inst         - The instruction to use as a source of information
 
338
static void X86PopulateOperands(
 
339
  FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
 
340
  const CodeGenInstruction &inst) {
 
341
  if (!inst.TheDef->isSubClassOf("X86Inst"))
 
342
    return;
 
343
  
 
344
  unsigned int index;
 
345
  unsigned int numOperands = inst.OperandList.size();
 
346
  
 
347
  for (index = 0; index < numOperands; ++index) {
 
348
    const CodeGenInstruction::OperandInfo &operandInfo = 
 
349
      inst.OperandList[index];
 
350
    Record &rec = *operandInfo.Rec;
 
351
    
 
352
    if (X86FlagFromOpName(operandFlags[index], rec.getName())) {
 
353
      errs() << "Operand type: " << rec.getName().c_str() << "\n";
 
354
      errs() << "Operand name: " << operandInfo.Name.c_str() << "\n";
 
355
      errs() << "Instruction mame: " << inst.TheDef->getName().c_str() << "\n";
 
356
      llvm_unreachable("Unhandled type");
 
357
    }
 
358
  }
 
359
}
 
360
 
 
361
/// decorate1 - Decorates a named operand with a new flag
 
362
///
 
363
/// @operandFlags - The array of operand flag objects, which don't have names
 
364
/// @inst         - The CodeGenInstruction, which provides a way to translate
 
365
///                 between names and operand indices
 
366
/// @opName       - The name of the operand
 
367
/// @flag         - The name of the flag to add
 
368
static inline void decorate1(FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
 
369
                             const CodeGenInstruction &inst,
 
370
                             const char *opName,
 
371
                             const char *opFlag) {
 
372
  unsigned opIndex;
 
373
  
 
374
  opIndex = inst.getOperandNamed(std::string(opName));
 
375
  
 
376
  operandFlags[opIndex]->addEntry(opFlag);
 
377
}
 
378
 
 
379
#define DECORATE1(opName, opFlag) decorate1(operandFlags, inst, opName, opFlag)
 
380
 
 
381
#define MOV(source, target) {                       \
 
382
  instFlags.addEntry("kInstructionFlagMove");       \
 
383
  DECORATE1(source, "kOperandFlagSource");          \
 
384
  DECORATE1(target, "kOperandFlagTarget");          \
 
385
}
 
386
 
 
387
#define BRANCH(target) {                            \
 
388
  instFlags.addEntry("kInstructionFlagBranch");     \
 
389
  DECORATE1(target, "kOperandFlagTarget");          \
 
390
}
 
391
 
 
392
#define PUSH(source) {                              \
 
393
  instFlags.addEntry("kInstructionFlagPush");       \
 
394
  DECORATE1(source, "kOperandFlagSource");          \
 
395
}
 
396
 
 
397
#define POP(target) {                               \
 
398
  instFlags.addEntry("kInstructionFlagPop");        \
 
399
  DECORATE1(target, "kOperandFlagTarget");          \
 
400
}
 
401
 
 
402
#define CALL(target) {                              \
 
403
  instFlags.addEntry("kInstructionFlagCall");       \
 
404
  DECORATE1(target, "kOperandFlagTarget");          \
 
405
}
 
406
 
 
407
#define RETURN() {                                  \
 
408
  instFlags.addEntry("kInstructionFlagReturn");     \
 
409
}
 
410
 
 
411
/// X86ExtractSemantics - Performs various checks on the name of an X86
 
412
///   instruction to determine what sort of an instruction it is and then adds 
 
413
///   the appropriate flags to the instruction and its operands
 
414
///
 
415
/// @arg instFlags    - A reference to the flags for the instruction as a whole
 
416
/// @arg operandFlags - A reference to the array of operand flag object pointers
 
417
/// @arg inst         - A reference to the original instruction
 
418
static void X86ExtractSemantics(FlagsConstantEmitter &instFlags,
 
419
                                FlagsConstantEmitter *(&operandFlags)[MAX_OPERANDS],
 
420
                                const CodeGenInstruction &inst) {
 
421
  const std::string &name = inst.TheDef->getName();
 
422
    
 
423
  if (name.find("MOV") != name.npos) {
 
424
    if (name.find("MOV_V") != name.npos) {
 
425
      // ignore (this is a pseudoinstruction)
 
426
    }
 
427
    else if (name.find("MASK") != name.npos) {
 
428
      // ignore (this is a masking move)
 
429
    }
 
430
    else if (name.find("r0") != name.npos) {
 
431
      // ignore (this is a pseudoinstruction)
 
432
    }
 
433
    else if (name.find("PS") != name.npos ||
 
434
             name.find("PD") != name.npos) {
 
435
      // ignore (this is a shuffling move)
 
436
    }
 
437
    else if (name.find("MOVS") != name.npos) {
 
438
      // ignore (this is a string move)
 
439
    }
 
440
    else if (name.find("_F") != name.npos) {
 
441
      // TODO handle _F moves to ST(0)
 
442
    }
 
443
    else if (name.find("a") != name.npos) {
 
444
      // TODO handle moves to/from %ax
 
445
    }
 
446
    else if (name.find("CMOV") != name.npos) {
 
447
      MOV("src2", "dst");
 
448
    }
 
449
    else if (name.find("PC") != name.npos) {
 
450
      MOV("label", "reg")
 
451
    }
 
452
    else {
 
453
      MOV("src", "dst");
 
454
    }
 
455
  }
 
456
  
 
457
  if (name.find("JMP") != name.npos ||
 
458
      name.find("J") == 0) {
 
459
    if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
 
460
      BRANCH("off");
 
461
    }
 
462
    else {
 
463
      BRANCH("dst");
 
464
    }
 
465
  }
 
466
  
 
467
  if (name.find("PUSH") != name.npos) {
 
468
    if (name.find("FS") != name.npos ||
 
469
        name.find("GS") != name.npos) {
 
470
      instFlags.addEntry("kInstructionFlagPush");
 
471
      // TODO add support for fixed operands
 
472
    }
 
473
    else if (name.find("F") != name.npos) {
 
474
      // ignore (this pushes onto the FP stack)
 
475
    }
 
476
    else if (name[name.length() - 1] == 'm') {
 
477
      PUSH("src");
 
478
    }
 
479
    else if (name.find("i") != name.npos) {
 
480
      PUSH("imm");
 
481
    }
 
482
    else {
 
483
      PUSH("reg");
 
484
    }
 
485
  }
 
486
  
 
487
  if (name.find("POP") != name.npos) {
 
488
    if (name.find("POPCNT") != name.npos) {
 
489
      // ignore (not a real pop)
 
490
    }
 
491
    else if (name.find("FS") != name.npos ||
 
492
             name.find("GS") != name.npos) {
 
493
      instFlags.addEntry("kInstructionFlagPop");
 
494
      // TODO add support for fixed operands
 
495
    }
 
496
    else if (name.find("F") != name.npos) {
 
497
      // ignore (this pops from the FP stack)
 
498
    }
 
499
    else if (name[name.length() - 1] == 'm') {
 
500
      POP("dst");
 
501
    }
 
502
    else {
 
503
      POP("reg");
 
504
    }
 
505
  }
 
506
  
 
507
  if (name.find("CALL") != name.npos) {
 
508
    if (name.find("ADJ") != name.npos) {
 
509
      // ignore (not a call)
 
510
    }
 
511
    else if (name.find("SYSCALL") != name.npos) {
 
512
      // ignore (doesn't go anywhere we know about)
 
513
    }
 
514
    else if (name.find("VMCALL") != name.npos) {
 
515
      // ignore (rather different semantics than a regular call)
 
516
    }
 
517
    else if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
 
518
      CALL("off");
 
519
    }
 
520
    else {
 
521
      CALL("dst");
 
522
    }
 
523
  }
 
524
  
 
525
  if (name.find("RET") != name.npos) {
 
526
    RETURN();
 
527
  }
 
528
}
 
529
 
 
530
#undef MOV
 
531
#undef BRANCH
 
532
#undef PUSH
 
533
#undef POP
 
534
#undef CALL
 
535
#undef RETURN
 
536
 
 
537
#undef COND_DECORATE_2
 
538
#undef COND_DECORATE_1
 
539
#undef DECORATE1
 
540
 
 
541
/// populateInstInfo - Fills an array of InstInfos with information about each 
 
542
///   instruction in a target
 
543
///
 
544
/// @arg infoArray  - The array of InstInfo objects to populate
 
545
/// @arg target     - The CodeGenTarget to use as a source of instructions
 
546
static void populateInstInfo(CompoundConstantEmitter &infoArray,
 
547
                             CodeGenTarget &target) {
 
548
  std::vector<const CodeGenInstruction*> numberedInstructions;
 
549
  target.getInstructionsByEnumValue(numberedInstructions);
 
550
  
 
551
  unsigned int index;
 
552
  unsigned int numInstructions = numberedInstructions.size();
 
553
  
 
554
  for (index = 0; index < numInstructions; ++index) {
 
555
    const CodeGenInstruction& inst = *numberedInstructions[index];
 
556
    
 
557
    CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter;
 
558
    infoArray.addEntry(infoStruct);
 
559
    
 
560
    FlagsConstantEmitter *instFlags = new FlagsConstantEmitter;
 
561
    infoStruct->addEntry(instFlags);
 
562
    
 
563
    LiteralConstantEmitter *numOperandsEmitter = 
 
564
      new LiteralConstantEmitter(inst.OperandList.size());
 
565
    infoStruct->addEntry(numOperandsEmitter);
 
566
                         
 
567
    CompoundConstantEmitter *operandFlagArray = new CompoundConstantEmitter;
 
568
    infoStruct->addEntry(operandFlagArray);
 
569
        
 
570
    FlagsConstantEmitter *operandFlags[MAX_OPERANDS];
 
571
    
 
572
    for (unsigned operandIndex = 0; operandIndex < MAX_OPERANDS; ++operandIndex) {
 
573
      operandFlags[operandIndex] = new FlagsConstantEmitter;
 
574
      operandFlagArray->addEntry(operandFlags[operandIndex]);
 
575
    }
 
576
 
 
577
    unsigned numSyntaxes = 0;
 
578
    
 
579
    if (target.getName() == "X86") {
 
580
      X86PopulateOperands(operandFlags, inst);
 
581
      X86ExtractSemantics(*instFlags, operandFlags, inst);
 
582
      numSyntaxes = 2;
 
583
    }
 
584
    
 
585
    CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter;
 
586
    infoStruct->addEntry(operandOrderArray);
 
587
    
 
588
    for (unsigned syntaxIndex = 0; syntaxIndex < MAX_SYNTAXES; ++syntaxIndex) {
 
589
      CompoundConstantEmitter *operandOrder = new CompoundConstantEmitter;
 
590
      operandOrderArray->addEntry(operandOrder);
 
591
      
 
592
      if (syntaxIndex < numSyntaxes) {
 
593
        populateOperandOrder(operandOrder, inst, syntaxIndex);
 
594
      }
 
595
      else {
 
596
        for (unsigned operandIndex = 0; 
 
597
             operandIndex < MAX_OPERANDS; 
 
598
             ++operandIndex) {
 
599
          operandOrder->addEntry(new LiteralConstantEmitter("-1"));
 
600
        }
 
601
      }
 
602
    }
 
603
  }
 
604
}
 
605
 
 
606
void EDEmitter::run(raw_ostream &o) {
 
607
  unsigned int i = 0;
 
608
  
 
609
  CompoundConstantEmitter infoArray;
 
610
  CodeGenTarget target;
 
611
  
 
612
  populateInstInfo(infoArray, target);
 
613
  
 
614
  o << "InstInfo instInfo" << target.getName().c_str() << "[] = ";
 
615
  infoArray.emit(o, i);
 
616
  o << ";" << "\n";
 
617
}
 
618
 
 
619
void EDEmitter::runHeader(raw_ostream &o) {
 
620
  EmitSourceFileHeader("Enhanced Disassembly Info Header", o);
 
621
  
 
622
  o << "#ifndef EDInfo_" << "\n";
 
623
  o << "#define EDInfo_" << "\n";
 
624
  o << "\n";
 
625
  o << "#include <inttypes.h>" << "\n";
 
626
  o << "\n";
 
627
  o << "#define MAX_OPERANDS " << format("%d", MAX_OPERANDS) << "\n";
 
628
  o << "#define MAX_SYNTAXES " << format("%d", MAX_SYNTAXES) << "\n";
 
629
  o << "\n";
 
630
  
 
631
  unsigned int i = 0;
 
632
  
 
633
  EnumEmitter operandFlags("OperandFlags");
 
634
  operandFlags.addEntry("kOperandFlagImmediate");
 
635
  operandFlags.addEntry("kOperandFlagRegister");
 
636
  operandFlags.addEntry("kOperandFlagMemory");
 
637
  operandFlags.addEntry("kOperandFlagEffectiveAddress");
 
638
  operandFlags.addEntry("kOperandFlagPCRelative");
 
639
  operandFlags.addEntry("kOperandFlagSource");
 
640
  operandFlags.addEntry("kOperandFlagTarget");
 
641
  operandFlags.emitAsFlags(o, i);
 
642
  
 
643
  o << "\n";
 
644
  
 
645
  EnumEmitter instructionFlags("InstructionFlags");
 
646
  instructionFlags.addEntry("kInstructionFlagMove");
 
647
  instructionFlags.addEntry("kInstructionFlagBranch");
 
648
  instructionFlags.addEntry("kInstructionFlagPush");
 
649
  instructionFlags.addEntry("kInstructionFlagPop");
 
650
  instructionFlags.addEntry("kInstructionFlagCall");
 
651
  instructionFlags.addEntry("kInstructionFlagReturn");
 
652
  instructionFlags.emitAsFlags(o, i);
 
653
  
 
654
  o << "\n";
 
655
  
 
656
  StructEmitter instInfo("InstInfo");
 
657
  instInfo.addMember("uint32_t", "instructionFlags");
 
658
  instInfo.addMember("uint8_t", "numOperands");
 
659
  instInfo.addMember("uint8_t", "operandFlags[MAX_OPERANDS]");
 
660
  instInfo.addMember("const char", "operandOrders[MAX_SYNTAXES][MAX_OPERANDS]");
 
661
  instInfo.emit(o, i);
 
662
  
 
663
  o << "\n";
 
664
  o << "#endif" << "\n";
 
665
}