changeset 1080:44d1c557a07b

Automated merge with http://hg.dsource.org/projects/ldc
author Frits van Bommel <fvbommel wxs.nl>
date Tue, 10 Mar 2009 04:48:54 +0100
parents 9c63438c3207 (current diff) 4e388d9d0e25 (diff)
children 5710440ea420
files
diffstat 3 files changed, 290 insertions(+), 146 deletions(-) [+]
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp	Mon Mar 09 20:11:42 2009 -0600
+++ b/gen/llvmhelpers.cpp	Tue Mar 10 04:48:54 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());
 }
--- a/runtime/import/ldc/intrinsics.di	Mon Mar 09 20:11:42 2009 -0600
+++ b/runtime/import/ldc/intrinsics.di	Tue Mar 10 04:48:54 2009 +0100
@@ -19,11 +19,6 @@
     static assert(false, "This module is only valid for LDC");
 }
 
-version(X86)
-    version = Reals_80Bit;
-else version(X86_64)
-    version = Reals_80Bit;
-
 //
 // CODE GENERATOR INTRINSICS
 //
@@ -106,11 +101,13 @@
 // Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do
 // not return a value, and takes an extra alignment argument.
 
-pragma(intrinsic, "llvm.memcpy.i32")
-    void llvm_memcpy_i32(void* dst, void* src, uint len, uint alignment);
+pragma(intrinsic, "llvm.memcpy.i#")
+    void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment);
 
-pragma(intrinsic, "llvm.memcpy.i64")
-    void llvm_memcpy_i64(void* dst, void* src, ulong len, uint alignment);
+deprecated {
+    alias llvm_memcpy!(uint)  llvm_memcpy_i32;
+    alias llvm_memcpy!(ulong) llvm_memcpy_i64;
+}
 
 
 // The 'llvm.memmove.*' intrinsics move a block of memory from the source
@@ -119,11 +116,13 @@
 // Note that, unlike the standard libc function, the llvm.memmove.* intrinsics
 // do not return a value, and takes an extra alignment argument.
 
-pragma(intrinsic, "llvm.memmove.i32")
-    void llvm_memmove_i32(void* dst, void* src, uint len, uint alignment);
+pragma(intrinsic, "llvm.memmove.i#")
+    void llvm_memmove(T)(void* dst, void* src, T len, uint alignment);
 
-pragma(intrinsic, "llvm.memmove.i64")
-    void llvm_memmove_i64(void* dst, void* src, ulong len, int alignment);
+deprecated {
+    alias llvm_memmove!(uint)  llvm_memmove_i32;
+    alias llvm_memmove!(ulong) llvm_memmove_i64;
+}
 
 
 // The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte
@@ -131,11 +130,13 @@
 // Note that, unlike the standard libc function, the llvm.memset intrinsic does
 // not return a value, and takes an extra alignment argument.
 
-pragma(intrinsic, "llvm.memset.i32")
-    void llvm_memset_i32(void* dst, ubyte val, uint len, uint alignment);
+pragma(intrinsic, "llvm.memset.i#")
+    void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment);
 
-pragma(intrinsic, "llvm.memset.i64")
-    void llvm_memset_i64(void* dst, ubyte val, ulong len, uint alignment);
+deprecated {
+    alias llvm_memset!(uint)  llvm_memset_i32;
+    alias llvm_memset!(ulong) llvm_memset_i64;
+}
 
 
 // The 'llvm.sqrt' intrinsics return the sqrt of the specified operand,
@@ -145,64 +146,37 @@
 // worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like
 // IEEE sqrt.
 
-pragma(intrinsic, "llvm.sqrt.f32")
-    float llvm_sqrt_f32(float val);
-
-pragma(intrinsic, "llvm.sqrt.f64")
-    double llvm_sqrt_f64(double val);
+pragma(intrinsic, "llvm.sqrt.f#")
+    T llvm_sqrt(T)(T val);
 
