[pypy-commit] pypy ppc-updated-backend: PPC Backend #3 (1/2): intermediate progress

arigo noreply at buildbot.pypy.org
Fri Sep 11 15:22:37 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: ppc-updated-backend
Changeset: r79590:b1f98b2e68b5
Date: 2015-09-02 18:44 +0200
http://bitbucket.org/pypy/pypy/changeset/b1f98b2e68b5/

Log:	PPC Backend #3 (1/2): intermediate progress

diff --git a/rpython/jit/backend/ppc/arch.py b/rpython/jit/backend/ppc/arch.py
--- a/rpython/jit/backend/ppc/arch.py
+++ b/rpython/jit/backend/ppc/arch.py
@@ -1,5 +1,6 @@
 # Constants that depend on whether we are on 32-bit or 64-bit
 
+import sys
 from rpython.jit.backend.ppc import register as r
 
 import sys
@@ -20,6 +21,10 @@
 IS_PPC_64               = not IS_PPC_32
 MY_COPY_OF_REGS         = 0
 
+IS_BIG_ENDIAN           = sys.byteorder == 'big'
+IS_LITTLE_ENDIAN        = sys.byteorder == 'little'
+assert IS_BIG_ENDIAN ^ IS_LITTLE_ENDIAN
+
 #FORCE_INDEX             = WORD
 #GPR_SAVE_AREA           = len(NONVOLATILES) * WORD
 #FLOAT_INT_CONVERSION    = WORD
@@ -32,28 +37,29 @@
 #FORCE_INDEX_OFS         = (len(MANAGED_REGS) + len(MANAGED_FP_REGS)) * WORD
 
 
+#                                      BIG ENDIAN       LITTLE ENDIAN
 #
-#        +--------------------+     <-  SP + STD_FRAME_SIZE
+#        +--------------------+     <-      SP + STD_FRAME_SIZE
 #        |  general registers |
 #        |  save area         |
-#        +--------------------+     <-  SP + 120
-#        |  Local vars (*)    |
-#        +--------------------+     <-  SP + 112
+#        +--------------------+     <-  SP + 120          SP + 104
+#        |  Local vars        |
+#        +--------------------+     <-  SP + 112          SP + 96
 #        |  Parameter save    |
 #        |  area (8 args max) |
-#        +--------------------+     <-  SP + 48
+#        +--------------------+     <-  SP + 48           SP + 32
 #        |  TOC (unused)      |
-#        +--------------------+     <-  SP + 40
+#        +--------------------+     <-  SP + 40           SP + 24
 #        |  link ed. (unused) |
-#        +--------------------+     <-  SP + 32
+#        +--------------------+     <-  SP + 32           absent
 #        |  compiler (unused) |
-#        +--------------------+     <-  SP + 24
+#        +--------------------+     <-  SP + 24           absent
 #        |  LR save area      |
-#        +--------------------+     <-  SP + 16
+#        +--------------------+     <-  SP + 16           SP + 16
 #        |  CR save (unused)  |
-#        +--------------------+     <-  SP + 8
+#        +--------------------+     <-  SP + 8            SP + 8
 #        |  SP back chain     |
-#        +--------------------+     <-  SP
+#        +--------------------+     <-  SP                SP
 
 # The local variables area contains only a copy of the 2nd argument
 # passed to the machine code function, which is the ll_threadlocal_addr.
@@ -62,9 +68,10 @@
 
 
 LR_BC_OFFSET            = 16
