Author: hager <sven.ha...@uni-duesseldorf.de>
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
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to