Author: hager <[email protected]>
Branch: ppc-jit-backend
Changeset: r47164:f1da4802e995
Date: 2011-09-08 15:29 +0200
http://bitbucket.org/pypy/pypy/changeset/f1da4802e995/
Log: (arigo, hager): Started refactoring of the PPC cpu and assembler.
The goal is to have code which is similar to the ARM backend. Most
important: Use register allocator.
diff --git a/pypy/jit/backend/llsupport/regalloc.py
b/pypy/jit/backend/llsupport/regalloc.py
--- a/pypy/jit/backend/llsupport/regalloc.py
+++ b/pypy/jit/backend/llsupport/regalloc.py
@@ -1,4 +1,3 @@
-
from pypy.jit.metainterp.history import Const, Box, REF
from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp.resoperation import rop
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,5 +10,10 @@
IS_PPC_32 = False
IS_PPC_64 = True
+ALL_REGS = range(32)
NONVOLATILES = [2] + range(13, 32)
VOLATILES = [0] + range(3, 13)
+
+MY_COPY_OF_REGS = 0
+
+GPR_SAVE_AREA = len(NONVOLATILES) * WORD
diff --git a/pypy/jit/backend/ppc/ppcgen/locations.py
b/pypy/jit/backend/ppc/ppcgen/locations.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/ppc/ppcgen/locations.py
@@ -0,0 +1,62 @@
+from pypy.jit.metainterp.history import INT, FLOAT, REF
+from pypy.jit.backend.arm.arch import WORD
+class AssemblerLocation(object):
+ _immutable_ = True
+ type = INT
+
+ def is_imm(self):
+ return False
+
+ def is_stack(self):
+ return False
+
+ def is_reg(self):
+ return False
+
+ def is_vfp_reg(self):
+ return False
+
+ def is_imm_float(self):
+ return False
+
+ def as_key(self):
+ raise NotImplementedError
+
+class RegisterLocation(AssemblerLocation):
+ _immutable_ = True
+ width = WORD
+
+ def __init__(self, value):
+ self.value = value
+
+ def __repr__(self):
+ return 'r%d' % self.value
+
+ def is_reg(self):
+ return True
+
+ def as_key(self):
+ return self.value
+
+class ImmLocation(AssemblerLocation):
+ _immutable_ = True
+ width = WORD
+
+
+ def __init__(self, value):
+ self.value = value
+
+ def getint(self):
+ return self.value
+
+ def __repr__(self):
+ return "imm(%d)" % (self.value)
+
+ def is_imm(self):
+ return True
+
+ def as_key(self):
+ return self.value + 40
+
+def imm(val):
+ return ImmLocation(val)
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
@@ -2,16 +2,25 @@
import struct
from pypy.jit.backend.ppc.ppcgen.ppc_form import PPCForm as Form
from pypy.jit.backend.ppc.ppcgen.ppc_field import ppc_fields
+from pypy.jit.backend.ppc.ppcgen.regalloc import (TempInt, PPCFrameManager,
+ Regalloc)
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, WORD, NONVOLATILES
+from pypy.jit.backend.ppc.ppcgen.arch import (IS_PPC_32, WORD, NONVOLATILES,
+ GPR_SAVE_AREA)
+import pypy.jit.backend.ppc.ppcgen.register as r
from pypy.jit.metainterp.history import Const, ConstPtr
from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
+from pypy.jit.backend.llsupport.regalloc import (RegisterManager,
+ compute_vars_longevity)
from pypy.jit.backend.llsupport import symbolic
+from pypy.jit.backend.model import CompiledLoopToken
from pypy.rpython.lltypesystem import lltype, rffi, rstr
from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.metainterp.history import BoxInt, ConstInt, Box
+from pypy.jit.metainterp.history import (BoxInt, ConstInt, ConstPtr,
+ ConstFloat, Box, INT, REF, FLOAT)
+from pypy.jit.backend.x86.support import values_array
A = Form("frD", "frA", "frB", "XO3", "Rc")
A1 = Form("frD", "frB", "XO3", "Rc")
@@ -906,10 +915,13 @@
return (w >> 16) & 0x0000FFFF
class PPCBuilder(PPCAssembler):
- def __init__(self):
+ def __init__(self, cpu, failargs_limit=1000):
PPCAssembler.__init__(self)
+ self.cpu = cpu
+ self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
- def load_word(self, rD, word):
+ def load_imm(self, rD, word):
+ rD = rD.as_key()
if word <= 32767 and word >= -32768:
self.li(rD, word)
elif IS_PPC_32 or (word <= 2147483647 and word >= -2147483648):
@@ -923,7 +935,7 @@
self.oris(rD, rD, high(word))
self.ori(rD, rD, lo(word))
- def load_from(self, rD, addr):
+ def load_from_addr(self, rD, addr):
if IS_PPC_32:
self.addis(rD, 0, ha(addr))
self.lwz(rD, rD, la(addr))
@@ -932,26 +944,78 @@
self.ld(rD, rD, 0)
def store_reg(self, source_reg, addr):
- self.load_word(0, addr)
+ self.load_imm(r.r0, addr)
if IS_PPC_32:
- self.stwx(source_reg, 0, 0)
+ self.stwx(source_reg.value, 0, 0)
else:
- self.stdx(source_reg, 0, 0)
+ # ?
+ self.std(source_reg.value, 0, 10)
- def save_nonvolatiles(self, framesize):
+ def _save_nonvolatiles(self):
for i, reg in enumerate(NONVOLATILES):
- if IS_PPC_32:
- self.stw(reg, 1, framesize - WORD * i)
+ self.stw(reg, 1, self.framesize - 4 * i)
+
+ def _restore_nonvolatiles(self):
+ for i, reg in enumerate(NONVOLATILES):
+ self.lwz(reg, 1, self.framesize - i * 4)
+
+ def _make_prologue(self):
+ self.stwu(1, 1, -self.framesize)
+ self.mflr(0)
+ self.stw(0, 1, self.framesize + 4)
+ self._save_nonvolatiles()
+
+ def _make_epilogue(self):
+ self._restore_nonvolatiles()
+
+ def gen_bootstrap_code(self, nonfloatlocs, inputargs):
+ for i in range(len(nonfloatlocs)):
+ loc = nonfloatlocs[i]
+ arg = inputargs[i]
+ assert arg.type != FLOAT
+ if arg.type == INT:
+ addr = self.fail_boxes_int.get_addr_for_num(i)
+ elif args.type == REF:
+ addr = self.fail_boxes_ptr.get_addr_for_num(i)
else:
- self.std(reg, 1, framesize - WORD * i)
+ assert 0, "%s not supported" % arg.type
+ if loc.is_reg():
+ reg = loc
+ else:
+ assert 0, "FIX LATER"
+ self.load_from_addr(reg.value, addr)
- def restore_nonvolatiles(self, framesize):
- for i, reg in enumerate(NONVOLATILES):
- if IS_PPC_32:
- self.lwz(reg, 1, framesize - WORD * i)
+ def assemble_loop(self, inputargs, operations, looptoken, log):
+ self.framesize = 256 + GPR_SAVE_AREA
+ clt = CompiledLoopToken(self.cpu, looptoken.number)
+ looptoken.compiled_loop_token = clt
+
+ longevity = compute_vars_longevity(inputargs, operations)
+ regalloc = Regalloc(longevity, assembler=self,
+ frame_manager=PPCFrameManager())
+
+ self._make_prologue()
+ nonfloatlocs = regalloc.prepare_loop(inputargs, operations, looptoken)
+ self.gen_bootstrap_code(nonfloatlocs, inputargs)
+ self._walk_operations(operations, regalloc)
+ looptoken.ppc_code = self.assemble(True)
+
+ def _walk_operations(self, operations, regalloc):
+ while regalloc.position() < len(operations) - 1:
+ regalloc.next_instruction()
+ pos = regalloc.position()
+ op = operations[pos]
+ opnum = op.getopnum()
+ if op.has_no_side_effect() and op.result not in regalloc.longevity:
+ regalloc.possibly_free_vars_for_op(op)
else:
- self.ld(reg, 1, framesize - WORD * i)
-
+ arglocs = regalloc.operations[opnum](regalloc, op)
+ if arglocs is not None:
+ self.operations[opnum](self, op, arglocs, regalloc)
+ if op.result:
+ regalloc.possibly_free_var(op.result)
+ regalloc.possibly_free_vars_for_op(op)
+ regalloc._check_invariants()
# translate a trace operation to corresponding machine code
def build_op(self, trace_op, cpu):
@@ -994,14 +1058,23 @@
if isinstance(arg0, Box):
reg0 = cpu.reg_map[arg0]
else:
- reg0 = cpu.get_next_register()
+ #reg0 = cpu.get_next_register()
+ box = TempInt()
+ reg0 = cpu.rm.force_allocate_reg(box)
self.load_word(reg0, arg0.value)
if isinstance(arg1, Box):
reg1 = cpu.reg_map[arg1]
else:
- reg1 = cpu.get_next_register()
+ #reg1 = cpu.get_next_register()
+ #reg1 = cpu.rm.force_allocate_reg(arg1)
+ box = TempInt()
+ reg1 = cpu.rm.force_allocate_reg(box)
+ boxed = cpu.rm.make_sure_var_in_reg(box)
self.load_word(reg1, arg1.value)
- free_reg = cpu.next_free_register
+ import pdb; pdb.set_trace()
+ #free_reg = cpu.next_free_register
+ free_reg = cpu.rm.force_allocate_reg(op.result)
+
return free_reg, reg0, reg1
def _int_op_epilog(self, op, cpu, result_reg):
@@ -1045,8 +1118,14 @@
# CODE GENERATION #
# --------------------------------------- #
- def emit_int_add(self, op, cpu, reg0, reg1, free_reg):
- self.add(free_reg, reg0, reg1)
+ def emit_int_add(self, op, arglocs, regalloc):
+ l0, l1, res = arglocs
+ if l0.is_imm():
+ self.addi(res.value, l1.value, l0.value)
+ elif l1.is_imm():
+ self.addi(res.value, l0.value, l1.value)
+ else:
+ self.add(res.value, l0.value, l1.value)
def emit_int_add_ovf(self, op, cpu, reg0, reg1, free_reg):
self.addo(free_reg, reg0, reg1)
@@ -1419,7 +1498,10 @@
arg_reg = 3
for arg in args:
if isinstance(arg, Box):
- self.mr(arg_reg, cpu.reg_map[arg])
+ try:
+ self.mr(arg_reg, cpu.reg_map[arg])
+ except KeyError:
+ self.lwz(arg_reg, 1, cpu.mem_map[arg])
elif isinstance(arg, Const):
self.load_word(arg_reg, arg.value)
else:
@@ -1435,16 +1517,15 @@
for i, arg in enumerate(remaining_args):
if isinstance(arg, Box):
#self.mr(0, cpu.reg_map[arg])
- if IS_PPC_32:
+ try:
self.stw(cpu.reg_map[arg], 1, 8 + WORD * i)
- else:
- self.std(cpu.reg_map[arg], 1, 8 + WORD * i)
+ except KeyError:
+ self.load_word(0, cpu.mem_map[arg])
+ self.lwzx(0, 1, 0)
+ self.stw(0, 1, 8 + WORD * i)
elif isinstance(arg, Const):
self.load_word(0, arg.value)
- if IS_PPC_32:
- self.stw(0, 1, 8 + WORD * i)
- else:
- self.std(0, 1, 8 + WORD * i)
+ self.stw(0, 1, 8 + WORD * i)
else:
assert 0, "%s not supported yet" % arg
@@ -1584,34 +1665,23 @@
#_____________________________________
- def emit_finish(self, op, cpu):
+ def emit_finish(self, op, arglocs, regalloc):
descr = op.getdescr()
- identifier = self._get_identifier_from_descr(descr, cpu)
- cpu.saved_descr[identifier] = descr
+ identifier = self._get_identifier_from_descr(descr, self.cpu)
+ self.cpu.saved_descr[identifier] = descr
args = op.getarglist()
- for index, arg in enumerate(args):
- if isinstance(arg, Box):
- regnum = cpu.reg_map[arg]
- addr = cpu.fail_boxes_int.get_addr_for_num(index)
- self.store_reg(regnum, addr)
- elif isinstance(arg, ConstInt):
- addr = cpu.fail_boxes_int.get_addr_for_num(index)
- self.load_word(cpu.next_free_register, arg.value)
- self.store_reg(cpu.next_free_register, addr)
- else:
- assert 0, "arg type not suported"
+ for index, arg in enumerate(arglocs):
+ addr = self.fail_boxes_int.get_addr_for_num(index)
+ self.store_reg(arg, addr)
- framesize = 16 * WORD + 20 * WORD
+ framesize = 256 + GPR_SAVE_AREA
- self.restore_nonvolatiles(framesize)
+ self._restore_nonvolatiles()
- if IS_PPC_32:
- self.lwz(0, 1, framesize + WORD) # 36
- else:
- self.ld(0, 1, framesize + WORD) # 36
+ self.lwz(0, 1, framesize + 4) # 36
self.mtlr(0)
self.addi(1, 1, framesize)
- self.load_word(3, identifier)
+ self.load_imm(r.r3, identifier)
self.blr()
def emit_jump(self, op, cpu):
@@ -1694,7 +1764,7 @@
oplist[val] = not_implemented
return oplist
-PPCBuilder.oplist = make_operations()
+PPCBuilder.operations = make_operations()
if __name__ == '__main__':
main()
diff --git a/pypy/jit/backend/ppc/ppcgen/regalloc.py
b/pypy/jit/backend/ppc/ppcgen/regalloc.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/ppc/ppcgen/regalloc.py
@@ -0,0 +1,218 @@
+from pypy.jit.backend.llsupport.regalloc import (RegisterManager, FrameManager,
+ TempBox,
compute_vars_longevity,
+ compute_loop_consts)
+from pypy.jit.backend.ppc.ppcgen.arch import (WORD, MY_COPY_OF_REGS)
+from pypy.jit.metainterp.history import INT, REF, Const, ConstInt, ConstPtr
+from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.backend.ppc.ppcgen import locations
+from pypy.rpython.lltypesystem import rffi, lltype
+import pypy.jit.backend.ppc.ppcgen.register as r
+
+class TempInt(TempBox):
+ type = INT
+
+ def __repr__(self):
+ return "<TempInt at %s>" % (id(self),)
+
+class TempPtr(TempBox):
+ type = REF
+
+ def __repr__(self):
+ return "<TempPtr at %s>" % (id(self),)
+
+class PPCRegisterManager(RegisterManager):
+ all_regs = r.ALL_REGS
+ box_types = None # or a list of acceptable types
+ no_lower_byte_regs = all_regs
+ save_around_call_regs = r.VOLATILES
+
+ REGLOC_TO_COPY_AREA_OFS = {
+ r.r0: MY_COPY_OF_REGS + 0 * WORD,
+ r.r2: MY_COPY_OF_REGS + 1 * WORD,
+ r.r3: MY_COPY_OF_REGS + 2 * WORD,
+ r.r4: MY_COPY_OF_REGS + 3 * WORD,
+ r.r5: MY_COPY_OF_REGS + 4 * WORD,
+ r.r6: MY_COPY_OF_REGS + 5 * WORD,
+ r.r7: MY_COPY_OF_REGS + 6 * WORD,
+ r.r8: MY_COPY_OF_REGS + 7 * WORD,
+ r.r9: MY_COPY_OF_REGS + 8 * WORD,
+ r.r10: MY_COPY_OF_REGS + 9 * WORD,
+ r.r11: MY_COPY_OF_REGS + 10 * WORD,
+ r.r12: MY_COPY_OF_REGS + 11 * WORD,
+ r.r13: MY_COPY_OF_REGS + 12 * WORD,
+ r.r14: MY_COPY_OF_REGS + 13 * WORD,
+ r.r15: MY_COPY_OF_REGS + 14 * WORD,
+ r.r16: MY_COPY_OF_REGS + 15 * WORD,
+ r.r17: MY_COPY_OF_REGS + 16 * WORD,
+ r.r18: MY_COPY_OF_REGS + 17 * WORD,
+ r.r19: MY_COPY_OF_REGS + 18 * WORD,
+ r.r20: MY_COPY_OF_REGS + 19 * WORD,
+ r.r21: MY_COPY_OF_REGS + 20 * WORD,
+ r.r22: MY_COPY_OF_REGS + 21 * WORD,
+ r.r23: MY_COPY_OF_REGS + 22 * WORD,
+ r.r24: MY_COPY_OF_REGS + 23 * WORD,
+ r.r25: MY_COPY_OF_REGS + 24 * WORD,
+ r.r26: MY_COPY_OF_REGS + 25 * WORD,
+ r.r27: MY_COPY_OF_REGS + 26 * WORD,
+ r.r28: MY_COPY_OF_REGS + 27 * WORD,
+ r.r29: MY_COPY_OF_REGS + 28 * WORD,
+ r.r30: MY_COPY_OF_REGS + 29 * WORD,
+ r.r31: MY_COPY_OF_REGS + 30 * WORD,
+ }
+
+ def __init__(self, longevity, frame_manager=None, assembler=None):
+ RegisterManager.__init__(self, longevity, frame_manager, assembler)
+
+ def call_result_location(self, v):
+ return r.r3
+
+ def convert_to_imm(self, c):
+ if isinstance(c, ConstInt):
+ return locations.ImmLocation(c.value)
+ else:
+ assert isinstance(c, ConstPtr)
+ return locations.ImmLocation(rffi.cast(lltype.Signed, c.value))
+
+class PPCFrameManager(FrameManager):
+ def __init__(self):
+ FrameManager.__init__(self)
+ self.frame_depth = 1
+
+class Regalloc(object):
+ def __init__(self, longevity, frame_manager=None, assembler=None):
+ self.cpu = assembler.cpu
+ self.longevity = longevity
+ self.frame_manager = frame_manager
+ self.assembler = assembler
+ self.rm = PPCRegisterManager(longevity, frame_manager, assembler)
+
+ def prepare_loop(self, inputargs, operations, looptoken):
+ loop_consts = compute_loop_consts(inputargs, operations[-1], looptoken)
+ inputlen = len(inputargs)
+ nonfloatlocs = [None] * len(inputargs)
+ for i in range(inputlen):
+ arg = inputargs[i]
+ assert not isinstance(arg, Const)
+ if arg not in loop_consts and self.longevity[arg][1] > -1:
+ self.try_allocate_reg(arg)
+ loc = self.loc(arg)
+ nonfloatlocs[i] = loc
+ self.possibly_free_vars(inputargs)
+ return nonfloatlocs
+
+ def possibly_free_var(self, var):
+ self.rm.possibly_free_var(var)
+
+ def possibly_free_vars(self, vars):
+ for var in vars:
+ self.possibly_free_var(var)
+
+ def possibly_free_vars_for_op(self, op):
+ for i in range(op.numargs()):
+ var = op.getarg(i)
+ if var is not None:
+ self.possibly_free_var(var)
+
+ def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
+ return self.rm.try_allocate_reg(v, selected_reg, need_lower_byte)
+
+ def force_allocate_reg(self, var, forbidden_vars=[], selected_reg=None,
+ need_lower_byte=False):
+ return self.rm.force_allocate_reg(var, forbidden_vars, selected_reg,
+ need_lower_byte)
+
+ def _check_invariants(self):
+ self.rm._check_invariants()
+
+ def loc(self, var):
+ return self.rm.loc(var)
+
+ def position(self):
+ return self.rm.position
+
+ def next_instruction(self):
+ self.rm.next_instruction()
+
+ def _check_imm_arg(self, arg):
+ return isinstance(arg, ConstInt)
+
+ def _ensure_value_is_boxed(self, thing, forbidden_vars=[]):
+ box = None
+ loc = None
+ if isinstance(thing, Const):
+ if isinstance(thing, ConstPtr):
+ box = TempPtr()
+ else:
+ box = TempInt()
+ loc = self.force_allocate_reg(box, forbidden_vars=forbidden_vars)
+ imm = self.rm.convert_to_imm(thing)
+ self.assembler.load_word(loc, imm)
+ else:
+ loc = self.make_sure_var_in_reg(thing,
+ forbidden_vars=forbidden_vars)
+ box = thing
+ return loc, box
+
+ def make_sure_var_in_reg(self, var, forbidden_vars=[],
+ selected_reg=None, need_lower_byte=False):
+ return self.rm.make_sure_var_in_reg(var, forbidden_vars,
+ selected_reg, need_lower_byte)
+
+ # ******************************************************
+ # * P R E P A R E O P E R A T I O N S *
+ # ******************************************************
+
+ def prepare_int_add(self, op):
+ boxes = op.getarglist()
+ b0, b1 = boxes
+ imm_b0 = self._check_imm_arg(b0)
+ imm_b1 = self._check_imm_arg(b1)
+ if not imm_b0 and imm_b1:
+ l0, box = self._ensure_value_is_boxed(b0)
+ l1 = self.make_sure_var_in_reg(b1, [b0])
+ boxes.append(box)
+ elif imm_b0 and not imm_b1:
+ l0 = self.make_sure_var_in_reg(b0)
+ l1, box = self._ensure_value_is_boxed(b1, [b0])
+ boxes.append(box)
+ else:
+ l0, box = self._ensure_value_is_boxed(b0)
+ boxes.append(box)
+ l1, box = self._ensure_value_is_boxed(b1, [box])
+ boxes.append(box)
+ #return [l0, l1], boxes
+ locs = [l0, l1]
+ self.possibly_free_vars(boxes)
+ res = self.force_allocate_reg(op.result)
+ return locs + [res]
+
+ def prepare_finish(self, op):
+ #args = [locations.imm(self.frame_manager.frame_depth)]
+ args = []
+ for i in range(op.numargs()):
+ arg = op.getarg(i)
+ if arg:
+ args.append(self.loc(arg))
+ self.possibly_free_var(arg)
+ else:
+ args.append(None)
+ return args
+
+def make_operation_list():
+ def not_implemented(self, op, *args):
+ raise NotImplementedError, op
+
+ operations = [None] * (rop._LAST + 1)
+ for key, val in rop.__dict__.items():
+ key = key.lower()
+ if key.startswith("_"):
+ continue
+ methname = "prepare_%s" % key
+ if hasattr(Regalloc, methname):
+ func = getattr(Regalloc, methname).im_func
+ else:
+ func = not_implemented
+ operations[val] = func
+ return operations
+
+Regalloc.operations = make_operation_list()
diff --git a/pypy/jit/backend/ppc/ppcgen/register.py
b/pypy/jit/backend/ppc/ppcgen/register.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/ppc/ppcgen/register.py
@@ -0,0 +1,11 @@
+from pypy.jit.backend.ppc.ppcgen.locations import RegisterLocation
+
+ALL_REGS = [RegisterLocation(i) for i in range(32)]
+
+r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16,\
+ r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31\
+ = ALL_REGS
+
+NONVOLATILES = [r2, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23,
+ r24, r25, r26, r27, r28, r29, r30, r31]
+VOLATILES = [r0, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12]
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,7 +12,8 @@
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 IS_PPC_32, NONVOLATILES
+from pypy.jit.backend.ppc.ppcgen.arch import NONVOLATILES, GPR_SAVE_AREA, WORD
+from pypy.jit.backend.ppc.ppcgen.regalloc import PPCRegisterManager,
PPCFrameManager
import sys
from pypy.tool.ansi_print import ansi_log
@@ -28,48 +29,15 @@
AbstractLLCPU.__init__(self, rtyper, stats, opts,
translate_support_code, gcdescr)
- # pointer to an array of ints
- # XXX length of the integer array is 1000 for now
- self.fail_boxes_int = values_array(lltype.Signed, 1000)
-
# floats are not supported yet
self.supports_floats = False
self.total_compiled_loops = 0
self.total_compiled_bridges = 0
+ self.asm = PPCBuilder(self)
- # compile a given trace
- def compile_loop(self, inputargs, operations, looptoken, log=True):
+ def compile_loop(self, inputargs, operations, looptoken, log=False):
self.saved_descr = {}
- self.patch_list = []
- self.reg_map = {}
- self.fail_box_count = 0
-
- codebuilder = PPCBuilder()
-
- # function prologue
- self._make_prologue(codebuilder)
-
- # initialize registers from memory
- self.next_free_register = 3
- for index, arg in enumerate(inputargs):
- self.reg_map[arg] = self.next_free_register
- addr = self.fail_boxes_int.get_addr_for_num(index)
- codebuilder.load_from(self.next_free_register, addr)
- self.next_free_register += 1
-
- self.startpos = codebuilder.get_relative_pos()
-
- # generate code for operations
- self._walk_trace_ops(codebuilder, operations)
-
- # function epilogue
- self._make_epilogue(codebuilder)
-
- f = codebuilder.assemble()
- looptoken.ppc_code = f
- looptoken.codebuilder = codebuilder
- self.total_compiled_loops += 1
- self.teardown()
+ self.asm.assemble_loop(inputargs, operations, looptoken, log)
def compile_bridge(self, descr, inputargs, operations, looptoken):
self.saved_descr = {}
@@ -110,18 +78,7 @@
self.next_free_register += 1
return reg
- def _make_prologue(self, codebuilder):
- framesize = 16 * WORD + 20 * WORD
- if IS_PPC_32:
- codebuilder.stwu(1, 1, -framesize)
- codebuilder.mflr(0)
- codebuilder.stw(0, 1, framesize + WORD)
- else:
- codebuilder.stdu(1, 1, -framesize)
- codebuilder.mflr(0)
- codebuilder.std(0, 1, framesize + WORD)
- codebuilder.save_nonvolatiles(framesize)
-
+ # XXX not used by now, move to ppc_assembler
def _make_epilogue(self, codebuilder):
for op_index, fail_index, guard, reglist in self.patch_list:
curpos = codebuilder.get_relative_pos()
@@ -147,22 +104,17 @@
descr.patch_pos = patch_pos
descr.used_mem_indices = used_mem_indices
- framesize = 16 * WORD + 20 * WORD
- codebuilder.restore_nonvolatiles(framesize)
+ codebuilder.restore_nonvolatiles(self.framesize)
- if IS_PPC_32:
- codebuilder.lwz(0, 1, framesize + WORD) # 36
- else:
- codebuilder.ld(0, 1, framesize + WORD) # 36
+ codebuilder.lwz(0, 1, self.framesize + 4)
codebuilder.mtlr(0)
- codebuilder.addi(1, 1, framesize)
-
+ codebuilder.addi(1, 1, self.framesize)
codebuilder.li(3, fail_index)
codebuilder.blr()
# set value in fail_boxes_int
def set_future_value_int(self, index, value_int):
- self.fail_boxes_int.setitem(index, value_int)
+ self.asm.fail_boxes_int.setitem(index, value_int)
def set_future_value_ref(self, index, pointer):
sign_ptr = rffi.cast(lltype.Signed, pointer)
@@ -174,8 +126,9 @@
# executes the stored machine code in the token
def execute_token(self, looptoken):
- descr_index = looptoken.ppc_code()
- return self.saved_descr[descr_index]
+ addr = looptoken.ppc_code
+ fail_index = addr()
+ return self.saved_descr[fail_index]
# return the number of values that can be returned
def get_latest_value_count(self):
@@ -183,7 +136,7 @@
# fetch the result of the computation and return it
def get_latest_value_int(self, index):
- value = self.fail_boxes_int.getitem(index)
+ value = self.asm.fail_boxes_int.getitem(index)
return value
def get_latest_value_ref(self, index):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit