# HG changeset patch # User Frits van Bommel # Date 1236656934 -3600 # Node ID 44d1c557a07bfa0248d9fba7dbb17f007bb51685 # Parent 9c63438c320746b54555c7de040c290cfe9daf9b# Parent 4e388d9d0e25ad50b9849b2d0766833290c417c0 Automated merge with http://hg.dsource.org/projects/ldc diff -r 9c63438c3207 -r 44d1c557a07b gen/llvmhelpers.cpp --- 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()); } diff -r 9c63438c3207 -r 44d1c557a07b runtime/import/ldc/intrinsics.di --- 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 diff -r 9c63438c3207 -r 44d1c557a07b tango.patch --- /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 + {