Commits

Sven Hager committed fc74b87

Save and restore nonvolatile registers, made test_call_many_arguments pass.

Comments (0)

Files changed (3)

pypy/jit/backend/ppc/ppcgen/arch.py

     IS_PPC_32 = False
     IS_PPC_64 = True
 
+NONVOLATILES    = [2] + range(13, 32)
+VOLATILES       = [0] + range(3, 13)

pypy/jit/backend/ppc/ppcgen/ppc_assembler.py

 from pypy.jit.backend.ppc.ppcgen.ppc_field import ppc_fields
 from pypy.jit.backend.ppc.ppcgen.assembler import Assembler
 from pypy.jit.backend.ppc.ppcgen.symbol_lookup import lookup
-from pypy.jit.backend.ppc.ppcgen.arch import IS_PPC_32
+from pypy.jit.backend.ppc.ppcgen.arch import IS_PPC_32, WORD, NONVOLATILES
 from pypy.jit.metainterp.history import Const, ConstPtr
 from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
 from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
             self.ld(rD, rD, 0)
 
     def store_reg(self, source_reg, addr):
+        self.load_word(0, addr)
         if IS_PPC_32:
-            self.addis(10, 0, ha(addr))
-            self.stw(source_reg, 10, la(addr))
+            self.stwx(source_reg, 0, 0)
         else:
-            self.load_word(10, addr)
-            self.std(source_reg, 10, 0)
+            # ? 
+            self.std(source_reg, 0, 10)
+
+    def save_nonvolatiles(self, framesize):
+        for i, reg in enumerate(NONVOLATILES):
+            self.stw(reg, 1, framesize - 4 * i)
+
+    def restore_nonvolatiles(self, framesize):
+        for i, reg in enumerate(NONVOLATILES):
+            self.lwz(reg, 1, framesize - i * 4)
+        
 
     # translate a trace operation to corresponding machine code
     def build_op(self, trace_op, cpu):
         call_addr = rffi.cast(lltype.Signed, op.getarg(0).value)
         args = op.getarglist()[1:]
         descr = op.getdescr()
+        num_args = len(args)
 
+        # pass first arguments in registers
         arg_reg = 3
         for arg in args:
             if isinstance(arg, Box):
             else:
                 assert 0, "%s not supported yet" % arg
             arg_reg += 1
+            if arg_reg == 11:
+                break
+
+        # if the function takes more than 8 arguments,
+        # pass remaining arguments on stack
+        if num_args > 8:
+            remaining_args = args[8:]
+            for i, arg in enumerate(remaining_args):
+                if isinstance(arg, Box):
+                    #self.mr(0, cpu.reg_map[arg])
+                    self.stw(cpu.reg_map[arg], 1, 8 + WORD * i)
+                elif isinstance(arg, Const):
+                    self.load_word(0, arg.value)
+                    self.stw(0, 1, 8 + WORD * i)
+                else:
+                    assert 0, "%s not supported yet" % arg
 
         self.load_word(0, call_addr)
         self.mtctr(0)
                 self.store_reg(cpu.next_free_register, addr)
             else:
                 assert 0, "arg type not suported"
-        self.lwz(0, 1, 36)
+
+        framesize = 64 + 80
+
+        self.restore_nonvolatiles(framesize)
+
+        self.lwz(0, 1, framesize + 4) # 36
         self.mtlr(0)
-        self.addi(1, 1, 32)
+        self.addi(1, 1, framesize)
         self.load_word(3, identifier)
         self.blr()
 

pypy/jit/backend/ppc/runner.py

 from pypy.jit.backend.x86 import regloc
 from pypy.jit.backend.x86.support import values_array
 from pypy.jit.backend.ppc.ppcgen.ppc_assembler import PPCBuilder
+from pypy.jit.backend.ppc.ppcgen.arch import NONVOLATILES
 import sys
 
 from pypy.tool.ansi_print import ansi_log
 log = py.log.Producer('jitbackend')
 py.log.setconsumer('jitbackend', ansi_log)
 
-
 class PPC_64_CPU(AbstractLLCPU):
 
     def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
 
         codebuilder = PPCBuilder()
         
+        # function prologue
+        self._make_prologue(codebuilder)
+
         # initialize registers from memory
         self.next_free_register = 3
         for index, arg in enumerate(inputargs):
         
         self.startpos = codebuilder.get_relative_pos()
 
-        self._make_prologue(codebuilder)
+        # generate code for operations
         self._walk_trace_ops(codebuilder, operations)
+
+        # function epilogue
         self._make_epilogue(codebuilder)
 
         f = codebuilder.assemble()
         return reg
 
     def _make_prologue(self, codebuilder):
-        codebuilder.stwu(1, 1, -32)
+        framesize = 64 + 80
+        codebuilder.stwu(1, 1, -framesize)
         codebuilder.mflr(0)
-        codebuilder.stw(0, 1, 36)
+        codebuilder.stw(0, 1, framesize + 4)
+        codebuilder.save_nonvolatiles(framesize)
 
     def _make_epilogue(self, codebuilder):
         for op_index, fail_index, guard, reglist in self.patch_list:
             descr.patch_pos = patch_pos
             descr.used_mem_indices = used_mem_indices
 
-            codebuilder.lwz(0, 1, 36)
+            framesize = 64 + 80
+            codebuilder.restore_nonvolatiles(framesize)
+
+            codebuilder.lwz(0, 1, framesize + 4) # 36
             codebuilder.mtlr(0)
-            codebuilder.addi(1, 1, 32)
+            codebuilder.addi(1, 1, framesize)
 
             codebuilder.li(3, fail_index)            
             codebuilder.blr()