diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-02-11 00:03:10 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-02-11 00:03:10 +0000 |
commit | 41da64ed3a42abd8b4e502b1a958322f62940d27 (patch) | |
tree | 9b9c08f320214694fa37fdd972b1d515e73dc55f | |
parent | c3b0c721e8e6f236f0609f2b753381369d0a0119 (diff) | |
download | gcc-41da64ed3a42abd8b4e502b1a958322f62940d27.zip gcc-41da64ed3a42abd8b4e502b1a958322f62940d27.tar.gz gcc-41da64ed3a42abd8b4e502b1a958322f62940d27.tar.bz2 |
runtime: Fix chan code for big-endian strict-alignment systems
From-SVN: r184115
-rw-r--r-- | libgo/runtime/chan.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/libgo/runtime/chan.c b/libgo/runtime/chan.c index 4fc2d60..24be950 100644 --- a/libgo/runtime/chan.c +++ b/libgo/runtime/chan.c @@ -409,11 +409,20 @@ closed: void __go_send_small(ChanType *t, Hchan* c, uint64 val) { - byte b[sizeof(uint64)]; - - runtime_memclr(b, sizeof(uint64)); - __builtin_memcpy(b, &val, t->__element_type->__size); - runtime_chansend(t, c, b, nil); + union + { + byte b[sizeof(uint64)]; + uint64 v; + } u; + byte *p; + + u.v = val; +#ifndef WORDS_BIGENDIAN + p = u.b; +#else + p = u.b + sizeof(uint64) - t->__element_type->__size; +#endif + runtime_chansend(t, c, p, nil); } // The compiler generates a call to __go_send_big to send a value @@ -433,9 +442,15 @@ __go_receive_small(ChanType *t, Hchan* c) byte b[sizeof(uint64)]; uint64 v; } u; + byte *p; u.v = 0; - runtime_chanrecv(t, c, u.b, nil, nil); +#ifndef WORDS_BIGENDIAN + p = u.b; +#else + p = u.b + sizeof(uint64) - t->__element_type->__size; +#endif + runtime_chanrecv(t, c, p, nil, nil); return u.v; } @@ -654,8 +669,8 @@ newselect(int32 size, Select **selp) sel->tcase = size; sel->ncase = 0; - sel->pollorder = (void*)(sel->scase + size); - sel->lockorder = (void*)(sel->pollorder + size); + sel->lockorder = (void*)(sel->scase + size); + sel->pollorder = (void*)(sel->lockorder + size); *selp = sel; if(debug) |