* libgo patch committed: Make libgo C code more portable
@ 2014-05-28 23:10 Ian Lance Taylor
2014-06-03 10:50 ` Rainer Orth
0 siblings, 1 reply; 2+ messages in thread
From: Ian Lance Taylor @ 2014-05-28 23:10 UTC (permalink / raw)
To: gcc-patches, gofrontend-dev
[-- Attachment #1: Type: text/plain, Size: 233 bytes --]
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
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 10982 bytes --]
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");
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: libgo patch committed: Make libgo C code more portable
2014-05-28 23:10 libgo patch committed: Make libgo C code more portable Ian Lance Taylor
@ 2014-06-03 10:50 ` Rainer Orth
0 siblings, 0 replies; 2+ messages in thread
From: Rainer Orth @ 2014-06-03 10:50 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev
Ian Lance Taylor <iant@google.com> writes:
> 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.
[...]
> 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"
> @@ -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;
> }
>
This change broke Solaris Go bootstrap:
/vol/gcc/src/hg/trunk/local/libgo/runtime/print.c: In function '__go_print_double':
/vol/gcc/src/hg/trunk/local/libgo/runtime/print.c:200:3: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
if(signbit(v)) {
^
cc1: all warnings being treated as errors
make: *** [print.lo] Error 1
It's an issue in the gcc version of signbit in <iso/math_c99.h>,
ultimately:
#undef signbit
#if defined(__sparc)
#define signbit(x) __extension__( \
{ __typeof(x) __x_s = (x); \
(int) (*(unsigned *) &__x_s >> 31); })
#elif defined(__i386) || defined(__amd64)
#define signbit(x) __extension__( \
{ __typeof(x) __x_s = (x); \
(sizeof (__x_s) == sizeof (float) ? \
(int) (*(unsigned *) &__x_s >> 31) : \
sizeof (__x_s) == sizeof (double) ? \
(int) (((unsigned *) &__x_s)[1] >> 31) : \
(int) (((unsigned short *) &__x_s)[4] >> 15)); })
#endif
Solaris lacks __signbit{f,,l} in libm, like some other Unices do, and
cannot use __builtin_signbit since that is missing in gcc 3.4 still
bundled with Solaris 10 and 11. I'll probably go for handling this in
fixincludes on mainline, though, where the gcc 3 issue is irrelevant.
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-06-03 10:50 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-28 23:10 libgo patch committed: Make libgo C code more portable Ian Lance Taylor
2014-06-03 10:50 ` Rainer Orth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).