diff gen/llvmhelpers.cpp @ 1079:4e388d9d0e25

Intrinsics overhaul: - More error checking for pragma(intrinsic) - Properly handle templating for real (use actual nr of bits, not .sizeof * 8) - Template all .i* and .f* intrinsics - The old names are deprecated aliases now I also added a preliminary patch to make tango.math.Math use the new versions. (I think it looks a lot nicer now)
author Frits van Bommel <fvbommel wxs.nl>
date Tue, 10 Mar 2009 04:45:32 +0100
parents 7ce8355fbcc6
children a08983bf972e
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp	Mon Mar 09 21:38:31 2009 +0100
+++ b/gen/llvmhelpers.cpp	Tue Mar 10 04:45:32 2009 +0100
@@ -1516,19 +1516,37 @@
     assert(ti->tdtypes.dim == 1);
     Type* T = (Type*)ti->tdtypes.data[0];
 
-    char tmp[10];
-    if (T->toBasetype()->ty == Tbool) // otherwise we'd get a mismatch
-        sprintf(tmp, "1");
-    else
-        sprintf(tmp, "%lu", T->size()*8);
+    char prefix = T->isreal() ? 'f' : T->isintegral() ? 'i' : 0;
+    if (!prefix) {
+        ti->error("has invalid template parameter for intrinsic: %s", T->toChars());
+        fatal(); // or LLVM asserts
+    }
+
+    char tmp[21]; // probably excessive, but covers a uint64_t
+    sprintf(tmp, "%lu", gTargetData->getTypeSizeInBits(DtoType(T)));
     
     // replace # in name with bitsize
     name = td->intrinsicName;
 
     std::string needle("#");
     size_t pos;
-    while(std::string::npos != (pos = name.find(needle)))
-        name.replace(pos, 1, tmp);
+    while(std::string::npos != (pos = name.find(needle))) {
+        if (pos > 0 && name[pos-1] == prefix) {
+            // Properly prefixed, insert bitwidth.
+            name.replace(pos, 1, tmp);
+        } else {
+            if (pos && (name[pos-1] == 'i' || name[pos-1] == 'f')) {
+                // Wrong type character.
+                ti->error("has invalid parameter type for intrinsic %s: %s is not a%s type",
+                    name.c_str(), T->toChars(),
+                    (name[pos-1] == 'i' ? "n integral" : " floating-point"));
+            } else {
+                // Just plain wrong.
+                ti->error("has an invalid intrinsic name: %s", name.c_str());
+            }
+            fatal(); // or LLVM asserts
+        }
+    }
     
     Logger::println("final intrinsic name: %s", name.c_str());
 }