This patch to libgo, from Peter Collingbourne, changes some of the C code to make it easier to compile libgo with a compiler other than GCC. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian
diff -r d73f07d002ef libgo/runtime/go-cdiv.c --- a/libgo/runtime/go-cdiv.c Tue May 27 15:00:31 2014 -0700 +++ b/libgo/runtime/go-cdiv.c Wed May 28 16:09:25 2014 -0700 @@ -4,6 +4,9 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ +#include <complex.h> +#include <math.h> + /* Calls to these functions are generated by the Go frontend for division of complex64 or complex128. We use these because Go's complex division expects slightly different results from the GCC @@ -13,33 +16,33 @@ the the whole number is Inf, but an operation involving NaN ought to result in NaN, not Inf. */ -__complex float -__go_complex64_div (__complex float a, __complex float b) +complex float +__go_complex64_div (complex float a, complex float b) { - if (__builtin_expect (b == 0+0i, 0)) + if (__builtin_expect (b == 0, 0)) { - if (!__builtin_isinff (__real__ a) - && !__builtin_isinff (__imag__ a) - && (__builtin_isnanf (__real__ a) || __builtin_isnanf (__imag__ a))) + if (!isinf (crealf (a)) + && !isinf (cimagf (a)) + && (isnan (crealf (a)) || isnan (cimagf (a)))) { /* Pass "1" to nanf to match math/bits.go. */ - return __builtin_nanf("1") + __builtin_nanf("1")*1i; + return nanf("1") + nanf("1")*I; } } return a / b; } -__complex double -__go_complex128_div (__complex double a, __complex double b) +complex double +__go_complex128_div (complex double a, complex double b) { - if (__builtin_expect (b == 0+0i, 0)) + if (__builtin_expect (b == 0, 0)) { - if (!__builtin_isinf (__real__ a) - && !__builtin_isinf (__imag__ a) - && (__builtin_isnan (__real__ a) || __builtin_isnan (__imag__ a))) + if (!isinf (creal (a)) + && !isinf (cimag (a)) + && (isnan (creal (a)) || isnan (cimag (a)))) { /* Pass "1" to nan to match math/bits.go. */ - return __builtin_nan("1") + __builtin_nan("1")*1i; + return nan("1") + nan("1")*I; } } return a / b; diff -r d73f07d002ef libgo/runtime/go-type-complex.c --- a/libgo/runtime/go-type-complex.c Tue May 27 15:00:31 2014 -0700 +++ b/libgo/runtime/go-type-complex.c Wed May 28 16:09:25 2014 -0700 @@ -4,13 +4,13 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ +#include <complex.h> +#include <math.h> +#include <stdint.h> +#include <string.h> #include "runtime.h" #include "go-type.h" -/* The 64-bit type. */ - -typedef unsigned int DItype __attribute__ ((mode (DI))); - /* Hash function for float types. */ uintptr_t @@ -18,69 +18,67 @@ { if (key_size == 8) { - union - { - unsigned char a[8]; - __complex float cf; - DItype di; - } ucf; - __complex float cf; + const complex float *cfp; + complex float cf; float cfr; float cfi; + uint64_t fi; - __builtin_memcpy (ucf.a, vkey, 8); - cf = ucf.cf; - cfr = __builtin_crealf (cf); - cfi = __builtin_cimagf (cf); - if (__builtin_isinff (cfr) || __builtin_isinff (cfi)) + cfp = (const complex float *) vkey; + cf = *cfp; + + cfr = crealf (cf); + cfi = cimagf (cf); + + if (isinf (cfr) || isinf (cfi)) return 0; /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it random so that not all NaNs wind up in the same place. */ - if (__builtin_isnanf (cfr) || __builtin_isnanf (cfi)) + if (isnan (cfr) || isnan (cfi)) return runtime_fastrand1 (); /* Avoid negative zero. */ if (cfr == 0 && cfi == 0) return 0; else if (cfr == 0) - ucf.cf = cfi * 1.0iF; + cf = cfi * I; else if (cfi == 0) - ucf.cf = cfr; + cf = cfr; - return ucf.di; + memcpy (&fi, &cf, 8); + return (uintptr_t) cfi; } else if (key_size == 16) { - union - { - unsigned char a[16]; - __complex double cd; - DItype adi[2]; - } ucd; - __complex double cd; + const complex double *cdp; + complex double cd; double cdr; double cdi; + uint64_t di[2]; - __builtin_memcpy (ucd.a, vkey, 16); - cd = ucd.cd; - cdr = __builtin_crealf (cd); - cdi = __builtin_cimagf (cd); - if (__builtin_isinf (cdr) || __builtin_isinf (cdi)) + cdp = (const complex double *) vkey; + cd = *cdp; + + cdr = creal (cd); + cdi = cimag (cd); + + if (isinf (cdr) || isinf (cdi)) return 0; - if (__builtin_isnan (cdr) || __builtin_isnan (cdi)) + if (isnan (cdr) || isnan (cdi)) return runtime_fastrand1 (); /* Avoid negative zero. */ if (cdr == 0 && cdi == 0) return 0; else if (cdr == 0) - ucd.cd = cdi * 1.0i; + cd = cdi * I; else if (cdi == 0) - ucd.cd = cdr; + cd = cdr; - return ucd.adi[0] ^ ucd.adi[1]; + memcpy (&di, &cd, 16); + return di[0] ^ di[1]; } else runtime_throw ("__go_type_hash_complex: invalid complex size"); @@ -93,35 +91,23 @@ { if (key_size == 8) { - union - { - unsigned char a[8]; - __complex float cf; - } ucf; - __complex float cf1; - __complex float cf2; + const complex float *cfp1; + const complex float *cfp2; + + cfp1 = (const complex float *) vk1; + cfp2 = (const complex float *) vk2; - __builtin_memcpy (ucf.a, vk1, 8); - cf1 = ucf.cf; - __builtin_memcpy (ucf.a, vk2, 8); - cf2 = ucf.cf; - return cf1 == cf2; + return *cfp1 == *cfp2; } else if (key_size == 16) { - union - { - unsigned char a[16]; - __complex double cd; - } ucd; - __complex double cd1; - __complex double cd2; + const complex double *cdp1; + const complex double *cdp2; + + cdp1 = (const complex double *) vk1; + cdp2 = (const complex double *) vk2; - __builtin_memcpy (ucd.a, vk1, 16); - cd1 = ucd.cd; - __builtin_memcpy (ucd.a, vk2, 16); - cd2 = ucd.cd; - return cd1 == cd2; + return *cdp1 == *cdp2; } else runtime_throw ("__go_type_equal_complex: invalid complex size"); diff -r d73f07d002ef libgo/runtime/go-type-float.c --- a/libgo/runtime/go-type-float.c Tue May 27 15:00:31 2014 -0700 +++ b/libgo/runtime/go-type-float.c Wed May 28 16:09:25 2014 -0700 @@ -4,14 +4,11 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ +#include <math.h> +#include <stdint.h> #include "runtime.h" #include "go-type.h" -/* The 32-bit and 64-bit types. */ - -typedef unsigned int SItype __attribute__ ((mode (SI))); -typedef unsigned int DItype __attribute__ ((mode (DI))); - /* Hash function for float types. */ uintptr_t @@ -19,45 +16,41 @@ { if (key_size == 4) { - union - { - unsigned char a[4]; - float f; - SItype si; - } uf; + const float *fp; float f; + uint32_t si; - __builtin_memcpy (uf.a, vkey, 4); - f = uf.f; - if (__builtin_isinff (f) || f == 0) + fp = (const float *) vkey; + f = *fp; + + if (isinf (f) || f == 0) return 0; /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it random so that not all NaNs wind up in the same place. */ - if (__builtin_isnanf (f)) + if (isnan (f)) return runtime_fastrand1 (); - return (uintptr_t) uf.si; + memcpy (&si, vkey, 4); + return (uintptr_t) si; } else if (key_size == 8) { - union - { - unsigned char a[8]; - double d; - DItype di; - } ud; + const double *dp; double d; + uint64_t di; - __builtin_memcpy (ud.a, vkey, 8); - d = ud.d; - if (__builtin_isinf (d) || d == 0) + dp = (const double *) vkey; + d = *dp; + + if (isinf (d) || d == 0) return 0; - if (__builtin_isnan (d)) + if (isnan (d)) return runtime_fastrand1 (); - return (uintptr_t) ud.di; + memcpy (&di, vkey, 8); + return (uintptr_t) di; } else runtime_throw ("__go_type_hash_float: invalid float size"); @@ -70,36 +63,23 @@ { if (key_size == 4) { - union - { - unsigned char a[4]; - float f; - } uf; - float f1; - float f2; + const float *fp1; + const float *fp2; - __builtin_memcpy (uf.a, vk1, 4); - f1 = uf.f; - __builtin_memcpy (uf.a, vk2, 4); - f2 = uf.f; - return f1 == f2; + fp1 = (const float *) vk1; + fp2 = (const float *) vk2; + + return *fp1 == *fp2; } else if (key_size == 8) { - union - { - unsigned char a[8]; - double d; - DItype di; - } ud; - double d1; - double d2; + const double *dp1; + const double *dp2; - __builtin_memcpy (ud.a, vk1, 8); - d1 = ud.d; - __builtin_memcpy (ud.a, vk2, 8); - d2 = ud.d; - return d1 == d2; + dp1 = (const double *) vk1; + dp2 = (const double *) vk2; + + return *dp1 == *dp2; } else runtime_throw ("__go_type_equal_float: invalid float size"); diff -r d73f07d002ef libgo/runtime/print.c --- a/libgo/runtime/print.c Tue May 27 15:00:31 2014 -0700 +++ b/libgo/runtime/print.c Wed May 28 16:09:25 2014 -0700 @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include <complex.h> +#include <math.h> #include <stdarg.h> #include "runtime.h" #include "array.h" @@ -105,7 +107,7 @@ runtime_printfloat(va_arg(va, float64)); break; case 'C': - runtime_printcomplex(va_arg(va, __complex double)); + runtime_printcomplex(va_arg(va, complex double)); break; case 'i': runtime_printiface(va_arg(va, Iface)); @@ -174,13 +176,12 @@ gwrite("NaN", 3); return; } - i = __builtin_isinf_sign(v); - if(i > 0) { - gwrite("+Inf", 4); - return; - } - if(i < 0) { - gwrite("-Inf", 4); + if(isinf(v)) { + if(signbit(v)) { + gwrite("-Inf", 4); + } else { + gwrite("+Inf", 4); + } return; } @@ -243,11 +244,11 @@ } void -runtime_printcomplex(__complex double v) +runtime_printcomplex(complex double v) { gwrite("(", 1); - runtime_printfloat(__builtin_creal(v)); - runtime_printfloat(__builtin_cimag(v)); + runtime_printfloat(creal(v)); + runtime_printfloat(cimag(v)); gwrite("i)", 2); } diff -r d73f07d002ef libgo/runtime/runtime.h --- a/libgo/runtime/runtime.h Tue May 27 15:00:31 2014 -0700 +++ b/libgo/runtime/runtime.h Wed May 28 16:09:25 2014 -0700 @@ -5,6 +5,7 @@ #include "config.h" #include "go-assert.h" +#include <complex.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -710,7 +711,7 @@ void runtime_printuint(uint64); void runtime_printhex(uint64); void runtime_printslice(Slice); -void runtime_printcomplex(__complex double); +void runtime_printcomplex(complex double); void reflect_call(const struct __go_func_type *, FuncVal *, _Bool, _Bool, void **, void **) __asm__ (GOSYM_PREFIX "reflect.call");