move some code around so that Verifier.cpp can get access to the intrinsic info table.
[oota-llvm.git] / utils / TableGen / IntrinsicEmitter.cpp
index c6acddf9dd2c78e6100e416cd4378d472975b122..9c024a4981aff6a5f9cd7463acdcf386ce4ce299 100644 (file)
@@ -310,7 +310,7 @@ void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints,
 }
 
 
 }
 
 
-// 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,
 enum IIT_Info {
   // Common values should be encoded with 0-15.
   IIT_Done = 0,
@@ -338,7 +338,8 @@ enum IIT_Info {
   IIT_STRUCT4 = 20,
   IIT_STRUCT5 = 21,
   IIT_EXTEND_VEC_ARG = 22,
   IIT_STRUCT4 = 20,
   IIT_STRUCT5 = 21,
   IIT_EXTEND_VEC_ARG = 22,
-  IIT_TRUNC_VEC_ARG = 23
+  IIT_TRUNC_VEC_ARG = 23,
+  IIT_ANYPTR = 24
 };
 
 
 };
 
 
@@ -371,29 +372,56 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT,
 #pragma optimize("",off) // MSVC 2010 optimizer can't deal with this function.
 #endif 
 
 #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");
                             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);
     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"));
 
   }
   
   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);
     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()) {
   }
   
   if (EVT(VT).isVector()) {
@@ -410,12 +438,7 @@ static void EncodeFixedType(Record *R, unsigned &NextArgNo,
     return EncodeFixedValueType(VVT.getVectorElementType().
                                 getSimpleVT().SimpleTy, Sig);
   }
     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);
 }
 
   EncodeFixedValueType(VT, Sig);
 }
 
@@ -427,7 +450,7 @@ static void EncodeFixedType(Record *R, unsigned &NextArgNo,
 /// intrinsic into 32 bits, return it.  If not, return ~0U.
 static void ComputeFixedEncoding(const CodeGenIntrinsic &Int,
                                  std::vector<unsigned char> &TypeSig) {
 /// 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);
   
   if (Int.IS.RetVTs.empty())
     TypeSig.push_back(IIT_Done);
@@ -445,11 +468,11 @@ static void ComputeFixedEncoding(const CodeGenIntrinsic &Int,
     }
     
     for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i)
     }
     
     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)
   }
   
   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 printIITEntry(raw_ostream &OS, unsigned char X) {
@@ -458,37 +481,6 @@ void printIITEntry(raw_ostream &OS, unsigned char X) {
 
 void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 
                                      raw_ostream &OS) {
 
 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;
   // 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;
@@ -534,6 +526,9 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
   
   LongEncodingTable.layout();
   
   
   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) {
   OS << "static const unsigned IIT_Table[] = {\n  ";
   
   for (unsigned i = 0, e = FixedEncodings.size(); i != e; ++i) {
@@ -563,7 +558,7 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
     LongEncodingTable.emit(OS, printIITEntry);
   OS << "  255\n};\n\n";
   
     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 {
 }
 
 namespace {