~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/utils/TableGen/SubtargetEmitter.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
//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
 
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 emits subtarget enumerations.
 
11
//
 
12
//===----------------------------------------------------------------------===//
 
13
 
 
14
#include "SubtargetEmitter.h"
 
15
#include "CodeGenTarget.h"
 
16
#include "Record.h"
 
17
#include "llvm/ADT/StringExtras.h"
 
18
#include "llvm/Support/Debug.h"
 
19
#include <algorithm>
 
20
using namespace llvm;
 
21
 
 
22
//
 
23
// Enumeration - Emit the specified class as an enumeration.
 
24
//
 
25
void SubtargetEmitter::Enumeration(raw_ostream &OS,
 
26
                                   const char *ClassName,
 
27
                                   bool isBits) {
 
28
  // Get all records of class and sort
 
29
  std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
 
30
  std::sort(DefList.begin(), DefList.end(), LessRecord());
 
31
 
 
32
  // Open enumeration
 
33
  OS << "enum {\n";
 
34
  
 
35
  // For each record
 
36
  for (unsigned i = 0, N = DefList.size(); i < N;) {
 
37
    // Next record
 
38
    Record *Def = DefList[i];
 
39
    
 
40
    // Get and emit name
 
41
    OS << "  " << Def->getName();
 
42
    
 
43
    // If bit flags then emit expression (1 << i)
 
44
    if (isBits)  OS << " = " << " 1 << " << i;
 
45
 
 
46
    // Depending on 'if more in the list' emit comma
 
47
    if (++i < N) OS << ",";
 
48
    
 
49
    OS << "\n";
 
50
  }
 
51
  
 
52
  // Close enumeration
 
53
  OS << "};\n";
 
54
}
 
55
 
 
56
//
 
57
// FeatureKeyValues - Emit data of all the subtarget features.  Used by the
 
58
// command line.
 
59
//
 
60
void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
 
61
  // Gather and sort all the features
 
62
  std::vector<Record*> FeatureList =
 
63
                           Records.getAllDerivedDefinitions("SubtargetFeature");
 
64
  std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
 
65
 
 
66
  // Begin feature table
 
67
  OS << "// Sorted (by key) array of values for CPU features.\n"
 
68
     << "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n";
 
69
  
 
70
  // For each feature
 
71
  for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
 
72
    // Next feature
 
73
    Record *Feature = FeatureList[i];
 
74
 
 
75
    const std::string &Name = Feature->getName();
 
76
    const std::string &CommandLineName = Feature->getValueAsString("Name");
 
77
    const std::string &Desc = Feature->getValueAsString("Desc");
 
78
    
 
79
    if (CommandLineName.empty()) continue;
 
80
    
 
81
    // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
 
82
    OS << "  { "
 
83
       << "\"" << CommandLineName << "\", "
 
84
       << "\"" << Desc << "\", "
 
85
       << Name << ", ";
 
86
 
 
87
    const std::vector<Record*> &ImpliesList = 
 
88
      Feature->getValueAsListOfDefs("Implies");
 
89
    
 
90
    if (ImpliesList.empty()) {
 
91
      OS << "0";
 
92
    } else {
 
93
      for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
 
94
        OS << ImpliesList[j]->getName();
 
95
        if (++j < M) OS << " | ";
 
96
      }
 
97
    }
 
98
 
 
99
    OS << " }";
 
100
    
 
101
    // Depending on 'if more in the list' emit comma
 
102
    if ((i + 1) < N) OS << ",";
 
103
    
 
104
    OS << "\n";
 
105
  }
 
106
  
 
107
  // End feature table
 
108
  OS << "};\n";
 
109
 
 
110
  // Emit size of table
 
111
  OS<<"\nenum {\n";
 
112
  OS<<"  FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
 
113
  OS<<"};\n";
 
114
}
 
115
 
 
116
//
 
117
// CPUKeyValues - Emit data of all the subtarget processors.  Used by command
 
118
// line.
 
119
//
 
120
void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
 
121
  // Gather and sort processor information
 
122
  std::vector<Record*> ProcessorList =
 
123
                          Records.getAllDerivedDefinitions("Processor");
 
124
  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
 
125
 
 
126
  // Begin processor table
 
127
  OS << "// Sorted (by key) array of values for CPU subtype.\n"
 
128
     << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
 
129
     
 
130
  // For each processor
 
131
  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
 
132
    // Next processor
 
133
    Record *Processor = ProcessorList[i];
 
134
 
 
135
    const std::string &Name = Processor->getValueAsString("Name");
 
136
    const std::vector<Record*> &FeatureList = 
 
