[pypy-commit] pypy ppc-jit-backend: Save and restore nonvolatile registers, made test_call_many_arguments pass.
hager
noreply at buildbot.pypy.org
Thu Sep 1 18:05:28 CEST 2011
Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r46990:fc74b87ee65e
Date: 2011-09-01 18:05 +0200
http://bitbucket.org/pypy/pypy/changeset/fc74b87ee65e/
Log: Save and restore nonvolatile registers, made
test_call_many_arguments pass.
diff --git a/pypy/jit/backend/ppc/ppcgen/arch.py b/pypy/jit/backend/ppc/ppcgen/arch.py
--- a/pypy/jit/backend/ppc/ppcgen/arch.py
+++ b/pypy/jit/backend/ppc/ppcgen/arch.py
@@ -10,3 +10,5 @@
IS_PPC_32 = False
IS_PPC_64 = True
+NONVOLATILES = [2] + range(13, 32)
+VOLATILES = [0] + range(3, 13)
diff --git a/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py b/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py
--- a/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py
+++ b/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py
@@ -4,7 +4,7 @@
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
@@ -932,12 +932,21 @@
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):
@@ -1399,7 +1408,9 @@
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):
@@ -1409,6 +1420,22 @@
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)
@@ -1562,9 +1589,14 @@
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()
diff --git a/pypy/jit/backend/ppc/runner.py b/pypy/jit/backend/ppc/runner.py
--- a/pypy/jit/backend/ppc/runner.py
+++ b/pypy/jit/backend/ppc/runner.py
@@ -12,13 +12,13 @@
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,
@@ -46,6 +46,9 @@
codebuilder = PPCBuilder()
+ # function prologue
+ self._make_prologue(codebuilder)
+
# initialize registers from memory
self.next_free_register = 3
for index, arg in enumerate(inputargs):
@@ -56,8 +59,10 @@
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()
@@ -106,9 +111,11 @@
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:
@@ -135,9 +142,12 @@
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()
More information about the pypy-commit
mailing list