//===----------------------------------------------------------------------===//
#include "CodeGenTarget.h"
+#include "CodeGenIntrinsics.h"
#include "Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
/// getValueType - Return the MCV::ValueType that the specified TableGen record
/// corresponds to.
-MVT::ValueType llvm::getValueType(Record *Rec) {
+MVT::ValueType llvm::getValueType(Record *Rec, const CodeGenTarget *CGT) {
return (MVT::ValueType)Rec->getValueAsInt("Value");
}
std::string llvm::getName(MVT::ValueType T) {
switch (T) {
case MVT::Other: return "UNKNOWN";
- case MVT::i1: return "i1";
- case MVT::i8: return "i8";
- case MVT::i16: return "i16";
- case MVT::i32: return "i32";
- case MVT::i64: return "i64";
- case MVT::i128: return "i128";
- case MVT::f32: return "f32";
- case MVT::f64: return "f64";
- case MVT::f80: return "f80";
- case MVT::f128: return "f128";
- case MVT::Flag: return "Flag";
- case MVT::isVoid:return "void";
- case MVT::v8i8: return "v8i8";
- case MVT::v4i16: return "v4i16";
- case MVT::v2i32: return "v2i32";
- case MVT::v16i8: return "v16i8";
- case MVT::v8i16: return "v8i16";
- case MVT::v4i32: return "v4i32";
- case MVT::v2i64: return "v2i64";
- case MVT::v2f32: return "v2f32";
- case MVT::v4f32: return "v4f32";
- case MVT::v2f64: return "v2f64";
+ case MVT::i1: return "MVT::i1";
+ case MVT::i8: return "MVT::i8";
+ case MVT::i16: return "MVT::i16";
+ case MVT::i32: return "MVT::i32";
+ case MVT::i64: return "MVT::i64";
+ case MVT::i128: return "MVT::i128";
+ case MVT::f32: return "MVT::f32";
+ case MVT::f64: return "MVT::f64";
+ case MVT::f80: return "MVT::f80";
+ case MVT::f128: return "MVT::f128";
+ case MVT::Flag: return "MVT::Flag";
+ case MVT::isVoid:return "MVT::void";
+ case MVT::v8i8: return "MVT::v8i8";
+ case MVT::v4i16: return "MVT::v4i16";
+ case MVT::v2i32: return "MVT::v2i32";
+ case MVT::v16i8: return "MVT::v16i8";
+ case MVT::v8i16: return "MVT::v8i16";
+ case MVT::v4i32: return "MVT::v4i32";
+ case MVT::v2i64: return "MVT::v2i64";
+ case MVT::v2f32: return "MVT::v2f32";
+ case MVT::v4f32: return "MVT::v4f32";
+ case MVT::v2f64: return "MVT::v2f64";
+ case MVT::iPTR: return "TLI.getPointerTy()";
default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
}
}
std::string llvm::getEnumName(MVT::ValueType T) {
switch (T) {
- case MVT::Other: return "Other";
- case MVT::i1: return "i1";
- case MVT::i8: return "i8";
- case MVT::i16: return "i16";
- case MVT::i32: return "i32";
- case MVT::i64: return "i64";
- case MVT::i128: return "i128";
- case MVT::f32: return "f32";
- case MVT::f64: return "f64";
- case MVT::f80: return "f80";
- case MVT::f128: return "f128";
- case MVT::Flag: return "Flag";
- case MVT::isVoid:return "isVoid";
- case MVT::v16i8: return "v16i8";
- case MVT::v8i16: return "v8i16";
- case MVT::v4i32: return "v4i32";
- case MVT::v2i64: return "v2i64";
- case MVT::v2f32: return "v2f32";
- case MVT::v4f32: return "v4f32";
- case MVT::v2f64: return "v2f64";
+ case MVT::Other: return "MVT::Other";
+ case MVT::i1: return "MVT::i1";
+ case MVT::i8: return "MVT::i8";
+ case MVT::i16: return "MVT::i16";
+ case MVT::i32: return "MVT::i32";
+ case MVT::i64: return "MVT::i64";
+ case MVT::i128: return "MVT::i128";
+ case MVT::f32: return "MVT::f32";
+ case MVT::f64: return "MVT::f64";
+ case MVT::f80: return "MVT::f80";
+ case MVT::f128: return "MVT::f128";
+ case MVT::Flag: return "MVT::Flag";
+ case MVT::isVoid:return "MVT::isVoid";
+ case MVT::v8i8: return "MVT::v8i8";
+ case MVT::v4i16: return "MVT::v4i16";
+ case MVT::v2i32: return "MVT::v2i32";
+ case MVT::v16i8: return "MVT::v16i8";
+ case MVT::v8i16: return "MVT::v8i16";
+ case MVT::v4i32: return "MVT::v4i32";
+ case MVT::v2i64: return "MVT::v2i64";
+ case MVT::v2f32: return "MVT::v2f32";
+ case MVT::v4f32: return "MVT::v4f32";
+ case MVT::v2f64: return "MVT::v2f64";
+ case MVT::iPTR: return "TLI.getPointerTy()";
default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
}
}
/// getTarget - Return the current instance of the Target class.
///
-CodeGenTarget::CodeGenTarget() : PointerType(MVT::Other) {
+CodeGenTarget::CodeGenTarget() {
std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
if (Targets.size() == 0)
throw std::string("ERROR: No 'Target' subclasses defined!");
if (Targets.size() != 1)
throw std::string("ERROR: Multiple subclasses of Target defined!");
TargetRec = Targets[0];
-
- // Read in all of the CalleeSavedRegisters.
- CalleeSavedRegisters =TargetRec->getValueAsListOfDefs("CalleeSavedRegisters");
- PointerType = getValueType(TargetRec->getValueAsDef("PointerType"));
}
RegisterClasses.assign(RegClasses.begin(), RegClasses.end());
}
+std::vector<unsigned char> CodeGenTarget::getRegisterVTs(Record *R) const {
+ std::vector<unsigned char> Result;
+ const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
+ for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
+ const CodeGenRegisterClass &RC = RegisterClasses[i];
+ for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
+ if (R == RC.Elements[ei]) {
+ const std::vector<MVT::ValueType> &InVTs = RC.getValueTypes();
+ for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
+ Result.push_back(InVTs[i]);
+ }
+ }
+ }
+ return Result;
+}
+
+
CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
// Rename anonymous register classes.
if (R->getName().size() > 9 && R->getName()[9] == '.') {
RootNodes = R->getValueAsListOfDefs("RootNodes");
}
+//===----------------------------------------------------------------------===//
+// CodeGenIntrinsic Implementation
+//===----------------------------------------------------------------------===//
+
+std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC) {
+ std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
+
+ std::vector<CodeGenIntrinsic> Result;
+
+ // If we are in the context of a target .td file, get the target info so that
+ // we can decode the current intptr_t.
+ CodeGenTarget *CGT = 0;
+ if (Records.getClass("Target") &&
+ Records.getAllDerivedDefinitions("Target").size() == 1)
+ CGT = new CodeGenTarget();
+
+ for (unsigned i = 0, e = I.size(); i != e; ++i)
+ Result.push_back(CodeGenIntrinsic(I[i], CGT));
+ delete CGT;
+ return Result;
+}
+
+CodeGenIntrinsic::CodeGenIntrinsic(Record *R, CodeGenTarget *CGT) {
+ TheDef = R;
+ std::string DefName = R->getName();
+ ModRef = WriteMem;
+
+ if (DefName.size() <= 4 ||
+ std::string(DefName.begin(), DefName.begin()+4) != "int_")
+ throw "Intrinsic '" + DefName + "' does not start with 'int_'!";
+ EnumName = std::string(DefName.begin()+4, DefName.end());
+ if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
+ GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
+ TargetPrefix = R->getValueAsString("TargetPrefix");
+ Name = R->getValueAsString("LLVMName");
+ if (Name == "") {
+ // If an explicit name isn't specified, derive one from the DefName.
+ Name = "llvm.";
+ for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
+ if (EnumName[i] == '_')
+ Name += '.';
+ else
+ Name += EnumName[i];
+ } else {
+ // Verify it starts with "llvm.".
+ if (Name.size() <= 5 ||
+ std::string(Name.begin(), Name.begin()+5) != "llvm.")
+ throw "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!";
+ }
+
+ // If TargetPrefix is specified, make sure that Name starts with
+ // "llvm.<targetprefix>.".
+ if (!TargetPrefix.empty()) {
+ if (Name.size() < 6+TargetPrefix.size() ||
+ std::string(Name.begin()+5, Name.begin()+6+TargetPrefix.size())
+ != (TargetPrefix+"."))
+ throw "Intrinsic '" + DefName + "' does not start with 'llvm." +
+ TargetPrefix + ".'!";
+ }
+
+ // Parse the list of argument types.
+ ListInit *TypeList = R->getValueAsListInit("Types");
+ for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
+ DefInit *DI = dynamic_cast<DefInit*>(TypeList->getElement(i));
+ assert(DI && "Invalid list type!");
+ Record *TyEl = DI->getDef();
+ assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
+ ArgTypes.push_back(TyEl->getValueAsString("TypeVal"));
+
+ if (CGT)
+ ArgVTs.push_back(getValueType(TyEl->getValueAsDef("VT"), CGT));
+ ArgTypeDefs.push_back(TyEl);
+ }
+ if (ArgTypes.size() == 0)
+ throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!";
+
+ // Parse the intrinsic properties.
+ ListInit *PropList = R->getValueAsListInit("Properties");
+ for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
+ DefInit *DI = dynamic_cast<DefInit*>(PropList->getElement(i));
+ assert(DI && "Invalid list type!");
+ Record *Property = DI->getDef();
+ assert(Property->isSubClassOf("IntrinsicProperty") &&
+ "Expected a property!");
+
+ if (Property->getName() == "IntrNoMem")
+ ModRef = NoMem;
+ else if (Property->getName() == "IntrReadArgMem")
+ ModRef = ReadArgMem;
+ else if (Property->getName() == "IntrReadMem")
+ ModRef = ReadMem;
+ else if (Property->getName() == "IntrWriteArgMem")
+ ModRef = WriteArgMem;
+ else if (Property->getName() == "IntrWriteMem")
+ ModRef = WriteMem;
+ else
+ assert(0 && "Unknown property!");
+ }
+}