CodeGenTarget.cpp revision 243830
167761Smsmith//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
278915Smsmith//
367761Smsmith//                     The LLVM Compiler Infrastructure
467761Smsmith//
567761Smsmith// This file is distributed under the University of Illinois Open Source
667761Smsmith// License. See LICENSE.TXT for details.
767761Smsmith//
867761Smsmith//===----------------------------------------------------------------------===//
967761Smsmith//
1067761Smsmith// This class wraps target description classes used by the various code
1167761Smsmith// generation TableGen backends.  This makes it easier to access the data and
1267761Smsmith// provides a single place that needs to check it for validity.  All of these
1367761Smsmith// classes abort on error conditions.
1467761Smsmith//
1567761Smsmith//===----------------------------------------------------------------------===//
1667761Smsmith
1767761Smsmith#include "CodeGenTarget.h"
1867761Smsmith#include "CodeGenIntrinsics.h"
1967761Smsmith#include "CodeGenSchedule.h"
2067761Smsmith#include "llvm/TableGen/Error.h"
2167761Smsmith#include "llvm/TableGen/Record.h"
2267761Smsmith#include "llvm/ADT/StringExtras.h"
2367761Smsmith#include "llvm/ADT/STLExtras.h"
2467761Smsmith#include "llvm/Support/CommandLine.h"
2567761Smsmith#include <algorithm>
2667761Smsmithusing namespace llvm;
2767761Smsmith
28119418Sobrienstatic cl::opt<unsigned>
29119418SobrienAsmParserNum("asmparsernum", cl::init(0),
30119418Sobrien             cl::desc("Make -gen-asm-parser emit assembly parser #N"));
3167761Smsmith
3267761Smsmithstatic cl::opt<unsigned>
3367761SmsmithAsmWriterNum("asmwriternum", cl::init(0),
3491126Smsmith             cl::desc("Make -gen-asm-writer emit assembly writer #N"));
3567761Smsmith
3691126Smsmith/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
3778915Smsmith/// record corresponds to.
3879283SmsmithMVT::SimpleValueType llvm::getValueType(Record *Rec) {
3991126Smsmith  return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
4091640Siwasaki}
4167761Smsmith
4267761Smsmithstd::string llvm::getName(MVT::SimpleValueType T) {
4367761Smsmith  switch (T) {
4467761Smsmith  case MVT::Other:   return "UNKNOWN";
45119529Snjl  case MVT::iPTR:    return "TLI.getPointerTy()";
4678999Smsmith  case MVT::iPTRAny: return "TLI.getPointerTy()";
4791126Smsmith  default: return getEnumName(T);
4869744Smsmith  }
4971874Smsmith}
5071874Smsmith
5167761Smsmithstd::string llvm::getEnumName(MVT::SimpleValueType T) {
5278915Smsmith  switch (T) {
5378915Smsmith  case MVT::Other:    return "MVT::Other";
5478915Smsmith  case MVT::i1:       return "MVT::i1";
5578915Smsmith  case MVT::i8:       return "MVT::i8";
56119529Snjl  case MVT::i16:      return "MVT::i16";
57119529Snjl  case MVT::i32:      return "MVT::i32";
5878915Smsmith  case MVT::i64:      return "MVT::i64";
59119529Snjl  case MVT::i128:     return "MVT::i128";
60119529Snjl  case MVT::iAny:     return "MVT::iAny";
6179375Smsmith  case MVT::fAny:     return "MVT::fAny";
6278915Smsmith  case MVT::vAny:     return "MVT::vAny";
6378915Smsmith  case MVT::f16:      return "MVT::f16";
6478915Smsmith  case MVT::f32:      return "MVT::f32";
6578915Smsmith  case MVT::f64:      return "MVT::f64";
6678915Smsmith  case MVT::f80:      return "MVT::f80";
6778915Smsmith  case MVT::f128:     return "MVT::f128";
6878915Smsmith  case MVT::ppcf128:  return "MVT::ppcf128";
6978915Smsmith  case MVT::x86mmx:   return "MVT::x86mmx";
7078915Smsmith  case MVT::Glue:     return "MVT::Glue";
7178915Smsmith  case MVT::isVoid:   return "MVT::isVoid";
7278915Smsmith  case MVT::v2i1:     return "MVT::v2i1";
7378915Smsmith  case MVT::v4i1:     return "MVT::v4i1";
7478915Smsmith  case MVT::v8i1:     return "MVT::v8i1";
7567761Smsmith  case MVT::v16i1:    return "MVT::v16i1";
76119529Snjl  case MVT::v2i8:     return "MVT::v2i8";
77119529Snjl  case MVT::v4i8:     return "MVT::v4i8";
78119529Snjl  case MVT::v8i8:     return "MVT::v8i8";
79119529Snjl  case MVT::v16i8:    return "MVT::v16i8";
8079375Smsmith  case MVT::v32i8:    return "MVT::v32i8";
81119529Snjl  case MVT::v1i16:    return "MVT::v1i16";
82119529Snjl  case MVT::v2i16:    return "MVT::v2i16";
8379375Smsmith  case MVT::v4i16:    return "MVT::v4i16";
8479375Smsmith  case MVT::v8i16:    return "MVT::v8i16";
8579375Smsmith  case MVT::v16i16:   return "MVT::v16i16";
8679375Smsmith  case MVT::v1i32:    return "MVT::v1i32";
8779283Smsmith  case MVT::v2i32:    return "MVT::v2i32";
88119529Snjl  case MVT::v4i32:    return "MVT::v4i32";
89119529Snjl  case MVT::v8i32:    return "MVT::v8i32";
90119529Snjl  case MVT::v16i32:   return "MVT::v16i32";
91119529Snjl  case MVT::v1i64:    return "MVT::v1i64";
9279283Smsmith  case MVT::v2i64:    return "MVT::v2i64";
93119529Snjl  case MVT::v4i64:    return "MVT::v4i64";
9479283Smsmith  case MVT::v8i64:    return "MVT::v8i64";
9578915Smsmith  case MVT::v16i64:   return "MVT::v16i64";
96119529Snjl  case MVT::v2f16:    return "MVT::v2f16";
9788420Siwasaki  case MVT::v2f32:    return "MVT::v2f32";
9867761Smsmith  case MVT::v4f32:    return "MVT::v4f32";
9967761Smsmith  case MVT::v8f32:    return "MVT::v8f32";
10067761Smsmith  case MVT::v2f64:    return "MVT::v2f64";
10167761Smsmith  case MVT::v4f64:    return "MVT::v4f64";
10278915Smsmith  case MVT::Metadata: return "MVT::Metadata";
103119529Snjl  case MVT::iPTR:     return "MVT::iPTR";
10478915Smsmith  case MVT::iPTRAny:  return "MVT::iPTRAny";
10578915Smsmith  case MVT::Untyped:  return "MVT::Untyped";
10678915Smsmith  default: llvm_unreachable("ILLEGAL VALUE TYPE!");
107119529Snjl  }
108119529Snjl}
10979283Smsmith
11079375Smsmith/// getQualifiedName - Return the name of the specified record, with a
111119529Snjl/// namespace qualifier if the record contains one.
112119529Snjl///
11391126Smsmithstd::string llvm::getQualifiedName(const Record *R) {
11491640Siwasaki  std::string Namespace;
11591126Smsmith  if (R->getValue("Namespace"))
11691126Smsmith     Namespace = R->getValueAsString("Namespace");
11767761Smsmith  if (Namespace.empty()) return R->getName();
11867761Smsmith  return Namespace + "::" + R->getName();
11967761Smsmith}
12067761Smsmith
12167761Smsmith
12267761Smsmith/// getTarget - Return the current instance of the Target class.
12367761Smsmith///
12467761SmsmithCodeGenTarget::CodeGenTarget(RecordKeeper &records)
12567761Smsmith  : Records(records), RegBank(0), SchedModels(0) {
12667761Smsmith  std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
12767761Smsmith  if (Targets.size() == 0)
12867761Smsmith    PrintFatalError("ERROR: No 'Target' subclasses defined!");
12967761Smsmith  if (Targets.size() != 1)
13067761Smsmith    PrintFatalError("ERROR: Multiple subclasses of Target defined!");
13189054Smsmith  TargetRec = Targets[0];
13267761Smsmith}
13367761Smsmith
13479283SmsmithCodeGenTarget::~CodeGenTarget() {
13579283Smsmith  delete RegBank;
13679283Smsmith  delete SchedModels;
137119529Snjl}
138119529Snjl
13988420Siwasakiconst std::string &CodeGenTarget::getName() const {
14085699Siwasaki  return TargetRec->getName();
141119529Snjl}
142119529Snjl
143119529Snjlstd::string CodeGenTarget::getInstNamespace() const {
14478915Smsmith  for (inst_iterator i = inst_begin(), e = inst_end(); i != e; ++i) {
14578915Smsmith    // Make sure not to pick up "TargetOpcode" by accidentally getting
14678915Smsmith    // the namespace off the PHI instruction or something.
14767761Smsmith    if ((*i)->Namespace != "TargetOpcode")
14867761Smsmith      return (*i)->Namespace;
14967761Smsmith  }
15078999Smsmith
151105282Sjhb  return "";
15278999Smsmith}
15378999Smsmith
15478999SmsmithRecord *CodeGenTarget::getInstructionSet() const {
155119529Snjl  return TargetRec->getValueAsDef("InstructionSet");
15669744Smsmith}
157119529Snjl
158120453Snjl
15978999Smsmith/// getAsmParser - Return the AssemblyParser definition for this target.
16078999Smsmith///
16178999SmsmithRecord *CodeGenTarget::getAsmParser() const {
16267761Smsmith  std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
16378999Smsmith  if (AsmParserNum >= LI.size())
164119529Snjl    PrintFatalError("Target does not have an AsmParser #" + utostr(AsmParserNum) + "!");
16567761Smsmith  return LI[AsmParserNum];
16667761Smsmith}
16778915Smsmith
16878915Smsmith/// getAsmParserVariant - Return the AssmblyParserVariant definition for
16978915Smsmith/// this target.
17067761Smsmith///
17167761SmsmithRecord *CodeGenTarget::getAsmParserVariant(unsigned i) const {
17267761Smsmith  std::vector<Record*> LI =
17367761Smsmith    TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
17479283Smsmith  if (i >= LI.size())
17578915Smsmith    PrintFatalError("Target does not have an AsmParserVariant #" + utostr(i) + "!");
17679283Smsmith  return LI[i];
177105282Sjhb}
17867761Smsmith
17996926Speter/// getAsmParserVariantCount - Return the AssmblyParserVariant definition
18069744Smsmith/// available for this target.
18178999Smsmith///
18278999Smsmithunsigned CodeGenTarget::getAsmParserVariantCount() const {
18367761Smsmith  std::vector<Record*> LI =
18467761Smsmith    TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
18567761Smsmith  return LI.size();
18679375Smsmith}
18788420Siwasaki
18867761Smsmith/// getAsmWriter - Return the AssemblyWriter definition for this target.
18978915Smsmith///
19078915SmsmithRecord *CodeGenTarget::getAsmWriter() const {
19178915Smsmith  std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
19278915Smsmith  if (AsmWriterNum >= LI.size())
19378915Smsmith    PrintFatalError("Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!");
19478999Smsmith  return LI[AsmWriterNum];
19578915Smsmith}
19678915Smsmith
19778915SmsmithCodeGenRegBank &CodeGenTarget::getRegBank() const {
19878915Smsmith  if (!RegBank)
19971874Smsmith    RegBank = new CodeGenRegBank(Records);
20078999Smsmith  return *RegBank;
20170271Stakawata}
20271874Smsmith
20379283Smsmithvoid CodeGenTarget::ReadRegAltNameIndices() const {
20479283Smsmith  RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex");
20579283Smsmith  std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord());
20679283Smsmith}
20779283Smsmith
20879283Smsmith/// getRegisterByName - If there is a register with the specific AsmName,
20979283Smsmith/// return it.
21079283Smsmithconst CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
211119529Snjl  const StringMap<CodeGenRegister*> &Regs = getRegBank().getRegistersByName();
212119529Snjl  StringMap<CodeGenRegister*>::const_iterator I = Regs.find(Name);
21385699Siwasaki  if (I == Regs.end())
21485699Siwasaki    return 0;
21585699Siwasaki  return I->second;
216119529Snjl}
217119529Snjl
21888420Siwasakistd::vector<MVT::SimpleValueType> CodeGenTarget::
21988420SiwasakigetRegisterVTs(Record *R) const {
22088420Siwasaki  const CodeGenRegister *Reg = getRegBank().getReg(R);
22188420Siwasaki  std::vector<MVT::SimpleValueType> Result;
22279283Smsmith  ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
22379283Smsmith  for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
22479283Smsmith    const CodeGenRegisterClass &RC = *RCs[i];
22579283Smsmith    if (RC.contains(Reg)) {
226119529Snjl      const std::vector<MVT::SimpleValueType> &InVTs = RC.getValueTypes();
227119529Snjl      Result.insert(Result.end(), InVTs.begin(), InVTs.end());
22879283Smsmith    }
22979283Smsmith  }
23079283Smsmith
23179375Smsmith  // Remove duplicates.
23279375Smsmith  array_pod_sort(Result.begin(), Result.end());
23379375Smsmith  Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
23479375Smsmith  return Result;
23579283Smsmith}
23679375Smsmith
23779375Smsmith
23879283Smsmithvoid CodeGenTarget::ReadLegalValueTypes() const {
23979283Smsmith  ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
24079375Smsmith  for (unsigned i = 0, e = RCs.size(); i != e; ++i)
24179283Smsmith    for (unsigned ri = 0, re = RCs[i]->VTs.size(); ri != re; ++ri)
24279283Smsmith      LegalValueTypes.push_back(RCs[i]->VTs[ri]);
24379375Smsmith
24479283Smsmith  // Remove duplicates.
24579283Smsmith  std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
24679375Smsmith  LegalValueTypes.erase(std::unique(LegalValueTypes.begin(),
24786399Siwasaki                                    LegalValueTypes.end()),
24886399Siwasaki                        LegalValueTypes.end());
24986399Siwasaki}
25079283Smsmith
25179283SmsmithCodeGenSchedModels &CodeGenTarget::getSchedModels() const {
25279375Smsmith  if (!SchedModels)
25379375Smsmith    SchedModels = new CodeGenSchedModels(Records, *this);
25479375Smsmith  return *SchedModels;
25579375Smsmith}
25691640Siwasaki
25779375Smsmithvoid CodeGenTarget::ReadInstructions() const {
25879375Smsmith  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
25979375Smsmith  if (Insts.size() <= 2)
26071874Smsmith    PrintFatalError("No 'Instruction' subclasses defined!");
26171874Smsmith
26271874Smsmith  // Parse the instructions defined in the .td file.
26378999Smsmith  for (unsigned i = 0, e = Insts.size(); i != e; ++i)
26491126Smsmith    Instructions[Insts[i]] = new CodeGenInstruction(Insts[i]);
26591126Smsmith}
26691126Smsmith
26791126Smsmithstatic const CodeGenInstruction *
26891126SmsmithGetInstByName(const char *Name,
26991126Smsmith              const DenseMap<const Record*, CodeGenInstruction*> &Insts,
270104354Sscottl              RecordKeeper &Records) {
27191126Smsmith  const Record *Rec = Records.getDef(Name);
272119529Snjl
273119529Snjl  DenseMap<const Record*, CodeGenInstruction*>::const_iterator
27491126Smsmith    I = Insts.find(Rec);
27591126Smsmith  if (Rec == 0 || I == Insts.end())
27691126Smsmith    PrintFatalError(std::string("Could not find '") + Name + "' instruction!");
27791126Smsmith  return I->second;
27878999Smsmith}
27978999Smsmith
28079375Smsmithnamespace {
281119529Snjl/// SortInstByName - Sorting predicate to sort instructions by name.
28267761Smsmith///
28370271Stakawatastruct SortInstByName {
28478915Smsmith  bool operator()(const CodeGenInstruction *Rec1,
28578915Smsmith                  const CodeGenInstruction *Rec2) const {
28678915Smsmith    return Rec1->TheDef->getName() < Rec2->TheDef->getName();
28778915Smsmith  }
28878915Smsmith};
28978915Smsmith}
29078915Smsmith
29178915Smsmith/// getInstructionsByEnumValue - Return all of the instructions defined by the
29278915Smsmith/// target, ordered by their enum value.
29378915Smsmithvoid CodeGenTarget::ComputeInstrsByEnum() const {
29478915Smsmith  // The ordering here must match the ordering in TargetOpcodes.h.
29578915Smsmith  const char *const FixedInstrs[] = {
29696926Speter    "PHI",
29778915Smsmith    "INLINEASM",
29878999Smsmith    "PROLOG_LABEL",
29978999Smsmith    "EH_LABEL",
300119529Snjl    "GC_LABEL",
30178915Smsmith    "KILL",
30278915Smsmith    "EXTRACT_SUBREG",
30379375Smsmith    "INSERT_SUBREG",
30479375Smsmith    "IMPLICIT_DEF",
30579375Smsmith    "SUBREG_TO_REG",
30679375Smsmith    "COPY_TO_REGCLASS",
30779375Smsmith    "DBG_VALUE",
30878915Smsmith    "REG_SEQUENCE",
309119529Snjl    "COPY",
31078915Smsmith    "BUNDLE",
31178915Smsmith    "LIFETIME_START",
31279375Smsmith    "LIFETIME_END",
31378915Smsmith    0
31491126Smsmith  };
31591126Smsmith  const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
31691126Smsmith  for (const char *const *p = FixedInstrs; *p; ++p) {
31779375Smsmith    const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
31878915Smsmith    assert(Instr && "Missing target independent instruction");
319119529Snjl    assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
32078915Smsmith    InstrsByEnum.push_back(Instr);
321119529Snjl  }
32278915Smsmith  unsigned EndOfPredefines = InstrsByEnum.size();
323119529Snjl
32478915Smsmith  for (DenseMap<const Record*, CodeGenInstruction*>::const_iterator
32578915Smsmith       I = Insts.begin(), E = Insts.end(); I != E; ++I) {
32678915Smsmith    const CodeGenInstruction *CGI = I->second;
32779375Smsmith    if (CGI->Namespace != "TargetOpcode")
32879375Smsmith      InstrsByEnum.push_back(CGI);
32991126Smsmith  }
33091126Smsmith
33191126Smsmith  assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
33279375Smsmith
33379375Smsmith  // All of the instructions are now in random order based on the map iteration.
33479375Smsmith  // Sort them by name.
33579375Smsmith  std::sort(InstrsByEnum.begin()+EndOfPredefines, InstrsByEnum.end(),
33679375Smsmith            SortInstByName());
33778915Smsmith}
33878915Smsmith
33979283Smsmith
34079283Smsmith/// isLittleEndianEncoding - Return whether this target encodes its instruction
34179283Smsmith/// in little-endian format, i.e. bits laid out in the order [0..n]
34279283Smsmith///
34379283Smsmithbool CodeGenTarget::isLittleEndianEncoding() const {
34479375Smsmith  return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
34579375Smsmith}
34679375Smsmith
34779283Smsmith/// guessInstructionProperties - Return true if it's OK to guess instruction
34879375Smsmith/// properties instead of raising an error.
34979283Smsmith///
35079283Smsmith/// This is configurable as a temporary migration aid. It will eventually be
35178915Smsmith/// permanently false.
35278915Smsmithbool CodeGenTarget::guessInstructionProperties() const {
35378915Smsmith  return getInstructionSet()->getValueAsBit("guessInstructionProperties");
35478915Smsmith}
355119529Snjl
35678915Smsmith//===----------------------------------------------------------------------===//
35778915Smsmith// ComplexPattern implementation
35885699Siwasaki//
35985699SiwasakiComplexPattern::ComplexPattern(Record *R) {
36085699Siwasaki  Ty          = ::getValueType(R->getValueAsDef("Ty"));
36185699Siwasaki  NumOperands = R->getValueAsInt("NumOperands");
36285699Siwasaki  SelectFunc  = R->getValueAsString("SelectFunc");
36385699Siwasaki  RootNodes   = R->getValueAsListOfDefs("RootNodes");
36485699Siwasaki
365119529Snjl  // Parse the properties.
36685699Siwasaki  Properties = 0;
36785699Siwasaki  std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
36885699Siwasaki  for (unsigned i = 0, e = PropList.size(); i != e; ++i)
36985699Siwasaki    if (PropList[i]->getName() == "SDNPHasChain") {
37085699Siwasaki      Properties |= 1 << SDNPHasChain;
37178915Smsmith    } else if (PropList[i]->getName() == "SDNPOptInGlue") {
37278915Smsmith      Properties |= 1 << SDNPOptInGlue;
37378915Smsmith    } else if (PropList[i]->getName() == "SDNPMayStore") {
37471874Smsmith      Properties |= 1 << SDNPMayStore;
375119529Snjl    } else if (PropList[i]->getName() == "SDNPMayLoad") {
37671874Smsmith      Properties |= 1 << SDNPMayLoad;
377119529Snjl    } else if (PropList[i]->getName() == "SDNPSideEffect") {
378119529Snjl      Properties |= 1 << SDNPSideEffect;
37979283Smsmith    } else if (PropList[i]->getName() == "SDNPMemOperand") {
38078915Smsmith      Properties |= 1 << SDNPMemOperand;
38179283Smsmith    } else if (PropList[i]->getName() == "SDNPVariadic") {
38286399Siwasaki      Properties |= 1 << SDNPVariadic;
38370271Stakawata    } else if (PropList[i]->getName() == "SDNPWantRoot") {
38496926Speter      Properties |= 1 << SDNPWantRoot;
38570271Stakawata    } else if (PropList[i]->getName() == "SDNPWantParent") {
38678999Smsmith      Properties |= 1 << SDNPWantParent;
38778999Smsmith    } else {
388119529Snjl      errs() << "Unsupported SD Node property '" << PropList[i]->getName()
389119529Snjl             << "' on ComplexPattern '" << R->getName() << "'!\n";
39088420Siwasaki      exit(1);
39188420Siwasaki    }
39288420Siwasaki}
393119529Snjl
394119529Snjl//===----------------------------------------------------------------------===//
395119529Snjl// CodeGenIntrinsic Implementation
39686552Siwasaki//===----------------------------------------------------------------------===//
39786552Siwasaki
39886552Siwasakistd::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
39978915Smsmith                                                   bool TargetOnly) {
40088420Siwasaki  std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
40171874Smsmith
40288420Siwasaki  std::vector<CodeGenIntrinsic> Result;
40382372Smsmith
40479283Smsmith  for (unsigned i = 0, e = I.size(); i != e; ++i) {
40578915Smsmith    bool isTarget = I[i]->getValueAsBit("isTarget");
40678915Smsmith    if (isTarget == TargetOnly)
40778915Smsmith      Result.push_back(CodeGenIntrinsic(I[i]));
40879283Smsmith  }
40979283Smsmith  return Result;
41078915Smsmith}
41179283Smsmith
41279375SmsmithCodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
41379375Smsmith  TheDef = R;
41479283Smsmith  std::string DefName = R->getName();
41582967Siwasaki  ModRef = ReadWriteMem;
416119529Snjl  isOverloaded = false;
417119529Snjl  isCommutative = false;
418119529Snjl  canThrow = false;
419119529Snjl  isNoReturn = false;
42085699Siwasaki
42182967Siwasaki  if (DefName.size() <= 4 ||
42279375Smsmith      std::string(DefName.begin(), DefName.begin() + 4) != "int_")
42379375Smsmith    PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!");
42479283Smsmith
42585699Siwasaki  EnumName = std::string(DefName.begin()+4, DefName.end());
42685699Siwasaki
42785699Siwasaki  if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
42885699Siwasaki    GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
42985699Siwasaki
43085699Siwasaki  TargetPrefix = R->getValueAsString("TargetPrefix");
431119529Snjl  Name = R->getValueAsString("LLVMName");
43285699Siwasaki
43385699Siwasaki  if (Name == "") {
434119529Snjl    // If an explicit name isn't specified, derive one from the DefName.
43585699Siwasaki    Name = "llvm.";
43685699Siwasaki
43785699Siwasaki    for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
438119529Snjl      Name += (EnumName[i] == '_') ? '.' : EnumName[i];
43979375Smsmith  } else {
44079375Smsmith    // Verify it starts with "llvm.".
44178915Smsmith    if (Name.size() <= 5 ||
44279375Smsmith        std::string(Name.begin(), Name.begin() + 5) != "llvm.")
44379375Smsmith      PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!");
44479375Smsmith  }
44579375Smsmith
44679375Smsmith  // If TargetPrefix is specified, make sure that Name starts with
44779375Smsmith  // "llvm.<targetprefix>.".
44879375Smsmith  if (!TargetPrefix.empty()) {
44979375Smsmith    if (Name.size() < 6+TargetPrefix.size() ||
45079375Smsmith        std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
451119529Snjl        != (TargetPrefix + "."))
45279283Smsmith      PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." +
453119529Snjl        TargetPrefix + ".'!");
45479283Smsmith  }
455119529Snjl
456119529Snjl  // Parse the list of return types.
457119529Snjl  std::vector<MVT::SimpleValueType> OverloadedVTs;
45878915Smsmith  ListInit *TypeList = R->getValueAsListInit("RetTypes");
459119529Snjl  for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
460119529Snjl    Record *TyEl = TypeList->getElementAsRecord(i);
461119529Snjl    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
462119529Snjl    MVT::SimpleValueType VT;
463119529Snjl    if (TyEl->isSubClassOf("LLVMMatchType")) {
464119529Snjl      unsigned MatchTy = TyEl->getValueAsInt("Number");
46586552Siwasaki      assert(MatchTy < OverloadedVTs.size() &&
466119529Snjl             "Invalid matching number!");
467119529Snjl      VT = OverloadedVTs[MatchTy];
468119529Snjl      // It only makes sense to use the extended and truncated vector element
46979283Smsmith      // variants with iAny types; otherwise, if the intrinsic is not
47079283Smsmith      // overloaded, all the types can be specified directly.
47178915Smsmith      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
472119529Snjl               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
47378915Smsmith              VT == MVT::iAny || VT == MVT::vAny) &&
47478915Smsmith             "Expected iAny or vAny type");
47579283Smsmith    } else {
47679283Smsmith      VT = getValueType(TyEl->getValueAsDef("VT"));
47779283Smsmith    }
47879283Smsmith    if (EVT(VT).isOverloaded()) {
47978915Smsmith      OverloadedVTs.push_back(VT);
480119529Snjl      isOverloaded = true;
481119529Snjl    }
482119529Snjl
483119529Snjl    // Reject invalid types.
484119529Snjl    if (VT == MVT::isVoid)
48597274Sbde      PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
48679283Smsmith
48778915Smsmith    IS.RetVTs.push_back(VT);
48879375Smsmith    IS.RetTypeDefs.push_back(TyEl);
48978915Smsmith  }
49088420Siwasaki
49188420Siwasaki  // Parse the list of parameter types.
49271874Smsmith  TypeList = R->getValueAsListInit("ParamTypes");
49371874Smsmith  for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
49470271Stakawata    Record *TyEl = TypeList->getElementAsRecord(i);
49578915Smsmith    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
49678915Smsmith    MVT::SimpleValueType VT;
49778915Smsmith    if (TyEl->isSubClassOf("LLVMMatchType")) {
49871874Smsmith      unsigned MatchTy = TyEl->getValueAsInt("Number");
49978915Smsmith      assert(MatchTy < OverloadedVTs.size() &&
50078915Smsmith             "Invalid matching number!");
50178915Smsmith      VT = OverloadedVTs[MatchTy];
50278915Smsmith      // It only makes sense to use the extended and truncated vector element
50396926Speter      // variants with iAny types; otherwise, if the intrinsic is not
50478999Smsmith      // overloaded, all the types can be specified directly.
50578999Smsmith      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
50678915Smsmith               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
507119529Snjl              VT == MVT::iAny || VT == MVT::vAny) &&
50878915Smsmith             "Expected iAny or vAny type");
50979375Smsmith    } else
51078915Smsmith      VT = getValueType(TyEl->getValueAsDef("VT"));
51179375Smsmith
51278915Smsmith    if (EVT(VT).isOverloaded()) {
51378915Smsmith      OverloadedVTs.push_back(VT);
51478915Smsmith      isOverloaded = true;
51578915Smsmith    }
51678915Smsmith
51778915Smsmith    // Reject invalid types.
51878915Smsmith    if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
51979283Smsmith      PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
52079375Smsmith
521119529Snjl    IS.ParamVTs.push_back(VT);
52278915Smsmith    IS.ParamTypeDefs.push_back(TyEl);
52378915Smsmith  }
52478915Smsmith
52578915Smsmith  // Parse the intrinsic properties.
52678915Smsmith  ListInit *PropList = R->getValueAsListInit("Properties");
52778915Smsmith  for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
52878915Smsmith    Record *Property = PropList->getElementAsRecord(i);
52978915Smsmith    assert(Property->isSubClassOf("IntrinsicProperty") &&
53078915Smsmith           "Expected a property!");
53178915Smsmith
53279375Smsmith    if (Property->getName() == "IntrNoMem")
53378915Smsmith      ModRef = NoMem;
53496926Speter    else if (Property->getName() == "IntrReadArgMem")
53578915Smsmith      ModRef = ReadArgMem;
53678999Smsmith    else if (Property->getName() == "IntrReadMem")
53778999Smsmith      ModRef = ReadMem;
53878915Smsmith    else if (Property->getName() == "IntrReadWriteArgMem")
539102470Siwasaki      ModRef = ReadWriteArgMem;
540119529Snjl    else if (Property->getName() == "Commutative")
541119529Snjl      isCommutative = true;
542102470Siwasaki    else if (Property->getName() == "Throws")
543102470Siwasaki      canThrow = true;
544102470Siwasaki    else if (Property->getName() == "IntrNoReturn")
54578915Smsmith      isNoReturn = true;
546119529Snjl    else if (Property->isSubClassOf("NoCapture")) {
547119529Snjl      unsigned ArgNo = Property->getValueAsInt("ArgNo");
54878915Smsmith      ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
54978915Smsmith    } else
55078915Smsmith      llvm_unreachable("Unknown property!");
55178915Smsmith  }
55278915Smsmith
55378915Smsmith  // Sort the argument attributes for later benefit.
55478915Smsmith  std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end());
55578915Smsmith}
55691126Smsmith