137
      Processor->getValueAsListOfDefs("Features");
 
138
    
 
139
    // Emit as { "cpu", "description", f1 | f2 | ... fn },
 
140
    OS << "  { "
 
141
       << "\"" << Name << "\", "
 
142
       << "\"Select the " << Name << " processor\", ";
 
143
    
 
144
    if (FeatureList.empty()) {
 
145
      OS << "0";
 
146
    } else {
 
147
      for (unsigned j = 0, M = FeatureList.size(); j < M;) {
 
148
        OS << FeatureList[j]->getName();
 
149
        if (++j < M) OS << " | ";
 
150
      }
 
151
    }
 
152
    
 
153
    // The "0" is for the "implies" section of this data structure.
 
154
    OS << ", 0 }";
 
155
    
 
156
    // Depending on 'if more in the list' emit comma
 
157
    if (++i < N) OS << ",";
 
158
    
 
159
    OS << "\n";
 
160
  }
 
161
  
 
162
  // End processor table
 
163
  OS << "};\n";
 
164
 
 
165
  // Emit size of table
 
166
  OS<<"\nenum {\n";
 
167
  OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
 
168
  OS<<"};\n";
 
169
}
 
170
 
 
171
//
 
172
// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
 
173
// Returns itinerary class count.
 
174
//
 
175
unsigned SubtargetEmitter::CollectAllItinClasses(raw_ostream &OS,
 
176
                              std::map<std::string, unsigned> &ItinClassesMap) {
 
177
  // Gather and sort all itinerary classes
 
178
  std::vector<Record*> ItinClassList =
 
179
                            Records.getAllDerivedDefinitions("InstrItinClass");
 
180
  std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
 
181
 
 
182
  // For each itinerary class
 
183
  unsigned N = ItinClassList.size();
 
184
  for (unsigned i = 0; i < N; i++) {
 
185
    // Next itinerary class
 
186
    const Record *ItinClass = ItinClassList[i];
 
187
    // Get name of itinerary class
 
188
    // Assign itinerary class a unique number
 
189
    ItinClassesMap[ItinClass->getName()] = i;
 
190
  }
 
191
  
 
192
  // Emit size of table
 
193
  OS<<"\nenum {\n";
 
194
  OS<<"  ItinClassesSize = " << N << "\n";
 
195
  OS<<"};\n";
 
196
 
 
197
  // Return itinerary class count
 
198
  return N;
 
199
}
 
200
 
 
201
//
 
202
// FormItineraryStageString - Compose a string containing the stage
 
203
// data initialization for the specified itinerary.  N is the number
 
204
// of stages.
 
205
//
 
206
void SubtargetEmitter::FormItineraryStageString(Record *ItinData,
 
207
                                                std::string &ItinString,
 
208
                                                unsigned &NStages) {
 
209
  // Get states list
 
210
  const std::vector<Record*> &StageList =
 
211
    ItinData->getValueAsListOfDefs("Stages");
 
212
 
 
213
  // For each stage
 
214
  unsigned N = NStages = StageList.size();
 
215
  for (unsigned i = 0; i < N;) {
 
216
    // Next stage
 
217
    const Record *Stage = StageList[i];
 
218
  
 
219
    // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc }
 
220
    int Cycles = Stage->getValueAsInt("Cycles");
 
221
    ItinString += "  { " + itostr(Cycles) + ", ";
 
222
    
 
223
    // Get unit list
 
224
    const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
 
225
    
 
226
    // For each unit
 
227
    for (unsigned j = 0, M = UnitList.size(); j < M;) {
 
228
      // Add name and bitwise or
 
229
      ItinString += UnitList[j]->getName();
 
230
      if (++j < M) ItinString += " | ";
 
231
    }
 
232
    
 
233
    int TimeInc = Stage->getValueAsInt("TimeInc");
 
234
    ItinString += ", " + itostr(TimeInc);
 
235
 
 
236
    // Close off stage
 
237
    ItinString += " }";
 
238
    if (++i < N) ItinString += ", ";
 
239
  }
 
240
}
 
241
 
 
242
//
 
243
// FormItineraryOperandCycleString - Compose a string containing the
 
244
// operand cycle initialization for the specified itinerary.  N is the
 
245
// number of operands that has cycles specified.
 
246
//
 
247
void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
 