-PARAM_SAVE_AREA_OFFSET  = 48
-THREADLOCAL_ADDR_OFFSET = 112
-GPR_SAVE_AREA_OFFSET    = 120
+_GAP                    = 0 if IS_BIG_ENDIAN else 16
+PARAM_SAVE_AREA_OFFSET  = 48 - _GAP
+THREADLOCAL_ADDR_OFFSET = 112 - _GAP
+GPR_SAVE_AREA_OFFSET    = 120 - _GAP
 
 REGISTERS_SAVED         = [r.r25, r.r26, r.r27, r.r28, r.r29, r.r30, r.r31]
 assert REGISTERS_SAVED == [_r for _r in r.NONVOLATILES
diff --git a/rpython/jit/backend/ppc/asmfunc.py b/rpython/jit/backend/ppc/asmfunc.py
deleted file mode 100644
--- a/rpython/jit/backend/ppc/asmfunc.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import py
-import mmap, struct
-
-from rpython.jit.backend.ppc.codebuf import MachineCodeBlockWrapper
-from rpython.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
-from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.jit.backend.ppc.arch import IS_PPC_32, IS_PPC_64, WORD
-from rpython.rlib.rarithmetic import r_uint
-
-_ppcgen = None
-
-def get_ppcgen():
-    global _ppcgen
-    if _ppcgen is None:
-        _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c')._getpymodule()
-    return _ppcgen
-
-class AsmCode(object):
-    def __init__(self, size):
-        self.code = MachineCodeBlockWrapper()
-        if IS_PPC_64:
-            # allocate function descriptor - 3 doublewords
-            for i in range(6):
-                self.emit(r_uint(0))
-
-    def emit(self, word):
-        self.code.writechar(chr((word >> 24) & 0xFF))
-        self.code.writechar(chr((word >> 16) & 0xFF))
-        self.code.writechar(chr((word >> 8) & 0xFF))
-        self.code.writechar(chr(word & 0xFF))
-
-    def get_function(self):
-        i = self.code.materialize(AsmMemoryManager(), [])
-        if IS_PPC_64:
-            p = rffi.cast(rffi.CArrayPtr(lltype.Signed), i)
-            p[0] = i + 3*WORD
-            # p[1], p[2] = ??
-        t = lltype.FuncType([], lltype.Signed)
-        return rffi.cast(lltype.Ptr(t), i)
diff --git a/rpython/jit/backend/ppc/callbuilder.py b/rpython/jit/backend/ppc/callbuilder.py
--- a/rpython/jit/backend/ppc/callbuilder.py
+++ b/rpython/jit/backend/ppc/callbuilder.py
@@ -1,6 +1,7 @@
-from rpython.jit.backend.ppc.arch import IS_PPC_64, WORD
+from rpython.jit.backend.ppc.arch import IS_PPC_64, WORD, PARAM_SAVE_AREA_OFFSET
+from rpython.jit.backend.ppc.arch import IS_BIG_ENDIAN, IS_LITTLE_ENDIAN
 import rpython.jit.backend.ppc.register as r
-from rpython.jit.metainterp.history import INT
+from rpython.jit.metainterp.history import INT, FLOAT
 from rpython.jit.backend.llsupport.callbuilder import AbstractCallBuilder
 from rpython.jit.backend.ppc.jump import remap_frame_layout
 
@@ -11,6 +12,15 @@
 
 
 class CallBuilder(AbstractCallBuilder):
+    GPR_ARGS = [r.r3, r.r4, r.r5, r.r6, r.r7, r.r8, r.r9, r.r10]
+    FPR_ARGS = r.MANAGED_FP_REGS
+    assert FPR_ARGS == [r.f1, r.f2, r.f3, r.f4, r.f5, r.f6, r.f7,
+                        r.f8, r.f9, r.f10, r.f11, r.f12, r.f13]
+
+    if IS_BIG_ENDIAN:
+        FNREG = r.r2
+    else:
+        FNREG = r.r12
 
     def __init__(self, assembler, fnloc, arglocs, resloc):
         AbstractCallBuilder.__init__(self, assembler, fnloc, arglocs,
@@ -18,18 +28,73 @@
 
     def prepare_arguments(self):
         assert IS_PPC_64
-
-        # First, copy fnloc into r2
-        self.asm.regalloc_mov(self.fnloc, r.r2)
+        self.subtracted_to_sp = 0
 
         # Prepare arguments
         arglocs = self.arglocs
-        argtypes = self.argtypes
+        num_args = len(arglocs)
 
-        assert len(argtypes) <= 8, "XXX"
-        non_float_locs = arglocs
-        non_float_regs = (           # XXX
-            [r.r3, r.r4, r.r5, r.r6, r.r7, r.r8, r.r9, r.r10][:len(argtypes)])
+        non_float_locs = []
+        non_float_regs = []
+        float_locs = []
+        for i in range(min(num_args, 8)):
+            if arglocs[i].type != FLOAT:
+                non_float_locs.append(arglocs[i])
+                non_float_regs.append(self.GPR_ARGS[i])
+            else:
+                float_locs.append(arglocs[i])
+        # now 'non_float_locs' and 'float_locs' together contain the
+        # locations of the first 8 arguments
+
+        if num_args > 8:
+            # We need to make a larger PPC stack frame, as shown on the
+            # picture in arch.py.  It needs to be 48 bytes + 8 * num_args.
+            # The new SP back chain location should point to the top of
+            # the whole stack frame, i.e. jumping over both the existing
+            # fixed-sise part and the new variable-sized part.
+            base = PARAM_SAVE_AREA_OFFSET
+            varsize = base + 8 * num_args
+            varsize = (varsize + 15) & ~15    # align
+            self.mc.load(r.SCRATCH2.value, r.SP.value, 0)    # SP back chain
+            self.mc.store_update(r.SCRATCH2.value, r.SP.value, -varsize)
+            self.subtracted_to_sp = varsize
+
+            # In this variable-sized part, only the arguments from the 8th
+            # one need to be written, starting at SP + 112
+            for n in range(8, num_args):
+                loc = arglocs[n]
+                if loc.type != FLOAT:
+                    # after the 8th argument, a non-float location is
+                    # always stored in the stack
+                    if loc.is_reg():
+                        src = loc.value
+                    else:
+                        src = r.r2
+                        self.asm.regalloc_mov(loc, src)
+                    self.mc.std(src.value, r.SP.value, base + 8 * n)
+                else:
+                    # the first 13 floating-point arguments are all passed
+                    # in the registers f1 to f13, independently on their
+                    # index in the complete list of arguments
+                    if len(float_locs) < len(self.FPR_ARGS):
+                        float_locs.append(loc)
+                    else:
+                        if loc.is_fp_reg():
+                            src = loc.value
+                        else:
+                            src = r.FP_SCRATCH
+                            self.asm.regalloc_mov(loc, src)
+                        self.mc.stfd(src.value, r.SP.value, base + 8 * n)
+
+        # We must also copy fnloc into FNREG
+        non_float_locs.append(self.fnloc)
+        non_float_regs.append(self.FNREG)
+
+        if float_locs:
+            assert len(float_locs) <= len(self.FPR_ARGS)
+            remap_frame_layout(self.asm, float_locs,
+                               self.FPR_ARGS[:len(float_locs)],
+                               r.FP_SCRATCH)
 
         remap_frame_layout(self.asm, non_float_locs, non_float_regs,
                            r.SCRATCH)
@@ -42,19 +107,25 @@
         pass  # XXX
 
     def emit_raw_call(self):
-        # Load the function descriptor (currently in r2) from memory:
-        #  [r2 + 0]  -> ctr
-        #  [r2 + 16] -> r11
-        #  [r2 + 8]  -> r2  (= TOC)
-        self.mc.ld(r.SCRATCH.value, r.r2.value, 0)
-        self.mc.ld(r.r11.value, r.r2.value, 16)
-        self.mc.mtctr(r.SCRATCH.value)
-        self.mc.ld(r.TOC.value, r.r2.value, 8)
-        # Call it
+        if IS_BIG_ENDIAN:
+            # Load the function descriptor (currently in r2) from memory:
+            #  [r2 + 0]  -> ctr
+            #  [r2 + 16] -> r11
+            #  [r2 + 8]  -> r2  (= TOC)
+            assert self.FNREG is r.r2
+            self.mc.ld(r.SCRATCH.value, r.r2.value, 0)
+            self.mc.ld(r.r11.value, r.r2.value, 16)
+            self.mc.mtctr(r.SCRATCH.value)
+            self.mc.ld(r.TOC.value, r.r2.value, 8)   # must be last: TOC is r2
+        elif IS_LITTLE_ENDIAN:
+            assert self.FNREG is r.r12
+            self.mc.mtctr(r.r12.value)
+        # Call the function
         self.mc.bctrl()
 
     def restore_stack_pointer(self):
-        pass  # XXX
+        if self.subtracted_to_sp != 0:
+            self.mc.addi(r.SP.value, r.SP.value, self.subtracted_to_sp)
 
     def load_result(self):
         pass
diff --git a/rpython/jit/backend/ppc/codebuilder.py b/rpython/jit/backend/ppc/codebuilder.py
--- a/rpython/jit/backend/ppc/codebuilder.py
+++ b/rpython/jit/backend/ppc/codebuilder.py
@@ -2,8 +2,8 @@
 from rpython.jit.backend.ppc.ppc_form import PPCForm as Form
 from rpython.jit.backend.ppc.locations import RegisterLocation
 from rpython.jit.backend.ppc.ppc_field import ppc_fields
-from rpython.jit.backend.ppc.arch import (IS_PPC_32, WORD, IS_PPC_64, 
-                                       LR_BC_OFFSET)
+from rpython.jit.backend.ppc.arch import (IS_PPC_32, WORD, IS_PPC_64,
+                                LR_BC_OFFSET, IS_BIG_ENDIAN, IS_LITTLE_ENDIAN)
 import rpython.jit.backend.ppc.register as r
 import rpython.jit.backend.ppc.condition as c
 from rpython.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
@@ -944,10 +944,16 @@
 
     def write32(self, word):
         index = self.index
-        self.mc.overwrite(index,     chr((word >> 24) & 0xff))
-        self.mc.overwrite(index + 1, chr((word >> 16) & 0xff))
-        self.mc.overwrite(index + 2, chr((word >> 8) & 0xff))
-        self.mc.overwrite(index + 3, chr(word & 0xff))
+        if IS_BIG_ENDIAN:
+            self.mc.overwrite(index,     chr((word >> 24) & 0xff))
+            self.mc.overwrite(index + 1, chr((word >> 16) & 0xff))
+            self.mc.overwrite(index + 2, chr((word >> 8) & 0xff))
+            self.mc.overwrite(index + 3, chr(word & 0xff))
+        elif IS_LITTLE_ENDIAN:
+            self.mc.overwrite(index    , chr(word & 0xff))
+            self.mc.overwrite(index + 1, chr((word >> 8) & 0xff))
+            self.mc.overwrite(index + 2, chr((word >> 16) & 0xff))
+            self.mc.overwrite(index + 3, chr((word >> 24) & 0xff))
         self.index = index + 4
 
     def overwrite(self):
@@ -1031,42 +1037,42 @@
             self.mtctr(r.SCRATCH.value)
         self.bctrl()
 
-    def call(self, address):
-        """ do a call to an absolute address
-        """
-        with scratch_reg(self):
-            if IS_PPC_32:
-                self.load_imm(r.SCRATCH, address)
-            else:
-                self.store(r.TOC.value, r.SP.value, 5 * WORD)
-                self.load_imm(r.r11, address)
-                self.load(r.SCRATCH.value, r.r11.value, 0)
-                self.load(r.TOC.value, r.r11.value, WORD)
-                self.load(r.r11.value, r.r11.value, 2 * WORD)
-            self.mtctr(r.SCRATCH.value)
-        self.bctrl()
+    ## def call(self, address):
+    ##     """ do a call to an absolute address
+    ##     """
+    ##     with scratch_reg(self):
+    ##         if IS_PPC_32:
+    ##             self.load_imm(r.SCRATCH, address)
+    ##         else:
+    ##             self.store(r.TOC.value, r.SP.value, 5 * WORD)
+    ##             self.load_imm(r.r11, address)
+    ##             self.load(r.SCRATCH.value, r.r11.value, 0)
+    ##             self.load(r.TOC.value, r.r11.value, WORD)
+    ##             self.load(r.r11.value, r.r11.value, 2 * WORD)
+    ##         self.mtctr(r.SCRATCH.value)
+    ##     self.bctrl()
 
-        if IS_PPC_64:
-            self.load(r.TOC.value, r.SP.value, 5 * WORD)
+    ##     if IS_PPC_64:
+    ##         self.load(r.TOC.value, r.SP.value, 5 * WORD)
 
-    def call_register(self, call_reg):
-        """ do a call to an address given in a register
-        """
-        assert isinstance(call_reg, RegisterLocation)
-        with scratch_reg(self):
-            if IS_PPC_32:
-                self.mr(r.SCRATCH.value, call_reg.value)
-            else:
-                self.store(r.TOC.value, r.SP.value, 5 * WORD)
-                self.mr(r.r11.value, call_reg.value)
-                self.load(r.SCRATCH.value, r.r11.value, 0)
-                self.load(r.TOC.value, r.r11.value, WORD)
-                self.load(r.r11.value, r.r11.value, 2 * WORD)
-            self.mtctr(r.SCRATCH.value)
-        self.bctrl()
+    ## def call_register(self, call_reg):
+    ##     """ do a call to an address given in a register
+    ##     """
+    ##     assert isinstance(call_reg, RegisterLocation)
+    ##     with scratch_reg(self):
+    ##         if IS_PPC_32:
+    ##             self.mr(r.SCRATCH.value, call_reg.value)
+    ##         else:
+    ##             self.store(r.TOC.value, r.SP.value, 5 * WORD)
+    ##             self.mr(r.r11.value, call_reg.value)
+    ##             self.load(r.SCRATCH.value, r.r11.value, 0)
+    ##             self.load(r.TOC.value, r.r11.value, WORD)
+    ##             self.load(r.r11.value, r.r11.value, 2 * WORD)
+    ##         self.mtctr(r.SCRATCH.value)
+    ##     self.bctrl()
 
-        if IS_PPC_64:
-            self.load(r.TOC.value, r.SP.value, 5 * WORD)
+    ##     if IS_PPC_64:
+    ##         self.load(r.TOC.value, r.SP.value, 5 * WORD)
 
     ## def make_function_prologue(self, frame_size):
     ##     """ Build a new stackframe of size frame_size 
@@ -1140,20 +1146,36 @@
             f.close()
 
     def write32(self, word):
-        self.writechar(chr((word >> 24) & 0xFF))
-        self.writechar(chr((word >> 16) & 0xFF))
-        self.writechar(chr((word >> 8) & 0xFF))
-        self.writechar(chr(word & 0xFF))
+        if IS_BIG_ENDIAN:
+            self.writechar(chr((word >> 24) & 0xFF))
+            self.writechar(chr((word >> 16) & 0xFF))
+            self.writechar(chr((word >> 8) & 0xFF))
+            self.writechar(chr(word & 0xFF))
+        elif IS_LITTLE_ENDIAN:
+            self.writechar(chr(word & 0xFF))
+            self.writechar(chr((word >> 8) & 0xFF))
+            self.writechar(chr((word >> 16) & 0xFF))
+            self.writechar(chr((word >> 24) & 0xFF))
 
     def write64(self, word):
-        self.writechar(chr((word >> 56) & 0xFF))
-        self.writechar(chr((word >> 48) & 0xFF))
-        self.writechar(chr((word >> 40) & 0xFF))
-        self.writechar(chr((word >> 32) & 0xFF))
-        self.writechar(chr((word >> 24) & 0xFF))
-        self.writechar(chr((word >> 16) & 0xFF))
-        self.writechar(chr((word >> 8) & 0xFF))
-        self.writechar(chr(word & 0xFF))
+        if IS_BIG_ENDIAN:
+            self.writechar(chr((word >> 56) & 0xFF))
+            self.writechar(chr((word >> 48) & 0xFF))
+            self.writechar(chr((word >> 40) & 0xFF))
+            self.writechar(chr((word >> 32) & 0xFF))
+            self.writechar(chr((word >> 24) & 0xFF))
+            self.writechar(chr((word >> 16) & 0xFF))
+            self.writechar(chr((word >> 8) & 0xFF))
+            self.writechar(chr(word & 0xFF))
+        elif IS_LITTLE_ENDIAN:
+            self.writechar(chr(word & 0xFF))
+            self.writechar(chr((word >> 8) & 0xFF))
+            self.writechar(chr((word >> 16) & 0xFF))
+            self.writechar(chr((word >> 24) & 0xFF))
+            self.writechar(chr((word >> 32) & 0xFF))
+            self.writechar(chr((word >> 40) & 0xFF))
+            self.writechar(chr((word >> 48) & 0xFF))
+            self.writechar(chr((word >> 56) & 0xFF))
 
     def currpos(self):
         return self.get_relative_pos()
diff --git a/rpython/jit/backend/ppc/opassembler.py b/rpython/jit/backend/ppc/opassembler.py
--- a/rpython/jit/backend/ppc/opassembler.py
+++ b/rpython/jit/backend/ppc/opassembler.py
@@ -5,7 +5,8 @@
 from rpython.jit.backend.ppc.locations import imm
 from rpython.jit.backend.ppc.locations import imm as make_imm_loc
 from rpython.jit.backend.ppc.arch import (IS_PPC_32, IS_PPC_64, WORD,
-                                          MAX_REG_PARAMS, MAX_FREG_PARAMS)
+                                          MAX_REG_PARAMS, MAX_FREG_PARAMS,
+                                          PARAM_SAVE_AREA_OFFSET)
 
 from rpython.jit.metainterp.history import (JitCellToken, TargetToken, Box,
                                             AbstractFailDescr, FLOAT, INT, REF)
@@ -232,24 +233,24 @@
     def emit_cast_float_to_int(self, op, arglocs, regalloc):
         l0, temp_loc, res = arglocs
         self.mc.fctidz(temp_loc.value, l0.value)
-        self.mc.stfd(temp_loc.value, r.SP.value, -16)
-        self.mc.ld(res.value, r.SP.value, -16)
+        self.mc.stfd(temp_loc.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
+        self.mc.ld(res.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
 
     def emit_cast_int_to_float(self, op, arglocs, regalloc):
         l0, res = arglocs
-        self.mc.std(l0.value, r.SP.value, -16)
-        self.mc.lfd(res.value, r.SP.value, -16)
+        self.mc.std(l0.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
+        self.mc.lfd(res.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
         self.mc.fcfid(res.value, res.value)
 
     def emit_convert_float_bytes_to_longlong(self, op, arglocs, regalloc):
         l0, res = arglocs
-        self.mc.stfd(l0.value, r.SP.value, -16)
-        self.mc.ld(res.value, r.SP.value, -16)
+        self.mc.stfd(l0.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
+        self.mc.ld(res.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
 
     def emit_convert_longlong_bytes_to_float(self, op, arglocs, regalloc):
         l0, res = arglocs
-        self.mc.std(l0.value, r.SP.value, -16)
-        self.mc.lfd(res.value, r.SP.value, -16)
+        self.mc.std(l0.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
+        self.mc.lfd(res.value, r.SP.value, PARAM_SAVE_AREA_OFFSET)
 
 class GuardOpAssembler(object):
 
diff --git a/rpython/jit/backend/ppc/ppc_assembler.py b/rpython/jit/backend/ppc/ppc_assembler.py
--- a/rpython/jit/backend/ppc/ppc_assembler.py
+++ b/rpython/jit/backend/ppc/ppc_assembler.py
@@ -7,7 +7,8 @@
                                           LR_BC_OFFSET, REGISTERS_SAVED,
                                           GPR_SAVE_AREA_OFFSET,
                                           THREADLOCAL_ADDR_OFFSET,
-                                          STD_FRAME_SIZE_IN_BYTES)
+                                          STD_FRAME_SIZE_IN_BYTES,
+                                          IS_BIG_ENDIAN)
 from rpython.jit.backend.ppc.helper.assembler import Saved_Volatiles
 from rpython.jit.backend.ppc.helper.regalloc import _check_imm_arg
 import rpython.jit.backend.ppc.register as r
@@ -354,9 +355,9 @@
             frame_size += WORD
 
         # write function descriptor
-        if IS_PPC_64:
-            for _ in range(6):
-                mc.write32(0)
+        if IS_PPC_64 and IS_BIG_ENDIAN:
+            for _ in range(3):
+                mc.write64(0)
 
         # build frame
         mc.make_function_prologue(frame_size)
@@ -550,7 +551,7 @@
     #    self.mc.b_offset(loophead)
 
     def _call_header(self):
-        if IS_PPC_64:
+        if IS_PPC_64 and IS_BIG_ENDIAN:
             # Reserve space for a function descriptor, 3 words
             self.mc.write64(0)
             self.mc.write64(0)
@@ -717,7 +718,7 @@
         full_size = self.mc.get_relative_pos()
         #
         rawstart = self.materialize_loop(looptoken)
-        if IS_PPC_64:    # fix the function descriptor (3 words)
+        if IS_PPC_64 and IS_BIG_ENDIAN:  # fix the function descriptor (3 words)
             rffi.cast(rffi.LONGP, rawstart)[0] = rawstart + 3 * WORD
         #
         self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE,
@@ -788,6 +789,7 @@
                                              self.current_clt.allgcrefs,
                                              self.current_clt.frame_info)
         #self._check_frame_depth(self.mc, regalloc.get_gcmap())
+        #        XXX ^^^^^^^^^^
         frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations)
         codeendpos = self.mc.get_relative_pos()
         self.write_pending_failure_recoveries()
diff --git a/rpython/jit/backend/ppc/test/test_runner.py b/rpython/jit/backend/ppc/test/test_runner.py
--- a/rpython/jit/backend/ppc/test/test_runner.py
+++ b/rpython/jit/backend/ppc/test/test_runner.py
@@ -202,3 +202,37 @@
         assert fail.identifier == 5
         res = self.cpu.get_int_value(deadframe, 0)
         assert res == -42 + NUM
+
+    def test_call_many_float_args(self):
+        from rpython.rtyper.annlowlevel import llhelper
+        from rpython.jit.codewriter.effectinfo import EffectInfo
+
+        seen = []
+        def func(*args):
+            seen.append(args)
+            return -42
+
+        F = lltype.Float
+        I = lltype.Signed
+        FUNC = self.FuncType([F] * 7 + [I] + [F] * 7 + [I] + [F], I)
+        FPTR = self.Ptr(FUNC)
+        func_ptr = llhelper(FPTR, func)
+        cpu = self.cpu
+        calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+                                    EffectInfo.MOST_GENERAL)
+        funcbox = self.get_funcbox(cpu, func_ptr)
+        argvals = [.1 * i for i in range(15)]
+        argvals.insert(7, 77)
+        argvals.insert(15, 1515)
+        argvals = tuple(argvals)
+        argboxes = []
+        for x in argvals:
+            if isinstance(x, float):
+                argboxes.append(BoxFloat(x))
+            else:
+                argboxes.append(BoxInt(x))
+        res = self.execute_operation(rop.CALL,
+                                     [funcbox] + argboxes,
+                                     'int', descr=calldescr)
+        assert res.value == -42
+        assert seen == [argvals]
diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py
--- a/rpython/jit/backend/tool/viewcode.py
+++ b/rpython/jit/backend/tool/viewcode.py
@@ -56,7 +56,9 @@
     }
     cmd = find_objdump()
     objdump = ('%(command)s -b binary -m %(machine)s '
-               '--endian=%(endianness)s '
+               # NOTE: specifying endianness is annoying to debug the ppc
+               # backend on little-endian machines; better use the native one
+               #'--endian=%(endianness)s '
                '--disassembler-options=intel-mnemonics '
                '--adjust-vma=%(origin)d -D %(file)s')
     #


More information about the pypy-commit mailing list