-version(Reals_80Bit)
-{
-    pragma(intrinsic, "llvm.sqrt.f80")
-        real llvm_sqrt_f80(real val);
-    alias llvm_sqrt_f80 llvm_sqrt_real;
-}
-else
-{
-    pragma(intrinsic, "llvm.sqrt.f64")
-        real llvm_sqrt_real(real val);
+deprecated {
+    alias llvm_sqrt!(float)  llvm_sqrt_f32;
+    alias llvm_sqrt!(double) llvm_sqrt_f64;
+    alias llvm_sqrt!(real)   llvm_sqrt_f80;     // may not actually be .f80
 }
 
 
 // The 'llvm.sin.*' intrinsics return the sine of the operand.
 
-pragma(intrinsic, "llvm.sin.f32")
-    float llvm_sin_f32(float val);
-
-pragma(intrinsic, "llvm.sin.f64")
-    double llvm_sin_f64(double val);
+pragma(intrinsic, "llvm.sin.f#")
+    T llvm_sin(T)(T val);
 
-version(Reals_80Bit)
-{
-    pragma(intrinsic, "llvm.sin.f80")
-        real llvm_sin_f80(real val);
-    alias llvm_sin_f80 llvm_sin_real;
-}
-else
-{
-    pragma(intrinsic, "llvm.sin.f64")
-        real llvm_sin_real(real val);
+deprecated {
+    alias llvm_sin!(float)  llvm_sin_f32;
+    alias llvm_sin!(double) llvm_sin_f64;
+    alias llvm_sin!(real)   llvm_sin_f80;       // may not actually be .f80
 }
 
 
 // The 'llvm.cos.*' intrinsics return the cosine of the operand.
 
-pragma(intrinsic, "llvm.cos.f32")
-    float llvm_cos_f32(float val);
-
-pragma(intrinsic, "llvm.cos.f64")
-    double llvm_cos_f64(double val);
+pragma(intrinsic, "llvm.cos.f#")
+    T llvm_cos(T)(T val);
 
-version(Reals_80Bit)
-{
-    pragma(intrinsic, "llvm.cos.f80")
-        real llvm_cos_f80(real val);
-    alias llvm_cos_f80 llvm_cos_real;
-}
-else
-{
-    pragma(intrinsic, "llvm.cos.f64")
-        real llvm_cos_real(real val);
+deprecated {
+    alias llvm_cos!(float)  llvm_cos_f32;
+    alias llvm_cos!(double) llvm_cos_f64;
+    alias llvm_cos!(real)   llvm_cos_f80;       // may not actually be .f80
 }
 
 
@@ -211,44 +185,26 @@
 // not defined. When a vector of floating point type is used, the second
 // argument remains a scalar integer value.
 
-pragma(intrinsic, "llvm.powi.f32")
-    float llvm_powi_f32(float val, int power);
-
-pragma(intrinsic, "llvm.powi.f64")
-    double llvm_powi_f64(double val, int power);
+pragma(intrinsic, "llvm.powi.f#")
+    T llvm_powi(T)(T val, int power);
 
-version(Reals_80Bit)
-{
-    pragma(intrinsic, "llvm.powi.f80")
-        real llvm_powi_f80(real val, int power);
-    alias llvm_powi_f80 llvm_powi_real;
-}
-else
-{
-    pragma(intrinsic, "llvm.powi.f64")
-        real llvm_powi_real(real val, int power);
+deprecated {
+    alias llvm_powi!(float)  llvm_powi_f32;
+    alias llvm_powi!(double) llvm_powi_f64;
+    alias llvm_powi!(real)   llvm_powi_f80;     // may not actually be .f80
 }
 
 
 // The 'llvm.pow.*' intrinsics return the first operand raised to the specified
 // (positive or negative) power.
 
-pragma(intrinsic, "llvm.pow.f32")
-    float llvm_pow_f32(float val, float power);
-
-pragma(intrinsic, "llvm.pow.f64")
-    double llvm_pow_f64(double val, double power);
+pragma(intrinsic, "llvm.pow.f#")
+    T llvm_pow(T)(T val, T power);
 
-version(Reals_80Bit)
-{
-    pragma(intrinsic, "llvm.pow.f80")
-        real llvm_pow_f80(real val, real power);
-    alias llvm_pow_f80 llvm_pow_real;
-}
-else
-{
-    pragma(intrinsic, "llvm.pow.f64")
-        real llvm_pow_real(real val, real power);
+deprecated {
+    alias llvm_pow!(float)  llvm_pow_f32;
+    alias llvm_pow!(double) llvm_pow_f64;
+    alias llvm_pow!(real)   llvm_pow_f80;       // may not actually be .f80
 }
 
 
@@ -261,79 +217,71 @@
 // useful for performing operations on data that is not in the target's native
 // byte order.
 
-pragma(intrinsic, "llvm.bswap.i16.i16")
-    ushort llvm_bswap_i16(ushort val);
+pragma(intrinsic, "llvm.bswap.i#.i#")
+    T llvm_bswap(T)(T val);
 
-pragma(intrinsic, "llvm.bswap.i32.i32")
-    uint llvm_bswap_i32(uint val);
-
-pragma(intrinsic, "llvm.bswap.i64.i64")
-    ulong llvm_bswap_i64(ulong val);
+deprecated {
+    alias llvm_bswap!(ushort) llvm_bswap_i16;
+    alias llvm_bswap!(uint)   llvm_bswap_i32;
+    alias llvm_bswap!(ulong)  llvm_bswap_i64;
+}
 
 
 // The 'llvm.ctpop' family of intrinsics counts the number of bits set in a
 // value.
 
-pragma(intrinsic, "llvm.ctpop.i8")
-    ubyte llvm_ctpop_i8(ubyte src);
-
-pragma(intrinsic, "llvm.ctpop.i16")
-    ushort llvm_ctpop_i16(ushort src);
+pragma(intrinsic, "llvm.ctpop.i#")
+    T llvm_ctpop(T)(T src);
 
-pragma(intrinsic, "llvm.ctpop.i32")
-    uint llvm_ctpop_i32(uint src);
-
-pragma(intrinsic, "llvm.ctpop.i64")
-    ulong llvm_ctpop_i64(ulong src);
+deprecated {
+    alias llvm_ctpop!(ubyte)  llvm_ctpop_i8;
+    alias llvm_ctpop!(ushort) llvm_ctpop_i16;
+    alias llvm_ctpop!(uint)   llvm_ctpop_i32;
+    alias llvm_ctpop!(ulong)  llvm_ctpop_i64;
+}
 
 
 // The 'llvm.ctlz' family of intrinsic functions counts the number of leading
 // zeros in a variable.
 
-pragma(intrinsic, "llvm.ctlz.i8")
-    ubyte llvm_ctlz_i8(ubyte src);
-
-pragma(intrinsic, "llvm.ctlz.i16")
-    ushort llvm_ctlz_i16(ushort src);
+pragma(intrinsic, "llvm.ctlz.i#")
+    T llvm_ctlz(T)(T src);
 
-pragma(intrinsic, "llvm.ctlz.i32")
-    uint llvm_ctlz_i32(uint src);
-
-pragma(intrinsic, "llvm.ctlz.i64")
-    ulong llvm_ctlz_i64(ulong src);
+deprecated {
+    alias llvm_ctlz!(ubyte)  llvm_ctlz_i8;
+    alias llvm_ctlz!(ushort) llvm_ctlz_i16;
+    alias llvm_ctlz!(uint)   llvm_ctlz_i32;
+    alias llvm_ctlz!(ulong)  llvm_ctlz_i64;
+}
 
 
 // The 'llvm.cttz' family of intrinsic functions counts the number of trailing
 // zeros.
 
-pragma(intrinsic, "llvm.cttz.i8")
-    ubyte llvm_cttz_i8(ubyte src);
-
-pragma(intrinsic, "llvm.cttz.i16")
-    ushort llvm_cttz_i16(ushort src);
+pragma(intrinsic, "llvm.cttz.i#")
+    T llvm_cttz(T)(T src);
 
-pragma(intrinsic, "llvm.cttz.i32")
-    uint llvm_cttz_i32(uint src);
-
-pragma(intrinsic, "llvm.cttz.i64")
-    ulong llvm_cttz_i64(ulong src);
+deprecated {
+    alias llvm_cttz!(ubyte)  llvm_cttz_i8;
+    alias llvm_cttz!(ushort) llvm_cttz_i16;
+    alias llvm_cttz!(uint)   llvm_cttz_i32;
+    alias llvm_cttz!(ulong)  llvm_cttz_i64;
+}
 
 
 // The 'llvm.part.select' family of intrinsic functions selects a range of bits
 // from an integer value and returns them in the same bit width as the original
 // value.
 
-pragma(intrinsic, "llvm.part.select.i8")
-    ubyte llvm_part_select_i(ubyte val, uint loBit, uint hiBit);
-
-pragma(intrinsic, "llvm.part.select.i16")
-    ushort llvm_part_select_i(ushort val, uint loBit, uint hiBit);
+pragma(intrinsic, "llvm.part.select.i#")
+    T llvm_part_select(T)(T val, uint loBit, uint hiBit);
 
-pragma(intrinsic, "llvm.part.select.i32")
-    uint llvm_part_select_i(uint val, uint loBit, uint hiBit);
-
-pragma(intrinsic, "llvm.part.select.i64")
-    ulong llvm_part_select_i(ulong val, uint loBit, uint hiBit);
+deprecated {
+    alias llvm_part_select!(ubyte)  llvm_part_select_i;
+    alias llvm_part_select!(ushort) llvm_part_select_i;
+    alias llvm_part_select!(uint)   llvm_part_select_i;
+    alias llvm_part_select!(ulong)  llvm_part_select_i;
+}
 
 
 // The 'llvm.part.set' family of intrinsic functions replaces a range of bits
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango.patch	Tue Mar 10 04:48:54 2009 +0100
@@ -0,0 +1,178 @@
+Index: tango/tango/math/Math.d
+===================================================================
+--- tango/tango/math/Math.d	(revision 4388)
++++ tango/tango/math/Math.d	(working copy)
+@@ -80,13 +80,9 @@
+ } else version(D_InlineAsm_X86) {
+     version = Naked_D_InlineAsm_X86;
+ }
+-else version(LDC)
++version(LDC)
+ {
+     import ldc.intrinsics;
+-    version(X86)
+-    {
+-        version = LDC_X86;
+-    }
+ }
+ 
+ /*
+@@ -312,26 +308,12 @@
+  *      Results are undefined if |x| >= $(POWER 2,64).
+  */
+ 
+-version(LDC)
++real cos(real x) /* intrinsic */
+ {
+-    alias llvm_cos_f32 cos;
+-    alias llvm_cos_f64 cos;
+-    version(X86)
++    version(LDC)
+     {
+-        alias llvm_cos_f80 cos;
++        return llvm_cos(x);
+     }
+-    else
+-    {
+-        real cos(real x)
+-        {
+-            return tango.stdc.math.cosl(x);
+-        }
+-    }
+-}
+-else
+-{
+-real cos(real x) /* intrinsic */
+-{
+     version(D_InlineAsm_X86)
+     {
+         asm
+@@ -345,7 +327,6 @@
+         return tango.stdc.math.cosl(x);
+     }
+ }
+-}
+ 
+ debug(UnitTest) {
+ unittest {
+@@ -366,26 +347,12 @@
+  * Bugs:
+  *      Results are undefined if |x| >= $(POWER 2,64).
+  */
+-version(LDC)
++real sin(real x) /* intrinsic */
+ {
+-    alias llvm_sin_f32 sin;
+-    alias llvm_sin_f64 sin;
+-    version(X86)
++    version(LDC)
+     {
+-        alias llvm_sin_f80 sin;
++        return llvm_sin(x);
+     }
+-    else
+-    {
+-        real sin(real x)
+-        {
+-            return tango.stdc.math.sinl(x);
+-        }
+-    }
+-}
+-else
+-{
+-real sin(real x) /* intrinsic */
+-{
+     version(D_InlineAsm_X86)
+     {
+         asm
+@@ -399,7 +366,6 @@
+         return tango.stdc.math.sinl(x);
+     }
+ }
+-}
+ 
+ debug(UnitTest) {
+ unittest {
+@@ -999,29 +965,14 @@
+  *      $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no))
+  *      )
+  */
+-version(LDC)
++float sqrt(float x) /* intrinsic */
+ {
+-    alias llvm_sqrt_f32 sqrt;
+-    alias llvm_sqrt_f64 sqrt;
+-    version(X86)
++    version(LDC)
+     {
+-        alias llvm_sqrt_f80 sqrt;
++        return llvm_sqrt(x);
+     }
+-    else
++    else version(D_InlineAsm_X86)
+     {
+-        real sqrt(real x)
+-        {
+-            return tango.stdc.math.sqrtl(x);
+-        }
+-    }
+-}
+-else
+-{
+-
+-float sqrt(float x) /* intrinsic */
+-{
+-    version(D_InlineAsm_X86)
+-    {
+         asm
+         {
+             fld x;
+@@ -1036,8 +987,12 @@
+ 
+ double sqrt(double x) /* intrinsic */ /// ditto
+ {
+-    version(D_InlineAsm_X86)
++    version(LDC)
+     {
++        return llvm_sqrt(x);
++    }
++    else version(D_InlineAsm_X86)
++    {
+         asm
+         {
+             fld x;
+@@ -1052,8 +1007,12 @@
+ 
+ real sqrt(real x) /* intrinsic */ /// ditto
+ {
+-    version(D_InlineAsm_X86)
++    version(LDC)
+     {
++        return llvm_sqrt(x);
++    }
++    else version(D_InlineAsm_X86)
++    {
+         asm
+         {
+             fld x;
+@@ -1066,8 +1025,6 @@
+     }
+ }
+ 
+-}
+-
+ /** ditto */
+ creal sqrt(creal z)
+ {
+@@ -1714,9 +1671,9 @@
+         }
+     }
+     }
+-    version(LDC_X86)
++    version(LDC)
+     {
+-        return llvm_pow_f80(x, y);
++        return llvm_pow(x, y);
+     }
+     else
+     {