248
                         std::string &ItinString, unsigned &NOperandCycles) {
 
249
  // Get operand cycle list
 
250
  const std::vector<int64_t> &OperandCycleList =
 
251
    ItinData->getValueAsListOfInts("OperandCycles");
 
252
 
 
253
  // For each operand cycle
 
254
  unsigned N = NOperandCycles = OperandCycleList.size();
 
255
  for (unsigned i = 0; i < N;) {
 
256
    // Next operand cycle
 
257
    const int OCycle = OperandCycleList[i];
 
258
  
 
259
    ItinString += "  " + itostr(OCycle);
 
260
    if (++i < N) ItinString += ", ";
 
261
  }
 
262
}
 
263
 
 
264
//
 
265
// EmitStageAndOperandCycleData - Generate unique itinerary stages and
 
266
// operand cycle tables.  Record itineraries for processors.
 
267
//
 
268
void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
 
269
       unsigned NItinClasses,
 
270
       std::map<std::string, unsigned> &ItinClassesMap, 
 
271
       std::vector<std::vector<InstrItinerary> > &ProcList) {
 
272
  // Gather processor iteraries
 
273
  std::vector<Record*> ProcItinList =
 
274
                       Records.getAllDerivedDefinitions("ProcessorItineraries");
 
275
  
 
276
  // If just no itinerary then don't bother
 
277
  if (ProcItinList.size() < 2) return;
 
278
 
 
279
  // Begin stages table
 
280
  std::string StageTable = "static const llvm::InstrStage Stages[] = {\n";
 
281
  StageTable += "  { 0, 0, 0 }, // No itinerary\n";
 
282
        
 
283
  // Begin operand cycle table
 
284
  std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
 
285
  OperandCycleTable += "  0, // No itinerary\n";
 
286
        
 
287
  unsigned StageCount = 1, OperandCycleCount = 1;
 
288
  unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
 
289
  std::map<std::string, unsigned> ItinStageMap, ItinOperandCycleMap;
 
290
  for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
 
291
    // Next record
 
292
    Record *Proc = ProcItinList[i];
 
293
    
 
294
    // Get processor itinerary name
 
295
    const std::string &Name = Proc->getName();
 
296
    
 
297
    // Skip default
 
298
    if (Name == "NoItineraries") continue;
 
299
    
 
300
    // Create and expand processor itinerary to cover all itinerary classes
 
301
    std::vector<InstrItinerary> ItinList;
 
302
    ItinList.resize(NItinClasses);
 
303
    
 
304
    // Get itinerary data list
 
305
    std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
 
306
    
 
307
    // For each itinerary data
 
308
    for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
 
309
      // Next itinerary data
 
310
      Record *ItinData = ItinDataList[j];
 
311
      
 
312
      // Get string and stage count
 
313
      std::string ItinStageString;
 
314
      unsigned NStages;
 
315
      FormItineraryStageString(ItinData, ItinStageString, NStages);
 
316
 
 
317
      // Get string and operand cycle count
 
318
      std::string ItinOperandCycleString;
 
319
      unsigned NOperandCycles;
 
320
      FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
 
321
                                      NOperandCycles);
 
322
 
 
323
      // Check to see if stage already exists and create if it doesn't
 
324
      unsigned FindStage = 0;
 
325
      if (NStages > 0) {
 
326
        FindStage = ItinStageMap[ItinStageString];
 
327
        if (FindStage == 0) {
 
328
          // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index
 
329
          StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n";
 
330
          // Record Itin class number.
 
331
          ItinStageMap[ItinStageString] = FindStage = StageCount;
 
332
          StageCount += NStages;
 
333
          ItinStageEnum++;
 
334
        }
 
335
      }
 
336
      
 
337
      // Check to see if operand cycle already exists and create if it doesn't
 
338
      unsigned FindOperandCycle = 0;
 
339
      if (NOperandCycles > 0) {
 
340
        FindOperandCycle = ItinOperandCycleMap[ItinOperandCycleString];
 
341
        if (FindOperandCycle == 0) {
 
342
          // Emit as  cycle, // index
 
343
          OperandCycleTable += ItinOperandCycleString + ", // " + 
 
344
            itostr(ItinOperandCycleEnum) + "\n";
 
345
          // Record Itin class number.
 
346
          ItinOperandCycleMap[ItinOperandCycleString] = 
 
347
            FindOperandCycle = OperandCycleCount;
 
348
          OperandCycleCount += NOperandCycles;
 
349
          ItinOperandCycleEnum++;
 
350
        }
 
351
      }
 
352
      
 
353
      // Set up itinerary as location and location + stage count
 
354
      InstrItinerary Intinerary = { FindStage, FindStage + NStages,
 
355
                                    FindOperandCycle, FindOperandCycle + NOperandCycles};
 
356
 
 
357
      // Locate where to inject into processor itinerary table
 
