Author: hager <sven.ha...@uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r46164:e6405645f87c
Date: 2011-08-01 18:08 +0200
http://bitbucket.org/pypy/pypy/changeset/e6405645f87c/

Log:    Made some refactorings in classes PPC_64_CPU and PPCBuilder.

        - PPCBuilder: Added more methods, don't inherit from
        BlockBuilderMixin any longer
        - PPC_64_CPU: Changed some attributes and methods, added important
        method _make_epilogue to patch generated
        code

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
@@ -464,7 +464,7 @@
     xor = XS(31, XO1=316, Rc=0)
     xorx = XS(31, XO1=316, Rc=1)
 
-class PPCAssembler(BasicPPCAssembler, BlockBuilderMixin):
+class PPCAssembler(BasicPPCAssembler):
     BA = BasicPPCAssembler
 
     # awkward mnemonics:
@@ -806,8 +806,6 @@
 class PPCBuilder(PPCAssembler):
     def __init__(self):
         PPCAssembler.__init__(self)
-        self.init_block_builder()
-        self.patch_list = []
 
     def load_word(self, rD, word):
         self.addis(rD, 0, hi(word))
@@ -830,8 +828,16 @@
         if opnum == rop.INT_ADD:
             self.emit_int_add(trace_op, cpu)
         elif opnum == rop.FINISH:
-            self.emit_finish(cpu)
-    
+            self.emit_finish(trace_op, cpu)
+        elif opnum == rop.INT_LE:
+            self.emit_int_le(trace_op, cpu)
+        elif opnum == rop.JUMP:
+            self.emit_jump(trace_op, cpu)
+        elif opnum == rop.GUARD_TRUE:
+            self.emit_guard_true(trace_op, cpu)
+        else:
+            assert 0, "Don't know this opcode"
+
     # --------------------------------------- #
     #             CODE GENERATION             #
     # --------------------------------------- #
@@ -840,17 +846,71 @@
         arg0 = op.getarg(0)
         arg1 = op.getarg(1)
 
-        arg0_index = cpu.get_box_index(arg0)
-        addr_box_0 = cpu.fail_boxes_int.get_addr_for_num(arg0_index)
+        regnum = cpu.reg_map[arg0]
+
+        self.addi(cpu.next_free_register, regnum, arg1.value)
+
+        result = op.result
+        cpu.reg_map[result] = cpu.next_free_register
+        cpu.next_free_register += 1
+
+    def emit_int_le(self, op, cpu):
+        arg0 = op.getarg(0)
+        arg1 = op.getarg(1)
+
+        regnum = cpu.reg_map[arg0]
         
-        self.load_from(3, addr_box_0)
-        self.addi(3, 3, arg1.value)
-        self.store_reg(3, addr_box_0)
+        free_reg = cpu.next_free_register
+        self.load_word(free_reg, arg1.value)
+        self.cmp(7, 1, regnum, free_reg)
+        self.crnot(30, 29)
+        self.mfcr(free_reg)
+        self.rlwinm(free_reg, free_reg, 31, 31, 31)
 
-    def emit_finish(self, cpu):
+        result = op.result
+        cpu.reg_map[result] = cpu.next_free_register
+        cpu.next_free_register += 1
+
+    def emit_guard_true(self, op, cpu):
+        arg0 = op.getarg(0)
+        regnum = cpu.reg_map[arg0]
+        self.cmpi(0, 1, regnum, 0)              # result of comparison
+        
+        fail_index = len(cpu.saved_descr)
+        cpu.saved_descr[fail_index] = op.getdescr()
+
+        numops = self.get_number_of_ops()
+        self.beq(0)
+
+        failargs = op.getfailargs()
+        reglist = []
+        for failarg in failargs:
+            reglist.append(cpu.reg_map[failarg])
+
+        cpu.patch_list.append((numops, fail_index, op, reglist))
+
+    def emit_finish(self, op, cpu):
+        fail_index = len(cpu.saved_descr)
+        cpu.saved_descr[fail_index] = op.getdescr()
+
+        args = op.getarglist()
+        for index, arg in enumerate(args):
+            regnum = cpu.reg_map[arg]
+            addr = cpu.fail_boxes_int.get_addr_for_num(index)
+            self.store_reg(regnum, addr)
+
         self.load_word(3, 0)
         self.blr()
 
+    def emit_jump(self, op, cpu):
+        for index, arg in enumerate(op.getarglist()):
+            target = index + 3
+            regnum = cpu.reg_map[arg]
+            self.mr(target, regnum)
+
+        offset = self.get_relative_pos()
+        self.b(-offset + cpu.startpos)
+
 class BranchUpdater(PPCAssembler):
     def __init__(self):
         PPCAssembler.__init__(self)
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
@@ -29,26 +29,51 @@
 
         # pointer to an array of ints
         # XXX length of the integer array is 1000 for now
-        self.arg_to_box = {}
         self.fail_boxes_int = values_array(lltype.Signed, 1000)
-        self.saved_descr = {}
 
         # floats are not supported yet
         self.supports_floats = False
 
     # compile a given trace
     def compile_loop(self, inputargs, operations, looptoken, log=True):
+        self.saved_descr = {}
+        self.patch_list = []
+        self.reg_map = {}
+        self.inputargs = inputargs
+        
         codebuilder = PPCBuilder()
-        self.saved_descr[len(self.saved_descr)] = operations[-1].getdescr()
+        
+        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()
 
-        for index, arg in enumerate(inputargs):
-            self.arg_to_box[arg] = index
-            
         self._walk_trace_ops(codebuilder, operations)
+        self._make_epilogue(codebuilder)
 
-        f = codebuilder.assemble()
+        f = codebuilder.assemble(True)
         looptoken.ppc_code = f
 
+    def _make_epilogue(self, codebuilder):
+        for op_index, fail_index, guard, reglist in self.patch_list:
+            curpos = codebuilder.get_relative_pos()
+            offset = curpos - (4 * op_index)
+            assert (1 << 15) > offset
+            codebuilder.beq(offset)
+            codebuilder.patch_op(op_index)
+
+            # store return parameters in memory
+            for index, reg in enumerate(reglist):
+                addr = self.fail_boxes_int.get_addr_for_num(index)
+                codebuilder.store_reg(reg, addr)
+
+            codebuilder.li(3, fail_index)            
+            codebuilder.blr()
+
     def set_future_value_int(self, index, value_int):
         self.fail_boxes_int.setitem(index, value_int)
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to