}
-// NOTE: This must be kept in synch with the version emitted to the .gen file!
+// NOTE: This must be kept in synch with the copy in lib/VMCore/Function.cpp!
enum IIT_Info {
// Common values should be encoded with 0-15.
IIT_Done = 0,
IIT_STRUCT4 = 20,
IIT_STRUCT5 = 21,
IIT_EXTEND_VEC_ARG = 22,
- IIT_TRUNC_VEC_ARG = 23
+ IIT_TRUNC_VEC_ARG = 23,
+ IIT_ANYPTR = 24
};
#pragma optimize("",off) // MSVC 2010 optimizer can't deal with this function.
#endif
-static void EncodeFixedType(Record *R, unsigned &NextArgNo,
+static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
std::vector<unsigned char> &Sig) {
if (R->isSubClassOf("LLVMMatchType")) {
unsigned Number = R->getValueAsInt("Number");
- assert(Number < NextArgNo && "Invalid matching number!");
+ assert(Number < ArgCodes.size() && "Invalid matching number!");
if (R->isSubClassOf("LLVMExtendedElementVectorType"))
Sig.push_back(IIT_EXTEND_VEC_ARG);
else if (R->isSubClassOf("LLVMTruncatedElementVectorType"))
Sig.push_back(IIT_TRUNC_VEC_ARG);
else
Sig.push_back(IIT_ARG);
- return Sig.push_back(Number);
+ return Sig.push_back((Number << 2) | ArgCodes[Number]);
}
MVT::SimpleValueType VT = getValueType(R->getValueAsDef("VT"));
- // If this is an "any" valuetype, then the type is the type of the next
- // type in the list specified to getIntrinsic().
- if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny ||
- VT == MVT::iPTRAny) {
+ unsigned Tmp = 0;
+ switch (VT) {
+ default: break;
+ case MVT::iPTRAny: ++Tmp; // FALL THROUGH.
+ case MVT::vAny: ++Tmp; // FALL THROUGH.
+ case MVT::fAny: ++Tmp; // FALL THROUGH.
+ case MVT::iAny: {
+ // If this is an "any" valuetype, then the type is the type of the next
+ // type in the list specified to getIntrinsic().
Sig.push_back(IIT_ARG);
- return Sig.push_back(NextArgNo++);
+
+ // Figure out what arg # this is consuming, and remember what kind it was.
+ unsigned ArgNo = ArgCodes.size();
+ ArgCodes.push_back(Tmp);
+
+ // Encode what sort of argument it must be in the low 2 bits of the ArgNo.
+ return Sig.push_back((ArgNo << 2) | Tmp);
+ }
+
+ case MVT::iPTR: {
+ unsigned AddrSpace = 0;
+ if (R->isSubClassOf("LLVMQualPointerType")) {
+ AddrSpace = R->getValueAsInt("AddrSpace");
+ assert(AddrSpace < 256 && "Address space exceeds 255");
+ }
+ if (AddrSpace) {
+ Sig.push_back(IIT_ANYPTR);
+ Sig.push_back(AddrSpace);
+ } else {
+ Sig.push_back(IIT_PTR);
+ }
+ return EncodeFixedType(R->getValueAsDef("ElTy"), ArgCodes, Sig);
+ }
}
if (EVT(VT).isVector()) {
return EncodeFixedValueType(VVT.getVectorElementType().
getSimpleVT().SimpleTy, Sig);
}
-
- if (VT == MVT::iPTR) {
- Sig.push_back(IIT_PTR);
- return EncodeFixedType(R->getValueAsDef("ElTy"), NextArgNo, Sig);
- }
-
+
EncodeFixedValueType(VT, Sig);
}
/// intrinsic into 32 bits, return it. If not, return ~0U.
static void ComputeFixedEncoding(const CodeGenIntrinsic &Int,
std::vector<unsigned char> &TypeSig) {
- unsigned NextArgNo = 0;
+ std::vector<unsigned char> ArgCodes;
if (Int.IS.RetVTs.empty())
TypeSig.push_back(IIT_Done);
}
for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i)
- EncodeFixedType(Int.IS.RetTypeDefs[i], NextArgNo, TypeSig);
+ EncodeFixedType(Int.IS.RetTypeDefs[i], ArgCodes, TypeSig);
}
for (unsigned i = 0, e = Int.IS.ParamTypeDefs.size(); i != e; ++i)
- EncodeFixedType(Int.IS.ParamTypeDefs[i], NextArgNo, TypeSig);
+ EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, TypeSig);
}
void printIITEntry(raw_ostream &OS, unsigned char X) {
void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
raw_ostream &OS) {
- OS << "// Global intrinsic function declaration type table.\n";
- OS << "#ifdef GET_INTRINSTIC_GENERATOR_GLOBAL\n";
- // NOTE: These enums must be kept in sync with the ones above!
- OS << "enum IIT_Info {\n";
- OS << " IIT_Done = 0,\n";
- OS << " IIT_I1 = 1,\n";
- OS << " IIT_I8 = 2,\n";
- OS << " IIT_I16 = 3,\n";
- OS << " IIT_I32 = 4,\n";
- OS << " IIT_I64 = 5,\n";
- OS << " IIT_F32 = 6,\n";
- OS << " IIT_F64 = 7,\n";
- OS << " IIT_V2 = 8,\n";
- OS << " IIT_V4 = 9,\n";
- OS << " IIT_V8 = 10,\n";
- OS << " IIT_V16 = 11,\n";
- OS << " IIT_V32 = 12,\n";
- OS << " IIT_MMX = 13,\n";
- OS << " IIT_PTR = 14,\n";
- OS << " IIT_ARG = 15,\n";
- OS << " IIT_METADATA = 16,\n";
- OS << " IIT_EMPTYSTRUCT = 17,\n";
- OS << " IIT_STRUCT2 = 18,\n";
- OS << " IIT_STRUCT3 = 19,\n";
- OS << " IIT_STRUCT4 = 20,\n";
- OS << " IIT_STRUCT5 = 21,\n";
- OS << " IIT_EXTEND_VEC_ARG = 22,\n";
- OS << " IIT_TRUNC_VEC_ARG = 23\n";
- OS << "};\n\n";
-
-
// If we can compute a 32-bit fixed encoding for this intrinsic, do so and
// capture it in this vector, otherwise store a ~0U.
std::vector<unsigned> FixedEncodings;
LongEncodingTable.layout();
+ OS << "// Global intrinsic function declaration type table.\n";
+ OS << "#ifdef GET_INTRINSIC_GENERATOR_GLOBAL\n";
+
OS << "static const unsigned IIT_Table[] = {\n ";
for (unsigned i = 0, e = FixedEncodings.size(); i != e; ++i) {
LongEncodingTable.emit(OS, printIITEntry);
OS << " 255\n};\n\n";
- OS << "#endif\n\n"; // End of GET_INTRINSTIC_GENERATOR_GLOBAL
+ OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL
}
namespace {