358
      const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
 
359
      unsigned Find = ItinClassesMap[Name];
 
360
      
 
361
      // Inject - empty slots will be 0, 0
 
362
      ItinList[Find] = Intinerary;
 
363
    }
 
364
    
 
365
    // Add process itinerary to list
 
366
    ProcList.push_back(ItinList);
 
367
  }
 
368
  
 
369
  // Closing stage
 
370
  StageTable += "  { 0, 0, 0 } // End itinerary\n";
 
371
  StageTable += "};\n";
 
372
 
 
373
  // Closing operand cycles
 
374
  OperandCycleTable += "  0 // End itinerary\n";
 
375
  OperandCycleTable += "};\n";
 
376
 
 
377
  // Emit tables.
 
378
  OS << StageTable;
 
379
  OS << OperandCycleTable;
 
380
  
 
381
  // Emit size of tables
 
382
  OS<<"\nenum {\n";
 
383
  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n";
 
384
  OS<<"  OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n";
 
385
  OS<<"};\n";
 
386
}
 
387
 
 
388
//
 
389
// EmitProcessorData - Generate data for processor itineraries.
 
390
//
 
391
void SubtargetEmitter::EmitProcessorData(raw_ostream &OS,
 
392
      std::vector<std::vector<InstrItinerary> > &ProcList) {
 
393
  // Get an iterator for processor itinerary stages
 
394
  std::vector<std::vector<InstrItinerary> >::iterator
 
395
      ProcListIter = ProcList.begin();
 
396
  
 
397
  // For each processor itinerary
 
398
  std::vector<Record*> Itins =
 
399
                       Records.getAllDerivedDefinitions("ProcessorItineraries");
 
400
  for (unsigned i = 0, N = Itins.size(); i < N; i++) {
 
401
    // Next record
 
402
    Record *Itin = Itins[i];
 
403
 
 
404
    // Get processor itinerary name
 
405
    const std::string &Name = Itin->getName();
 
406
    
 
407
    // Skip default
 
408
    if (Name == "NoItineraries") continue;
 
409
 
 
410
    // Begin processor itinerary table
 
411
    OS << "\n";
 
412
    OS << "static const llvm::InstrItinerary " << Name << "[] = {\n";
 
413
    
 
414
    // For each itinerary class
 
415
    std::vector<InstrItinerary> &ItinList = *ProcListIter++;
 
416
    for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
 
417
      InstrItinerary &Intinerary = ItinList[j];
 
418
      
 
419
      // Emit in the form of 
 
420
      // { firstStage, lastStage, firstCycle, lastCycle } // index
 
421
      if (Intinerary.FirstStage == 0) {
 
422
        OS << "  { 0, 0, 0, 0 }";
 
423
      } else {
 
424
        OS << "  { " << Intinerary.FirstStage << ", " << 
 
425
          Intinerary.LastStage << ", " << 
 
426
          Intinerary.FirstOperandCycle << ", " << 
 
427
          Intinerary.LastOperandCycle << " }";
 
428
      }
 
429
      
 
430
      OS << ", // " << j << "\n";
 
431
    }
 
432
    
 
433
    // End processor itinerary table
 
434
    OS << "  { ~0U, ~0U, ~0U, ~0U } // end marker\n";
 
435
    OS << "};\n";
 
436
  }
 
437
}
 
438
 
 
439
//
 
440
// EmitProcessorLookup - generate cpu name to itinerary lookup table.
 
441
//
 
442
void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
 
443
  // Gather and sort processor information
 
444
  std::vector<Record*> ProcessorList =
 
445
                          Records.getAllDerivedDefinitions("Processor");
 
446
  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
 
447
 
 
448
  // Begin processor table
 
449
  OS << "\n";
 
450
  OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
 
451
     << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
 
452
     
 
453
  // For each processor
 
454
  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
 
455
    // Next processor
 
456
    Record *Processor = ProcessorList[i];
 
457
 
 
458
    const std::string &Name = Processor->getValueAsString("Name");
 
459
    const std::string &ProcItin =
 
460
      Processor->getValueAsDef("ProcItin")->getName();
 
461
    
 
462
    // Emit as { "cpu", procinit },
 
463
    OS << "  { "
 
464
       << "\"" << Name << "\", "
 
465
       << "(void *)&" << ProcItin;
 
466
        
 
467
    OS << " }";
 
468
    
 
469
    // Depending on ''if more in the list'' emit comma
 
470
    if (++i < N) OS << ",";
 
471
    
 
472
    OS << "\n";
 
473
  }
 
