On Thu, Mar 05, 2015 at 08:41:51PM +0000, Nicholas Clark wrote:
> On Thu, Mar 05, 2015 at 07:57:12PM +0000, Nicholas Clark wrote:
> 
> > Sadly PPC32 is a mess. With these patches NQP will build, and the nativecall
> > tests pass. However 2 other tests fail (arithmetic and printf problems), and
> > the Rakudo build explodes with a syntax error backtrace.
> 
> [nick@gcc1-power7 nqp]$ for fmt in s i u x e f g; do ./nqp-m -e 
> "say(nqp::sprintf('%%$fmt is %$fmt', [4294967295]))"; done
> %s is 4294967295
> %i is 277721840
> %u is 280670960
> %x is 10bab2f0
> %e is 5.789358e+09
> %f is 277094112.395473
> %g is 4.29497e+09
> 
> Well, two are correct.

And it turned out that the values were actually random.
So, presuambly undefined behaviour

FROGGS suggested the union in the P6int REPR. Which was so nearly a hole in
one, as it's actually the union in the P6bitint REPR.

With this patch, PPC32 passes all NQP and Rakudo spectests, and fails the
same spectests as PPC64, for the same reasons.

Tested on PPC32, PPC64, x86_64 and x86.

I think we now stand a fighting chance of building on any architecture, as
long as dyncall supports it.

Nicholas Clark
>From 824fed77ff37d047ab29a70f70120f7a9935a7d1 Mon Sep 17 00:00:00 2001
From: Nicholas Clark <n...@ccl4.org>
Date: Thu, 5 Mar 2015 13:33:47 -0800
Subject: [PATCH] In the P6bigint body union, the flag most only be first for
 64 bit Big Endian.

The intent is that the flag value (0xFFFFFFFF) is in the lower 32 bits of the
function pointer. On 64 Big Endian systems, the existing code implemented this
correctly, by storing the 32 bit value first, the 32 bit flag second. But for
32 bit Big Endian systems the flag must come first (just like all Little
Endian systems), because otherwise the 32 bit value and 32 bit pointer share
the same memory, and writing the flag doesn't cause set the lower bits of the
pointer)
---
 src/6model/reprs/P6bigint.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/6model/reprs/P6bigint.h b/src/6model/reprs/P6bigint.h
index 70d6276..cfdcd20 100644
--- a/src/6model/reprs/P6bigint.h
+++ b/src/6model/reprs/P6bigint.h
@@ -13,7 +13,7 @@ struct MVMP6bigintBody {
          * so that the flag sets the lower bits of any 64-bit pointer, which
          * should never happen in a real pointer due to alignment. */
         struct {
-#if MVM_BIGENDIAN
+#if MVM_BIGENDIAN && MVM_PTR_SIZE > 4
             MVMint32  value;
             MVMuint32 flag;
 #else
-- 
1.8.1.4

Reply via email to