From 018730326d878d98b85b1256ff220e76665ed97e Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sat, 25 Apr 2020 02:19:04 +0200 Subject: [PATCH] d: Merge upstream dmd 09db0c41e, druntime e68a5ae3. * New core.math.toPrec templates have been added as an intrinsic. Some floating point algorithms, such as Kahan-Babuska-Neumaier Summation, require rounding to specific precisions. Rounding to precision after every operation, however, loses overall precision in the general case and is a runtime performance problem. Adding these functions guarantee the rounding at required points in the code, and document where in the algorithm the requirement exists. * Support IBM long double types in core.internal.convert. * Add missing aliases for 64-bit vectors in core.simd. * RUNNABLE_PHOBOS_TEST directive has been properly integrated into the D2 language testsuite. Reviewed-on: https://github.com/dlang/druntime/pull/3063 https://github.com/dlang/dmd/pull/11054 gcc/d/ChangeLog: * intrinsics.cc (expand_intrinsic_toprec): New function. (maybe_expand_intrinsic): Handle toPrec intrinsics. * intrinsics.def (TOPRECF, TOPREC, TOPRECL): Add toPrec intrinsics. --- gcc/d/ChangeLog | 6 + gcc/d/dmd/MERGE | 2 +- gcc/d/intrinsics.cc | 22 +++ gcc/d/intrinsics.def | 3 + .../gdc.test/compilable/interpret3.d | 16 ++ gcc/testsuite/gdc.test/runnable/builtin.d | 2 +- gcc/testsuite/gdc.test/runnable/complex.d | 2 +- gcc/testsuite/gdc.test/runnable/constfold.d | 3 +- gcc/testsuite/gdc.test/runnable/foreach4.d | 3 +- gcc/testsuite/gdc.test/runnable/ifti.d | 2 +- gcc/testsuite/gdc.test/runnable/implicit.d | 3 +- gcc/testsuite/gdc.test/runnable/inner.d | 3 +- gcc/testsuite/gdc.test/runnable/interpret.d | 47 ++++- gcc/testsuite/gdc.test/runnable/issue8671.d | 2 +- gcc/testsuite/gdc.test/runnable/lazy.d | 2 +- gcc/testsuite/gdc.test/runnable/mars1.d | 2 +- gcc/testsuite/gdc.test/runnable/mixin1.d | 3 +- gcc/testsuite/gdc.test/runnable/mixin2.d | 2 +- gcc/testsuite/gdc.test/runnable/s2ir.d | 3 +- gcc/testsuite/gdc.test/runnable/stress.d | 2 +- gcc/testsuite/gdc.test/runnable/template4.d | 2 +- gcc/testsuite/gdc.test/runnable/template9.d | 2 +- gcc/testsuite/gdc.test/runnable/test10942.d | 2 +- gcc/testsuite/gdc.test/runnable/test11.d | 2 +- gcc/testsuite/gdc.test/runnable/test12.d | 2 +- gcc/testsuite/gdc.test/runnable/test12197.d | 2 +- gcc/testsuite/gdc.test/runnable/test15.d | 2 +- gcc/testsuite/gdc.test/runnable/test22.d | 2 +- gcc/testsuite/gdc.test/runnable/test23.d | 2 +- gcc/testsuite/gdc.test/runnable/test24.d | 2 +- gcc/testsuite/gdc.test/runnable/test27.d | 2 +- gcc/testsuite/gdc.test/runnable/test28.d | 2 +- gcc/testsuite/gdc.test/runnable/test34.d | 3 +- gcc/testsuite/gdc.test/runnable/test37.d | 2 +- gcc/testsuite/gdc.test/runnable/test42.d | 3 +- gcc/testsuite/gdc.test/runnable/test5305.d | 2 +- gcc/testsuite/gdc.test/runnable/test60.d | 2 +- gcc/testsuite/gdc.test/runnable/testaa.d | 2 +- .../gdc.test/runnable/testbitarray.d | 2 +- gcc/testsuite/gdc.test/runnable/testdstress.d | 2 +- gcc/testsuite/gdc.test/runnable/testfile.d | 2 +- gcc/testsuite/gdc.test/runnable/testformat.d | 2 +- gcc/testsuite/gdc.test/runnable/testline.d | 2 +- gcc/testsuite/gdc.test/runnable/testmmfile.d | 2 +- gcc/testsuite/gdc.test/runnable/testscope2.d | 2 +- gcc/testsuite/gdc.test/runnable/testsignals.d | 2 +- gcc/testsuite/gdc.test/runnable/testsocket.d | 2 +- gcc/testsuite/gdc.test/runnable/teststdio.d | 2 +- gcc/testsuite/gdc.test/runnable/testthread2.d | 2 +- gcc/testsuite/gdc.test/runnable/testtypeid.d | 3 +- gcc/testsuite/gdc.test/runnable/traits.d | 2 +- gcc/testsuite/gdc.test/runnable/wc.d | 2 +- gcc/testsuite/gdc.test/runnable/wc2.d | 2 +- gcc/testsuite/gdc.test/runnable/wc3.d | 2 +- gcc/testsuite/gdc.test/runnable/xtest46.d | 2 +- gcc/testsuite/gdc.test/runnable/xtest55.d | 2 +- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/cpuid.d | 2 +- libphobos/libdruntime/core/internal/convert.d | 170 ++++++++++++------ libphobos/libdruntime/core/math.d | 71 ++++++++ libphobos/libdruntime/core/simd.d | 6 +- 61 files changed, 335 insertions(+), 121 deletions(-) diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index b96f0ffb82f..7bb38a8b0e7 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,9 @@ +2020-04-25 Iain Buclaw + + * intrinsics.cc (expand_intrinsic_toprec): New function. + (maybe_expand_intrinsic): Handle toPrec intrinsics. + * intrinsics.def (TOPRECF, TOPREC, TOPRECL): Add toPrec intrinsics. + 2020-04-24 Iain Buclaw * d-spec.cc (need_phobos): Remove. diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 155286dd765..a878cb9f42e 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -62ce36f3737de691217c21f0173f411734eb1d43 +09db0c41ee922502fa0966bde24c1cb9b15ad436 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc index 9a9fd41727f..c7bde88e5cd 100644 --- a/gcc/d/intrinsics.cc +++ b/gcc/d/intrinsics.cc @@ -467,6 +467,25 @@ expand_intrinsic_pow (tree callexp) base, exponent); } +/* Expand a front-end intrinsic call to toPrec(). This takes one argument, the + signature to which can be either: + + T toPrec(T)(float f); + T toPrec(T)(double f); + T toPrec(T)(real f); + + This rounds the argument F to the precision of the specified floating + point type T. The original call expression is held in CALLEXP. */ + +static tree +expand_intrinsic_toprec (tree callexp) +{ + tree f = CALL_EXPR_ARG (callexp, 0); + tree type = TREE_TYPE (callexp); + + return convert (type, f); +} + /* Expand a front-end intrinsic call to va_arg(). This takes either one or two arguments, the signature to which can be either: @@ -818,6 +837,9 @@ maybe_expand_intrinsic (tree callexp) CALL_EXPR_ARG (callexp, 1), CALL_EXPR_ARG (callexp, 2)); + case INTRINSIC_TOPREC: + return expand_intrinsic_toprec (callexp); + case INTRINSIC_VA_ARG: case INTRINSIC_C_VA_ARG: return expand_intrinsic_vaarg (callexp); diff --git a/gcc/d/intrinsics.def b/gcc/d/intrinsics.def index 3c8ed101848..1782cd7f507 100644 --- a/gcc/d/intrinsics.def +++ b/gcc/d/intrinsics.def @@ -95,6 +95,9 @@ DEF_D_BUILTIN (SIN, SIN, "sin", "core.math", "FNaNbNiNfeZe") DEF_D_BUILTIN (SQRTF, SQRTF, "sqrt", "core.math", "FNaNbNiNffZf") DEF_D_BUILTIN (SQRT, SQRT, "sqrt", "core.math", "FNaNbNiNfdZd") DEF_D_BUILTIN (SQRTL, SQRTL, "sqrt", "core.math", "FNaNbNiNfeZe") +DEF_D_BUILTIN (TOPRECF, TOPREC, "toPrec", "core.math", "FNaNbNffZI1T") +DEF_D_BUILTIN (TOPREC, TOPREC, "toPrec", "core.math", "FNaNbNfdZI1T") +DEF_D_BUILTIN (TOPRECL, TOPREC, "toPrec", "core.math", "FNaNbNfeZI1T") /* std.math intrinsics. */ diff --git a/gcc/testsuite/gdc.test/compilable/interpret3.d b/gcc/testsuite/gdc.test/compilable/interpret3.d index 36cdd13148b..14d1a12c240 100644 --- a/gcc/testsuite/gdc.test/compilable/interpret3.d +++ b/gcc/testsuite/gdc.test/compilable/interpret3.d @@ -7742,3 +7742,19 @@ struct RBNode(T) static assert(!__traits(compiles, { alias bug18057 = RBNode!int; })); +/************************************************/ +// https://issues.dlang.org/show_bug.cgi?id=9937 + +int test9937() +{ + import core.math; + + float x = float.max; + x *= 2; + x = toPrec!float(x); + x /= 2; + assert(x == float.infinity); + return 1; +} + +static assert(test9937()); diff --git a/gcc/testsuite/gdc.test/runnable/builtin.d b/gcc/testsuite/gdc.test/runnable/builtin.d index d7ac356757f..44817b16ee0 100644 --- a/gcc/testsuite/gdc.test/runnable/builtin.d +++ b/gcc/testsuite/gdc.test/runnable/builtin.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST import std.stdio; import std.math; @@ -116,4 +117,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/complex.d b/gcc/testsuite/gdc.test/runnable/complex.d index 49bb3097aef..78fe574b310 100644 --- a/gcc/testsuite/gdc.test/runnable/complex.d +++ b/gcc/testsuite/gdc.test/runnable/complex.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import std.stdio; @@ -460,4 +461,3 @@ int main(char[][] args) return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/constfold.d b/gcc/testsuite/gdc.test/runnable/constfold.d index d56f6c1357c..42406ea44a5 100644 --- a/gcc/testsuite/gdc.test/runnable/constfold.d +++ b/gcc/testsuite/gdc.test/runnable/constfold.d @@ -1,5 +1,5 @@ #! blah - +// RUNNABLE_PHOBOS_TEST static assert(__LINE__ == 3); // fails as __LINE__ is 2 import std.stdio; @@ -672,4 +672,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/foreach4.d b/gcc/testsuite/gdc.test/runnable/foreach4.d index bf8eab45b0e..8c9d4218d6e 100644 --- a/gcc/testsuite/gdc.test/runnable/foreach4.d +++ b/gcc/testsuite/gdc.test/runnable/foreach4.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST import core.stdc.stdio; import std.stdio; @@ -928,4 +928,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/ifti.d b/gcc/testsuite/gdc.test/runnable/ifti.d index 0e4edef8983..6d669753123 100644 --- a/gcc/testsuite/gdc.test/runnable/ifti.d +++ b/gcc/testsuite/gdc.test/runnable/ifti.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST import std.stdio; struct S { @@ -118,4 +119,3 @@ void main() { } } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/implicit.d b/gcc/testsuite/gdc.test/runnable/implicit.d index 89e6ac11b9f..9170b04adb0 100644 --- a/gcc/testsuite/gdc.test/runnable/implicit.d +++ b/gcc/testsuite/gdc.test/runnable/implicit.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST import std.stdio; /***********************************/ @@ -479,4 +479,3 @@ void main() writefln("Success"); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/inner.d b/gcc/testsuite/gdc.test/runnable/inner.d index 40eb27d5799..e1be7b9cbad 100644 --- a/gcc/testsuite/gdc.test/runnable/inner.d +++ b/gcc/testsuite/gdc.test/runnable/inner.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST import std.stdio; /*******************************************************/ @@ -916,4 +916,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/interpret.d b/gcc/testsuite/gdc.test/runnable/interpret.d index eee3930d34b..b822cadfcd0 100644 --- a/gcc/testsuite/gdc.test/runnable/interpret.d +++ b/gcc/testsuite/gdc.test/runnable/interpret.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST import std.stdio; template Tuple(A...) @@ -3480,6 +3480,50 @@ void test15681() assert(s2.values[1].value == 1); // OK } +/************************************************/ +// toPrec + +void testToPrec() +{ + import core.math; + + enum real ctpir = 0xc.90fdaa22168c235p-2; + enum double ctpid = 0x1.921fb54442d18p+1; + enum float ctpif = 0x1.921fb6p+1; + static assert(toPrec!float(ctpir) == ctpif); + static assert(toPrec!double(ctpir) == ctpid); + static assert(toPrec!real(ctpir) == ctpir); + static assert(toPrec!float(ctpid) == ctpif); + static assert(toPrec!double(ctpid) == ctpid); + static assert(toPrec!real(ctpid) == ctpid); + static assert(toPrec!float(ctpif) == ctpif); + static assert(toPrec!double(ctpif) == ctpif); + static assert(toPrec!real(ctpif) == ctpif); + + assert(toPrec!float(ctpir) == ctpif); + assert(toPrec!double(ctpir) == ctpid); + assert(toPrec!real(ctpir) == ctpir); + assert(toPrec!float(ctpid) == ctpif); + assert(toPrec!double(ctpid) == ctpid); + assert(toPrec!real(ctpid) == ctpid); + assert(toPrec!float(ctpif) == ctpif); + assert(toPrec!double(ctpif) == ctpif); + assert(toPrec!real(ctpif) == ctpif); + + static real rtpir = 0xc.90fdaa22168c235p-2; + static double rtpid = 0x1.921fb54442d18p+1; + static float rtpif = 0x1.921fb6p+1; + assert(toPrec!float(rtpir) == rtpif); + assert(toPrec!double(rtpir) == rtpid); + assert(toPrec!real(rtpir) == rtpir); + assert(toPrec!float(rtpid) == rtpif); + assert(toPrec!double(rtpid) == rtpid); + assert(toPrec!real(rtpid) == rtpid); + assert(toPrec!float(rtpif) == rtpif); + assert(toPrec!double(rtpif) == rtpif); + assert(toPrec!real(rtpif) == rtpif); +} + /************************************************/ int main() @@ -3609,4 +3653,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/issue8671.d b/gcc/testsuite/gdc.test/runnable/issue8671.d index 8097e79d6bf..c28e63b275b 100644 --- a/gcc/testsuite/gdc.test/runnable/issue8671.d +++ b/gcc/testsuite/gdc.test/runnable/issue8671.d @@ -1,6 +1,6 @@ +// RUNNABLE_PHOBOS_TEST import std.random; void main() { double t = 1.0 - uniform(0.0, 1.0); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/lazy.d b/gcc/testsuite/gdc.test/runnable/lazy.d index 741877cb970..b9d0fd2afc5 100644 --- a/gcc/testsuite/gdc.test/runnable/lazy.d +++ b/gcc/testsuite/gdc.test/runnable/lazy.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST import core.vararg; import std.stdio; @@ -308,4 +309,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/mars1.d b/gcc/testsuite/gdc.test/runnable/mars1.d index b240745a513..4d17d33aebf 100644 --- a/gcc/testsuite/gdc.test/runnable/mars1.d +++ b/gcc/testsuite/gdc.test/runnable/mars1.d @@ -1,4 +1,5 @@ /* +RUNNABLE_PHOBOS_TEST REQUIRED_ARGS: -mcpu=native PERMUTE_ARGS: -O -inline */ @@ -1723,4 +1724,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/mixin1.d b/gcc/testsuite/gdc.test/runnable/mixin1.d index c16d943d20f..9d88fbd2841 100644 --- a/gcc/testsuite/gdc.test/runnable/mixin1.d +++ b/gcc/testsuite/gdc.test/runnable/mixin1.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST module mixin1; import std.stdio; @@ -1468,4 +1468,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/mixin2.d b/gcc/testsuite/gdc.test/runnable/mixin2.d index 53a64d5f40e..3591d1200e0 100644 --- a/gcc/testsuite/gdc.test/runnable/mixin2.d +++ b/gcc/testsuite/gdc.test/runnable/mixin2.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST import std.stdio; /*********************************************/ @@ -361,4 +362,3 @@ void main() writeln("Success"); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/s2ir.d b/gcc/testsuite/gdc.test/runnable/s2ir.d index 4c969b4b16f..29cfc9669bb 100644 --- a/gcc/testsuite/gdc.test/runnable/s2ir.d +++ b/gcc/testsuite/gdc.test/runnable/s2ir.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST import std.stdio; /***********************************/ @@ -95,4 +95,3 @@ int main() writefln("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/stress.d b/gcc/testsuite/gdc.test/runnable/stress.d index 1b7f6457cf0..b15725369be 100644 --- a/gcc/testsuite/gdc.test/runnable/stress.d +++ b/gcc/testsuite/gdc.test/runnable/stress.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import core.stdc.stdio : printf; @@ -725,4 +726,3 @@ void CLASS() } } } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/template4.d b/gcc/testsuite/gdc.test/runnable/template4.d index 84792dae6ae..77d6254361a 100644 --- a/gcc/testsuite/gdc.test/runnable/template4.d +++ b/gcc/testsuite/gdc.test/runnable/template4.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST import std.stdio; import core.stdc.stdio; @@ -1164,4 +1165,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/template9.d b/gcc/testsuite/gdc.test/runnable/template9.d index 0b11c6b4fa3..4f182959cb1 100644 --- a/gcc/testsuite/gdc.test/runnable/template9.d +++ b/gcc/testsuite/gdc.test/runnable/template9.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: module breaker; @@ -4965,4 +4966,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test10942.d b/gcc/testsuite/gdc.test/runnable/test10942.d index 612158fc294..0d48946383d 100644 --- a/gcc/testsuite/gdc.test/runnable/test10942.d +++ b/gcc/testsuite/gdc.test/runnable/test10942.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // REQUIRED_ARGS: -g import std.string; @@ -24,4 +25,3 @@ mixin(getEnum(1087)); void main() { } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test11.d b/gcc/testsuite/gdc.test/runnable/test11.d index e62ea97940a..0d916c1af6c 100644 --- a/gcc/testsuite/gdc.test/runnable/test11.d +++ b/gcc/testsuite/gdc.test/runnable/test11.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // REQUIRED_ARGS: extern(C) int printf(const char*, ...); @@ -1390,4 +1391,3 @@ int main(string[] argv) } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test12.d b/gcc/testsuite/gdc.test/runnable/test12.d index c196361a401..eb7e422c28b 100644 --- a/gcc/testsuite/gdc.test/runnable/test12.d +++ b/gcc/testsuite/gdc.test/runnable/test12.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: -unittest -O -release -inline -fPIC -g extern(C) int printf(const char*, ...); @@ -1250,4 +1251,3 @@ int main(string[] argv) return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test12197.d b/gcc/testsuite/gdc.test/runnable/test12197.d index 52d44c94a2e..92a0bbddde5 100644 --- a/gcc/testsuite/gdc.test/runnable/test12197.d +++ b/gcc/testsuite/gdc.test/runnable/test12197.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // import std.math; void foo(T)(T[] b) @@ -10,4 +11,3 @@ void main() foo(a); assert(a[0] == 10000); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test15.d b/gcc/testsuite/gdc.test/runnable/test15.d index 75cd11ee8e7..234f50b2749 100644 --- a/gcc/testsuite/gdc.test/runnable/test15.d +++ b/gcc/testsuite/gdc.test/runnable/test15.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // REQUIRED_ARGS: // EXTRA_FILES: extra-files/test15.txt @@ -1439,4 +1440,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test22.d b/gcc/testsuite/gdc.test/runnable/test22.d index d15db1d86a9..bd0487845b3 100644 --- a/gcc/testsuite/gdc.test/runnable/test22.d +++ b/gcc/testsuite/gdc.test/runnable/test22.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // REQUIRED_ARGS: import std.math: poly; @@ -1306,4 +1307,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test23.d b/gcc/testsuite/gdc.test/runnable/test23.d index dda2864fb48..abf8e37f83d 100644 --- a/gcc/testsuite/gdc.test/runnable/test23.d +++ b/gcc/testsuite/gdc.test/runnable/test23.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // REQUIRED_ARGS: module test; @@ -1566,4 +1567,3 @@ void main() printf("Success\n"); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test24.d b/gcc/testsuite/gdc.test/runnable/test24.d index cc6d6686d7a..2f31d757921 100644 --- a/gcc/testsuite/gdc.test/runnable/test24.d +++ b/gcc/testsuite/gdc.test/runnable/test24.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // EXTRA_SOURCES: imports/test24a.d imports/test24b.d // PERMUTE_ARGS: // REQUIRED_ARGS: @@ -8,4 +9,3 @@ void main() { string hi = std.string.format("%s", 3); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test27.d b/gcc/testsuite/gdc.test/runnable/test27.d index 3e5a462e4a5..a3e76ea8d62 100644 --- a/gcc/testsuite/gdc.test/runnable/test27.d +++ b/gcc/testsuite/gdc.test/runnable/test27.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // COMPILE_SEPARATELY // EXTRA_SOURCES: imports/test27a.d // PERMUTE_ARGS: @@ -11,4 +12,3 @@ int main() return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test28.d b/gcc/testsuite/gdc.test/runnable/test28.d index 1f7e7e89cf0..5355c2cb23a 100644 --- a/gcc/testsuite/gdc.test/runnable/test28.d +++ b/gcc/testsuite/gdc.test/runnable/test28.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST module test; import core.vararg; @@ -1318,4 +1319,3 @@ void main() printf("Success\n"); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test34.d b/gcc/testsuite/gdc.test/runnable/test34.d index e92f3d6e340..6e2b36846c9 100644 --- a/gcc/testsuite/gdc.test/runnable/test34.d +++ b/gcc/testsuite/gdc.test/runnable/test34.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST module test34; import std.stdio; @@ -1292,4 +1292,3 @@ void main() } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test37.d b/gcc/testsuite/gdc.test/runnable/test37.d index c28d30f2ae9..f4a454747b4 100644 --- a/gcc/testsuite/gdc.test/runnable/test37.d +++ b/gcc/testsuite/gdc.test/runnable/test37.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: // REQUIRED_ARGS: -Jrunnable/extra-files // EXTRA_FILES: extra-files/foo37.txt extra-files/std14198/uni.d @@ -11,4 +12,3 @@ void main() // imports in a subdirectory of the -J path writefln(import("std14198/uni.d")); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test42.d b/gcc/testsuite/gdc.test/runnable/test42.d index 2bb04580a7d..66b3c04e0bb 100644 --- a/gcc/testsuite/gdc.test/runnable/test42.d +++ b/gcc/testsuite/gdc.test/runnable/test42.d @@ -1,5 +1,5 @@ +// RUNNABLE_PHOBOS_TEST // REQUIRED_ARGS: -// module test42; @@ -6438,4 +6438,3 @@ int main() return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test5305.d b/gcc/testsuite/gdc.test/runnable/test5305.d index 9102cba91f2..ff52936a8dc 100644 --- a/gcc/testsuite/gdc.test/runnable/test5305.d +++ b/gcc/testsuite/gdc.test/runnable/test5305.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // https://issues.dlang.org/show_bug.cgi?id=5305 import std.math; @@ -5,4 +6,3 @@ void map(real function(real) f) { } int main() { map(&sqrt); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/test60.d b/gcc/testsuite/gdc.test/runnable/test60.d index ab967329f08..cfd92b225ca 100644 --- a/gcc/testsuite/gdc.test/runnable/test60.d +++ b/gcc/testsuite/gdc.test/runnable/test60.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST import std.stdio; import std.algorithm; @@ -20,4 +21,3 @@ void main() writeln("Success"); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testaa.d b/gcc/testsuite/gdc.test/runnable/testaa.d index 6e28e894cf2..75e8172ab49 100644 --- a/gcc/testsuite/gdc.test/runnable/testaa.d +++ b/gcc/testsuite/gdc.test/runnable/testaa.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: -fPIC /* Test associative arrays */ @@ -1383,4 +1384,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testbitarray.d b/gcc/testsuite/gdc.test/runnable/testbitarray.d index 118388bebd1..8a34f886b05 100644 --- a/gcc/testsuite/gdc.test/runnable/testbitarray.d +++ b/gcc/testsuite/gdc.test/runnable/testbitarray.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import std.bitmanip; @@ -14,4 +15,3 @@ void main() { } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testdstress.d b/gcc/testsuite/gdc.test/runnable/testdstress.d index 097fc310d34..f06f93982a5 100644 --- a/gcc/testsuite/gdc.test/runnable/testdstress.d +++ b/gcc/testsuite/gdc.test/runnable/testdstress.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: module dstress.run.module_01; @@ -930,4 +931,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testfile.d b/gcc/testsuite/gdc.test/runnable/testfile.d index e7c3e19a49d..6f568044ea4 100644 --- a/gcc/testsuite/gdc.test/runnable/testfile.d +++ b/gcc/testsuite/gdc.test/runnable/testfile.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import std.file; @@ -22,4 +23,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testformat.d b/gcc/testsuite/gdc.test/runnable/testformat.d index 2cb0da9fc4d..74f4095c009 100644 --- a/gcc/testsuite/gdc.test/runnable/testformat.d +++ b/gcc/testsuite/gdc.test/runnable/testformat.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import std.stdio; @@ -123,4 +124,3 @@ int main() std.stdio.writefln("Success"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testline.d b/gcc/testsuite/gdc.test/runnable/testline.d index 5001fc2fa68..5b84204b785 100644 --- a/gcc/testsuite/gdc.test/runnable/testline.d +++ b/gcc/testsuite/gdc.test/runnable/testline.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: // $HeadURL$ @@ -41,4 +42,3 @@ void checkFileSpec(Object o){ writeln(str); assert(str[start .. start+3]=="(1)"); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testmmfile.d b/gcc/testsuite/gdc.test/runnable/testmmfile.d index 1ae98df9178..6a9d6e9094a 100644 --- a/gcc/testsuite/gdc.test/runnable/testmmfile.d +++ b/gcc/testsuite/gdc.test/runnable/testmmfile.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: // REQUIRED_ARGS: @@ -117,4 +118,3 @@ int main() return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testscope2.d b/gcc/testsuite/gdc.test/runnable/testscope2.d index cde02ab405f..6c96fb5873d 100644 --- a/gcc/testsuite/gdc.test/runnable/testscope2.d +++ b/gcc/testsuite/gdc.test/runnable/testscope2.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // REQUIRED_ARGS: -dip25 import core.stdc.stdio; @@ -246,4 +247,3 @@ void main() printf("Success\n"); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testsignals.d b/gcc/testsuite/gdc.test/runnable/testsignals.d index a43f89295e8..c2fbcee45cb 100644 --- a/gcc/testsuite/gdc.test/runnable/testsignals.d +++ b/gcc/testsuite/gdc.test/runnable/testsignals.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST import std.stdio; import std.signals; @@ -111,4 +112,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testsocket.d b/gcc/testsuite/gdc.test/runnable/testsocket.d index 00b757a896b..d0619299ece 100644 --- a/gcc/testsuite/gdc.test/runnable/testsocket.d +++ b/gcc/testsuite/gdc.test/runnable/testsocket.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import std.stdio; @@ -48,4 +49,3 @@ int main () } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/teststdio.d b/gcc/testsuite/gdc.test/runnable/teststdio.d index 854dcb5ae38..d340f21892f 100644 --- a/gcc/testsuite/gdc.test/runnable/teststdio.d +++ b/gcc/testsuite/gdc.test/runnable/teststdio.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: // EXTRA_FILES: extra-files/teststdio.txt @@ -31,4 +32,3 @@ void main() } while (!feof(fp)); //fclose(fp); } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testthread2.d b/gcc/testsuite/gdc.test/runnable/testthread2.d index 0ec6e0dbcdc..93aace6c650 100644 --- a/gcc/testsuite/gdc.test/runnable/testthread2.d +++ b/gcc/testsuite/gdc.test/runnable/testthread2.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import std.algorithm : map; @@ -106,4 +107,3 @@ void main() { } } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/testtypeid.d b/gcc/testsuite/gdc.test/runnable/testtypeid.d index dcaac731fa3..ebdda30c197 100644 --- a/gcc/testsuite/gdc.test/runnable/testtypeid.d +++ b/gcc/testsuite/gdc.test/runnable/testtypeid.d @@ -1,4 +1,4 @@ - +// RUNNABLE_PHOBOS_TEST import core.vararg; import std.stdio; @@ -684,4 +684,3 @@ int main() return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/traits.d b/gcc/testsuite/gdc.test/runnable/traits.d index 915f16da48e..547976f6598 100644 --- a/gcc/testsuite/gdc.test/runnable/traits.d +++ b/gcc/testsuite/gdc.test/runnable/traits.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: module traits; @@ -1606,4 +1607,3 @@ int main() writeln("Success"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/wc.d b/gcc/testsuite/gdc.test/runnable/wc.d index e5fd98a0f83..8f847c5938f 100644 --- a/gcc/testsuite/gdc.test/runnable/wc.d +++ b/gcc/testsuite/gdc.test/runnable/wc.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: // EXECUTE_ARGS: runnable/wc.d @@ -48,4 +49,3 @@ int main (string[] args) } return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/wc2.d b/gcc/testsuite/gdc.test/runnable/wc2.d index 780f5f160ea..a97c6fa8620 100644 --- a/gcc/testsuite/gdc.test/runnable/wc2.d +++ b/gcc/testsuite/gdc.test/runnable/wc2.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: // EXECUTE_ARGS: runnable/wc2.d @@ -72,4 +73,3 @@ int main (string[] args) } return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/wc3.d b/gcc/testsuite/gdc.test/runnable/wc3.d index 666bfb99113..13beac25aba 100644 --- a/gcc/testsuite/gdc.test/runnable/wc3.d +++ b/gcc/testsuite/gdc.test/runnable/wc3.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: // EXECUTE_ARGS: runnable/extra-files/alice30.txt // EXTRA_FILES: extra-files/alice30.txt @@ -70,4 +71,3 @@ int main (string[] args) } return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d index e1cdbcd1922..8cba4ed4a80 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest46.d +++ b/gcc/testsuite/gdc.test/runnable/xtest46.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: -unittest -O -release -inline -fPIC -g import std.stdio; @@ -8283,4 +8284,3 @@ int main() printf("Success\n"); return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/gcc/testsuite/gdc.test/runnable/xtest55.d b/gcc/testsuite/gdc.test/runnable/xtest55.d index 1062a1a77fc..4b295d8c686 100644 --- a/gcc/testsuite/gdc.test/runnable/xtest55.d +++ b/gcc/testsuite/gdc.test/runnable/xtest55.d @@ -1,3 +1,4 @@ +// RUNNABLE_PHOBOS_TEST // PERMUTE_ARGS: import core.memory, std.stdio; @@ -22,4 +23,3 @@ int main() return 0; } -// RUNNABLE_PHOBOS_TEST diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 18d479d54ff..8b461f76ad0 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -c9c209e2c62ce43a2c08ddd61d647730716b2d0f +e68a5ae36790fa9dc5bab6155bc450eb6bf8c12c The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/core/cpuid.d b/libphobos/libdruntime/core/cpuid.d index d35e7d5449f..839605aee1e 100644 --- a/libphobos/libdruntime/core/cpuid.d +++ b/libphobos/libdruntime/core/cpuid.d @@ -822,7 +822,7 @@ void cpuidX86() { asm pure nothrow @nogc { "cpuid" : "=a" (pnb[0]), "=b" (pnb[1]), "=c" (pnb[ 2]), "=d" (pnb[ 3]) : "a" (0x8000_0002); - "cpuid" : "=a" (pnb[4]), "=b" (pnb[5]), "=c" (pnb[ 6]), "=d" (pnb[ 7]) : "a" (0x8000_0003); + "cpuid" : "=a" (pnb[4]), "=b" (pnb[5]), "=c" (pnb[ 6]), "=d" (pnb[ 7]) : "a" (0x8000_0003); "cpuid" : "=a" (pnb[8]), "=b" (pnb[9]), "=c" (pnb[10]), "=d" (pnb[11]) : "a" (0x8000_0004); } } diff --git a/libphobos/libdruntime/core/internal/convert.d b/libphobos/libdruntime/core/internal/convert.d index 3b82010ab9c..3d2cb59a64a 100644 --- a/libphobos/libdruntime/core/internal/convert.d +++ b/libphobos/libdruntime/core/internal/convert.d @@ -37,76 +37,138 @@ private ubyte[] ctfe_alloc()(size_t n) const(ubyte)[] toUbyte(T)(const ref T val) if (is(Unqual!T == float) || is(Unqual!T == double) || is(Unqual!T == real) || is(Unqual!T == ifloat) || is(Unqual!T == idouble) || is(Unqual!T == ireal)) { - static const(ubyte)[] reverse_(const(ubyte)[] arr) - { - ubyte[] buff = ctfe_alloc(arr.length); - foreach (k, v; arr) - { - buff[$-k-1] = v; - } - return buff; - } if (__ctfe) { - auto parsed = parse(val); - - ulong mantissa = parsed.mantissa; - uint exp = parsed.exponent; - uint sign = parsed.sign; - - ubyte[] buff = ctfe_alloc(T.sizeof); - size_t off_bytes = 0; - size_t off_bits = 0; - // Quadruples won't fit in one ulong, so check for that. - enum mantissaMax = FloatTraits!T.MANTISSA < ulong.sizeof*8 ? - FloatTraits!T.MANTISSA : ulong.sizeof*8; - - for (; off_bytes < mantissaMax/8; ++off_bytes) + static if (T.mant_dig == float.mant_dig || T.mant_dig == double.mant_dig) { - buff[off_bytes] = cast(ubyte)mantissa; - mantissa >>= 8; + static if (is(T : ireal)) // https://issues.dlang.org/show_bug.cgi?id=19932 + const f = val.im; + else + alias f = val; + static if (T.sizeof == uint.sizeof) + uint bits = *cast(const uint*) &f; + else static if (T.sizeof == ulong.sizeof) + ulong bits = *cast(const ulong*) &f; + ubyte[] result = ctfe_alloc(T.sizeof); + version (BigEndian) + { + foreach_reverse (ref b; result) + { + b = cast(ubyte) bits; + bits >>= 8; + } + } + else + { + foreach (ref b; result) + { + b = cast(ubyte) bits; + bits >>= 8; + } + } + return result; } - - static if (floatFormat!T == FloatFormat.Quadruple) + else static if (floatFormat!T == FloatFormat.DoubleDouble) { - ulong mantissa2 = parsed.mantissa2; - off_bytes--; // go back one, since mantissa only stored data in 56 - // bits, ie 7 bytes - for (; off_bytes < FloatTraits!T.MANTISSA/8; ++off_bytes) + // Parse DoubleDoubles as a pair of doubles. + // The layout of the type is: + // + // [1| 7 | 56 ][ 8 | 56 ] + // [S| Exp | Fraction (hi) ][ Unused | Fraction (low) ] + // + // We can get the least significant bits by subtracting the IEEE + // double precision portion from the real value. + + import core.math : toPrec; + + ubyte[] buff = ctfe_alloc(T.sizeof); + enum msbSize = double.sizeof; + + double hi = toPrec!double(val); + buff[0 .. msbSize] = toUbyte(hi)[]; + + if (val is cast(T)0.0 || val is cast(T)-0.0 || + val is T.nan || val is -T.nan || + val is T.infinity || val > T.max || + val is -T.infinity || val < -T.max) + { + // Zero, NaN, and Inf are all representable as doubles, so the + // least significant part can be 0.0. + buff[msbSize .. $] = 0; + } + else { - buff[off_bytes] = cast(ubyte)mantissa2; - mantissa2 >>= 8; + double low = toPrec!double(val - hi); + buff[msbSize .. $] = toUbyte(low)[]; } + + // Arrays don't index differently between little and big-endian targets. + return buff; } else { - off_bits = FloatTraits!T.MANTISSA%8; - buff[off_bytes] = cast(ubyte)mantissa; - } + auto parsed = parse(val); - for (size_t i=0; i>= 8; - buff[off_bytes] |= (cur_exp << off_bits); - ++off_bytes; - buff[off_bytes] |= cur_exp >> 8 - off_bits; - } + ulong mantissa = parsed.mantissa; + uint exp = parsed.exponent; + uint sign = parsed.sign; + ubyte[] buff = ctfe_alloc(T.sizeof); + size_t off_bytes = 0; + size_t off_bits = 0; + // Quadruples won't fit in one ulong, so check for that. + enum mantissaMax = FloatTraits!T.MANTISSA < ulong.sizeof*8 ? + FloatTraits!T.MANTISSA : ulong.sizeof*8; - exp <<= 8 - FloatTraits!T.EXPONENT%8 - 1; - buff[off_bytes] |= exp; - sign <<= 7; - buff[off_bytes] |= sign; + for (; off_bytes < mantissaMax/8; ++off_bytes) + { + buff[off_bytes] = cast(ubyte)mantissa; + mantissa >>= 8; + } - version (LittleEndian) - { + static if (floatFormat!T == FloatFormat.Quadruple) + { + ulong mantissa2 = parsed.mantissa2; + off_bytes--; // go back one, since mantissa only stored data in 56 + // bits, ie 7 bytes + for (; off_bytes < FloatTraits!T.MANTISSA/8; ++off_bytes) + { + buff[off_bytes] = cast(ubyte)mantissa2; + mantissa2 >>= 8; + } + } + else + { + off_bits = FloatTraits!T.MANTISSA%8; + buff[off_bytes] = cast(ubyte)mantissa; + } + + for (size_t i=0; i>= 8; + buff[off_bytes] |= (cur_exp << off_bits); + ++off_bytes; + buff[off_bytes] |= cur_exp >> 8 - off_bits; + } + + + exp <<= 8 - FloatTraits!T.EXPONENT%8 - 1; + buff[off_bytes] |= exp; + sign <<= 7; + buff[off_bytes] |= sign; + + version (BigEndian) + { + for (size_t left = 0, right = buff.length - 1; left < right; left++, right--) + { + const swap = buff[left]; + buff[left] = buff[right]; + buff[right] = swap; + } + } return buff; } - else - { - return reverse_(buff); - } } else { diff --git a/libphobos/libdruntime/core/math.d b/libphobos/libdruntime/core/math.d index 1b661d365c9..878623258cd 100644 --- a/libphobos/libdruntime/core/math.d +++ b/libphobos/libdruntime/core/math.d @@ -164,3 +164,74 @@ unittest } } +/************************************* + * Round argument to a specific precision. + * + * D language types specify a minimum precision, not a maximum. The + * `toPrec()` function forces rounding of the argument `f` to the + * precision of the specified floating point type `T`. + * + * Params: + * T = precision type to round to + * f = value to convert + * Returns: + * f in precision of type `T` + */ +@safe pure nothrow +T toPrec(T:float)(float f) { pragma(inline, false); return f; } +/// ditto +@safe pure nothrow +T toPrec(T:float)(double f) { pragma(inline, false); return cast(T) f; } +/// ditto +@safe pure nothrow +T toPrec(T:float)(real f) { pragma(inline, false); return cast(T) f; } +/// ditto +@safe pure nothrow +T toPrec(T:double)(float f) { pragma(inline, false); return f; } +/// ditto +@safe pure nothrow +T toPrec(T:double)(double f) { pragma(inline, false); return f; } +/// ditto +@safe pure nothrow +T toPrec(T:double)(real f) { pragma(inline, false); return cast(T) f; } +/// ditto +@safe pure nothrow +T toPrec(T:real)(float f) { pragma(inline, false); return f; } +/// ditto +@safe pure nothrow +T toPrec(T:real)(double f) { pragma(inline, false); return f; } +/// ditto +@safe pure nothrow +T toPrec(T:real)(real f) { pragma(inline, false); return f; } + +@safe unittest +{ + static float f = 1.1f; + static double d = 1.1; + static real r = 1.1L; + f = toPrec!float(f + f); + f = toPrec!float(d + d); + f = toPrec!float(r + r); + d = toPrec!double(f + f); + d = toPrec!double(d + d); + d = toPrec!double(r + r); + r = toPrec!real(f + f); + r = toPrec!real(d + d); + r = toPrec!real(r + r); + + /+ Uncomment these once compiler support has been added. + enum real PIR = 0xc.90fdaa22168c235p-2; + enum double PID = 0x1.921fb54442d18p+1; + enum float PIF = 0x1.921fb6p+1; + + assert(toPrec!float(PIR) == PIF); + assert(toPrec!double(PIR) == PID); + assert(toPrec!real(PIR) == PIR); + assert(toPrec!float(PID) == PIF); + assert(toPrec!double(PID) == PID); + assert(toPrec!real(PID) == PID); + assert(toPrec!float(PIF) == PIF); + assert(toPrec!double(PIF) == PIF); + assert(toPrec!real(PIF) == PIF); + +/ +} diff --git a/libphobos/libdruntime/core/simd.d b/libphobos/libdruntime/core/simd.d index 780db37c993..32e2aaf5cfd 100644 --- a/libphobos/libdruntime/core/simd.d +++ b/libphobos/libdruntime/core/simd.d @@ -10,9 +10,6 @@ * Authors: $(WEB digitalmars.com, Walter Bright), */ -/* NOTE: This file has been patched from the original DMD distribution to - * work with the GDC compiler. - */ module core.simd; pure: @@ -42,6 +39,7 @@ template Vector(T) /* Handy aliases */ static if (is(Vector!(void[8]))) alias Vector!(void[8]) void8; /// +static if (is(Vector!(double[1]))) alias Vector!(double[1]) double1; /// static if (is(Vector!(float[2]))) alias Vector!(float[2]) float2; /// static if (is(Vector!(byte[8]))) alias Vector!(byte[8]) byte8; /// static if (is(Vector!(ubyte[8]))) alias Vector!(ubyte[8]) ubyte8; /// @@ -49,6 +47,8 @@ static if (is(Vector!(short[4]))) alias Vector!(short[4]) short4; /// static if (is(Vector!(ushort[4]))) alias Vector!(ushort[4]) ushort4; /// static if (is(Vector!(int[2]))) alias Vector!(int[2]) int2; /// static if (is(Vector!(uint[2]))) alias Vector!(uint[2]) uint2; /// +static if (is(Vector!(long[1]))) alias Vector!(long[1]) long1; /// +static if (is(Vector!(ulong[1]))) alias Vector!(ulong[1]) ulong1; /// static if (is(Vector!(void[16]))) alias Vector!(void[16]) void16; /// static if (is(Vector!(double[2]))) alias Vector!(double[2]) double2; /// -- 2.30.2