#include "Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Streams.h"
#include <algorithm>
using namespace llvm;
std::string llvm::getName(MVT::SimpleValueType T) {
switch (T) {
- case MVT::Other: return "UNKNOWN";
- 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::iAny: return "MVT::iAny";
- case MVT::fAny: return "MVT::fAny";
- 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::ppcf128: return "MVT::ppcf128";
- 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::v1i64: return "MVT::v1i64";
- 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::v3i32: return "MVT::v3i32";
- case MVT::v3f32: return "MVT::v3f32";
- case MVT::iPTR: return "TLI.getPointerTy()";
- case MVT::iPTRAny: return "TLI.getPointerTy()";
- default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
+ case MVT::Other: return "UNKNOWN";
+ case MVT::iPTR: return "TLI.getPointerTy()";
+ case MVT::iPTRAny: return "TLI.getPointerTy()";
+ default: return getEnumName(T);
}
}
case MVT::ppcf128: return "MVT::ppcf128";
case MVT::Flag: return "MVT::Flag";
case MVT::isVoid:return "MVT::isVoid";
+ case MVT::v2i8: return "MVT::v2i8";
+ case MVT::v4i8: return "MVT::v4i8";
case MVT::v8i8: return "MVT::v8i8";
- case MVT::v4i16: return "MVT::v4i16";
- case MVT::v2i32: return "MVT::v2i32";
- case MVT::v1i64: return "MVT::v1i64";
case MVT::v16i8: return "MVT::v16i8";
+ case MVT::v32i8: return "MVT::v32i8";
+ case MVT::v2i16: return "MVT::v2i16";
+ case MVT::v4i16: return "MVT::v4i16";
case MVT::v8i16: return "MVT::v8i16";
+ case MVT::v16i16: return "MVT::v16i16";
+ case MVT::v2i32: return "MVT::v2i32";
case MVT::v4i32: return "MVT::v4i32";
+ case MVT::v8i32: return "MVT::v8i32";
+ case MVT::v1i64: return "MVT::v1i64";
case MVT::v2i64: return "MVT::v2i64";
+ case MVT::v4i64: return "MVT::v4i64";
case MVT::v2f32: return "MVT::v2f32";
case MVT::v4f32: return "MVT::v4f32";
+ case MVT::v8f32: return "MVT::v8f32";
case MVT::v2f64: return "MVT::v2f64";
- case MVT::v3i32: return "MVT::v3i32";
- case MVT::v3f32: return "MVT::v3f32";
+ case MVT::v4f64: return "MVT::v4f64";
+ case MVT::Metadata: return "MVT::Metadata";
case MVT::iPTR: return "MVT::iPTR";
case MVT::iPTRAny: return "MVT::iPTRAny";
default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
if (I == Instructions.end())
throw "Could not find 'SUBREG_TO_REG' instruction!";
const CodeGenInstruction *SUBREG_TO_REG = &I->second;
-
+
+ I = getInstructions().find("COPY_TO_REGCLASS");
+ if (I == Instructions.end())
+ throw "Could not find 'COPY_TO_REGCLASS' instruction!";
+ const CodeGenInstruction *COPY_TO_REGCLASS = &I->second;
+
// Print out the rest of the instructions now.
NumberedInstructions.push_back(PHI);
NumberedInstructions.push_back(INLINEASM);
NumberedInstructions.push_back(INSERT_SUBREG);
NumberedInstructions.push_back(IMPLICIT_DEF);
NumberedInstructions.push_back(SUBREG_TO_REG);
+ NumberedInstructions.push_back(COPY_TO_REGCLASS);
for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II)
if (&II->second != PHI &&
&II->second != INLINEASM &&
&II->second != EXTRACT_SUBREG &&
&II->second != INSERT_SUBREG &&
&II->second != IMPLICIT_DEF &&
- &II->second != SUBREG_TO_REG)
+ &II->second != SUBREG_TO_REG &&
+ &II->second != COPY_TO_REGCLASS)
NumberedInstructions.push_back(&II->second);
}
} else if (PropList[i]->getName() == "SDNPMemOperand") {
Properties |= 1 << SDNPMemOperand;
} else {
- cerr << "Unsupported SD Node property '" << PropList[i]->getName()
- << "' on ComplexPattern '" << R->getName() << "'!\n";
+ errs() << "Unsupported SD Node property '" << PropList[i]->getName()
+ << "' on ComplexPattern '" << R->getName() << "'!\n";
exit(1);
}
if (PropList[i]->getName() == "CPAttrParentAsRoot") {
Attributes |= 1 << CPAttrParentAsRoot;
} else {
- cerr << "Unsupported pattern attribute '" << PropList[i]->getName()
- << "' on ComplexPattern '" << R->getName() << "'!\n";
+ errs() << "Unsupported pattern attribute '" << PropList[i]->getName()
+ << "' on ComplexPattern '" << R->getName() << "'!\n";
exit(1);
}
}
// CodeGenIntrinsic Implementation
//===----------------------------------------------------------------------===//
-std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC) {
+std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
+ bool TargetOnly) {
std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
std::vector<CodeGenIntrinsic> Result;
- for (unsigned i = 0, e = I.size(); i != e; ++i)
- Result.push_back(CodeGenIntrinsic(I[i]));
+ for (unsigned i = 0, e = I.size(); i != e; ++i) {
+ bool isTarget = I[i]->getValueAsBit("isTarget");
+ if (isTarget == TargetOnly)
+ Result.push_back(CodeGenIntrinsic(I[i]));
+ }
return Result;
}
}
// Parse the list of return types.
+ std::vector<MVT::SimpleValueType> OverloadedVTs;
ListInit *TypeList = R->getValueAsListInit("RetTypes");
for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
- MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
- isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
+ MVT::SimpleValueType VT;
+ if (TyEl->isSubClassOf("LLVMMatchType")) {
+ unsigned MatchTy = TyEl->getValueAsInt("Number");
+ assert(MatchTy < OverloadedVTs.size() &&
+ "Invalid matching number!");
+ VT = OverloadedVTs[MatchTy];
+ // It only makes sense to use the extended and truncated vector element
+ // variants with iAny types; otherwise, if the intrinsic is not
+ // overloaded, all the types can be specified directly.
+ assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+ !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+ VT == MVT::iAny) && "Expected iAny type");
+ } else {
+ VT = getValueType(TyEl->getValueAsDef("VT"));
+ }
+ if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny) {
+ OverloadedVTs.push_back(VT);
+ isOverloaded |= true;
+ }
IS.RetVTs.push_back(VT);
IS.RetTypeDefs.push_back(TyEl);
}
for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
Record *TyEl = TypeList->getElementAsRecord(i);
assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
- MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
- isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
+ MVT::SimpleValueType VT;
+ if (TyEl->isSubClassOf("LLVMMatchType")) {
+ unsigned MatchTy = TyEl->getValueAsInt("Number");
+ assert(MatchTy < OverloadedVTs.size() &&
+ "Invalid matching number!");
+ VT = OverloadedVTs[MatchTy];
+ // It only makes sense to use the extended and truncated vector element
+ // variants with iAny types; otherwise, if the intrinsic is not
+ // overloaded, all the types can be specified directly.
+ assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+ !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+ VT == MVT::iAny) && "Expected iAny type");
+ } else
+ VT = getValueType(TyEl->getValueAsDef("VT"));
+ if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny) {
+ OverloadedVTs.push_back(VT);
+ isOverloaded |= true;
+ }
IS.ParamVTs.push_back(VT);
IS.ParamTypeDefs.push_back(TyEl);
}
ModRef = WriteMem;
else if (Property->getName() == "Commutative")
isCommutative = true;
- else
+ else if (Property->isSubClassOf("NoCapture")) {
+ unsigned ArgNo = Property->getValueAsInt("ArgNo");
+ ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
+ } else
assert(0 && "Unknown property!");
}
}