474
  
 
475
  // End processor table
 
476
  OS << "};\n";
 
477
 
 
478
  // Emit size of table
 
479
  OS<<"\nenum {\n";
 
480
  OS<<"  ProcItinKVSize = sizeof(ProcItinKV)/"
 
481
                            "sizeof(llvm::SubtargetInfoKV)\n";
 
482
  OS<<"};\n";
 
483
}
 
484
 
 
485
//
 
486
// EmitData - Emits all stages and itineries, folding common patterns.
 
487
//
 
488
void SubtargetEmitter::EmitData(raw_ostream &OS) {
 
489
  std::map<std::string, unsigned> ItinClassesMap;
 
490
  std::vector<std::vector<InstrItinerary> > ProcList;
 
491
  
 
492
  // Enumerate all the itinerary classes
 
493
  unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap);
 
494
  // Make sure the rest is worth the effort
 
495
  HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
 
496
  
 
497
  if (HasItineraries) {
 
498
    // Emit the stage data
 
499
    EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ProcList);
 
500
    // Emit the processor itinerary data
 
501
    EmitProcessorData(OS, ProcList);
 
502
    // Emit the processor lookup data
 
503
    EmitProcessorLookup(OS);
 
504
  }
 
505
}
 
506
 
 
507
//
 
508
// ParseFeaturesFunction - Produces a subtarget specific function for parsing
 
509
// the subtarget features string.
 
510
//
 
511
void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
 
512
  std::vector<Record*> Features =
 
513
                       Records.getAllDerivedDefinitions("SubtargetFeature");
 
514
  std::sort(Features.begin(), Features.end(), LessRecord());
 
515
 
 
516
  OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" 
 
517
     << "// subtarget options.\n" 
 
518
     << "std::string llvm::";
 
519
  OS << Target;
 
520
  OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
 
521
     << "                                  const std::string &CPU) {\n"
 
522
     << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
 
523
     << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
 
524
     << "  SubtargetFeatures Features(FS);\n"
 
525
     << "  Features.setCPUIfNone(CPU);\n"
 
526
     << "  uint32_t Bits =  Features.getBits(SubTypeKV, SubTypeKVSize,\n"
 
527
     << "                                    FeatureKV, FeatureKVSize);\n";
 
528
 
 
529
  for (unsigned i = 0; i < Features.size(); i++) {
 
530
    // Next record
 
531
    Record *R = Features[i];
 
532
    const std::string &Instance = R->getName();
 
533
    const std::string &Value = R->getValueAsString("Value");
 
534
    const std::string &Attribute = R->getValueAsString("Attribute");
 
535
 
 
536
    if (Value=="true" || Value=="false")
 
537
      OS << "  if ((Bits & " << Instance << ") != 0) "
 
538
         << Attribute << " = " << Value << ";\n";
 
539
    else
 
540
      OS << "  if ((Bits & " << Instance << ") != 0 && " << Attribute << 
 
541
            " < " << Value << ") " << Attribute << " = " << Value << ";\n";
 
542
  }
 
543
 
 
544
  if (HasItineraries) {
 
545
    OS << "\n"
 
546
       << "  InstrItinerary *Itinerary = (InstrItinerary *)"
 
547
       <<              "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
 
548
       << "  InstrItins = InstrItineraryData(Stages, OperandCycles, Itinerary);\n";
 
549
  }
 
550
 
 
551
  OS << "  return Features.getCPU();\n"
 
552
     << "}\n";
 
553
}
 
554
 
 
555
//
 
556
// SubtargetEmitter::run - Main subtarget enumeration emitter.
 
557
//
 
558
void SubtargetEmitter::run(raw_ostream &OS) {
 
559
  Target = CodeGenTarget().getName();
 
560
 
 
561
  EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
 
562
 
 
563
  OS << "#include \"llvm/Support/Debug.h\"\n";
 
564
  OS << "#include \"llvm/Support/raw_ostream.h\"\n";
 
565
  OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
 
566
  OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
 
567
  
 
568
  Enumeration(OS, "FuncUnit", true);
 
569
  OS<<"\n";
 
570
//  Enumeration(OS, "InstrItinClass", false);
 
571
//  OS<<"\n";
 
572
  Enumeration(OS, "SubtargetFeature", true);
 
573
  OS<<"\n";
 
574
  FeatureKeyValues(OS);
 
575
  OS<<"\n";
 
576
  CPUKeyValues(OS);
 
577
  OS<<"\n";
 
578
  EmitData(OS);
 
579
  OS<<"\n";
 
580
  ParseFeaturesFunction(OS);
 
581
}