[pypy-commit] pypy arm-backend-2: implement getinteriorfield_gc and setinteriorfield_gc

bivab noreply at buildbot.pypy.org
Tue Oct 25 11:07:50 CEST 2011


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r48415:6d558e62094e
Date: 2011-10-24 12:37 +0200
http://bitbucket.org/pypy/pypy/changeset/6d558e62094e/

Log:	implement getinteriorfield_gc and setinteriorfield_gc

diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -565,6 +565,64 @@
     emit_op_getfield_raw_pure = emit_op_getfield_gc
     emit_op_getfield_gc_pure = emit_op_getfield_gc
 
+    def emit_op_getinteriorfield_gc(self, op, arglocs, regalloc, fcond):
+        base_loc, index_loc, res_loc, ofs_loc, ofs, itemsize, fieldsize = arglocs
+        self.mc.gen_load_int(r.ip.value, itemsize.value)
+        self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
+        if ofs.value > 0:
+            if ofs_loc.is_imm():
+                self.mc.ADD_ri(r.ip.value, r.ip.value, ofs_loc.value)
+            else:
+                self.mc.ADD_rr(r.ip.value, r.ip.value, ofs_loc.value)
+
+        if fieldsize.value == 8:
+            # vldr only supports imm offsets
+            # so if the ofset is too large we add it to the base and use an
+            # offset of 0
+            assert res_loc.is_vfp_reg()
+            self.mc.ADD_rr(r.ip.value, base_loc.value, r.ip.value)
+            self.mc.VLDR(res_loc.value, r.ip.value, 0)
+        elif fieldsize.value == 4:
+            self.mc.LDR_rr(res_loc.value, base_loc.value, r.ip.value)
+        elif fieldsize.value == 2:
+            self.mc.LDRH_rr(res_loc.value, base_loc.value, r.ip.value)
+        elif fieldsize.value == 1:
+            self.mc.LDRB_rr(res_loc.value, base_loc.value, r.ip.value)
+        else:
+            assert 0
+
+        #XXX Hack, Hack, Hack
+        if not we_are_translated():
+            signed = op.getdescr().fielddescr.is_field_signed()
+            self._ensure_result_bit_extension(res_loc, fieldsize.value, signed)
+        return fcond
+
+    def emit_op_setinteriorfield_gc(self, op, arglocs, regalloc, fcond):
+        base_loc, index_loc, value_loc, ofs_loc, ofs, itemsize, fieldsize = arglocs
+        self.mc.gen_load_int(r.ip.value, itemsize.value)
+        self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
+        if ofs.value > 0:
+            if ofs_loc.is_imm():
+                self.mc.ADD_ri(r.ip.value, r.ip.value, ofs_loc.value)
+            else:
+                self.mc.ADD_rr(r.ip.value, r.ip.value, ofs_loc.value)
+        if fieldsize.value == 8:
+            # vstr only supports imm offsets
+            # so if the ofset is too large we add it to the base and use an
+            # offset of 0
+            assert value_loc.is_vfp_reg()
+            self.mc.ADD_rr(r.ip.value, base_loc.value, r.ip.value)
+            self.mc.VSTR(value_loc.value, r.ip.value, 0)
+        elif fieldsize.value == 4:
+            self.mc.STR_rr(value_loc.value, base_loc.value, r.ip.value)
+        elif fieldsize.value == 2:
+            self.mc.STRH_rr(value_loc.value, base_loc.value, r.ip.value)
+        elif fieldsize.value == 1:
+            self.mc.STRB_rr(value_loc.value, base_loc.value, r.ip.value)
+        else:
+            assert 0
+        return fcond
+
 
 
 
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -17,7 +17,8 @@
                                         INT, REF, FLOAT, LoopToken)
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr, \
-                                             BaseCallDescr, BaseSizeDescr
+                                             BaseCallDescr, BaseSizeDescr, \
+                                             InteriorFieldDescr
 from pypy.jit.backend.llsupport import symbolic
 from pypy.rpython.lltypesystem import lltype, rffi, rstr, llmemory
 from pypy.jit.codewriter import heaptracker
@@ -637,6 +638,46 @@
     prepare_op_getfield_raw_pure = prepare_op_getfield_gc
     prepare_op_getfield_gc_pure = prepare_op_getfield_gc
 
+    def prepare_op_getinteriorfield_gc(self, op, fcond):
+        t = self._unpack_interiorfielddescr(op.getdescr())
+        ofs, itemsize, fieldsize, sign = t
+        args = op.getarglist()
+        base_loc, base_box = self._ensure_value_is_boxed(op.getarg(0), args)
+        index_loc, index_box = self._ensure_value_is_boxed(op.getarg(1), args)
+        c_ofs = ConstInt(ofs)
+        if _check_imm_arg(c_ofs):
+            ofs_loc = imm(ofs)
+        else:
+            ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, [base_box, index_box])
+            self.possibly_free_var(ofs_box)
+        self.possibly_free_vars(args)
+        self.possibly_free_var(base_box)
+        self.possibly_free_var(index_box)
+        result_loc = self.force_allocate_reg(op.result)
+        return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs), 
+                                        imm(itemsize), imm(fieldsize)]
+
+    
+    def prepare_op_setinteriorfield_gc(self, op, fcond):
+        t = self._unpack_interiorfielddescr(op.getdescr())
+        ofs, itemsize, fieldsize, sign = t
+        boxes = [None]*3
+        base_loc, base_box = self._ensure_value_is_boxed(op.getarg(0), boxes)
+        boxes[0] = base_box
+        index_loc, index_box = self._ensure_value_is_boxed(op.getarg(1), boxes)
+        boxes[1] = index_box
+        value_loc, value_box = self._ensure_value_is_boxed(op.getarg(2), boxes)
+        boxes[2] = value_box
+        c_ofs = ConstInt(ofs)
+        if _check_imm_arg(c_ofs):
+            ofs_loc = imm(ofs)
+        else:
+            ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, boxes)
+            self.possibly_free_var(ofs_box)
+        self.possibly_free_vars(boxes)
+        return [base_loc, index_loc, value_loc, ofs_loc, imm(ofs),
+                                        imm(itemsize), imm(fieldsize)]
+
     def prepare_op_arraylen_gc(self, op, fcond):
         arraydescr = op.getdescr()
         assert isinstance(arraydescr, BaseArrayDescr)
@@ -657,7 +698,6 @@
         boxes.append(base_box)
         ofs_loc, ofs_box = self._ensure_value_is_boxed(a1, boxes)
         boxes.append(ofs_box)
-        #XXX check if imm would be fine here
         value_loc, value_box = self._ensure_value_is_boxed(a2, boxes)
         boxes.append(value_box)
         self.possibly_free_vars(boxes)
@@ -1071,6 +1111,16 @@
         assert (1 << scale) == size
         return size, scale, ofs, ofs_length, ptr
 
+    # from ../x86/regalloc.py:965
+    def _unpack_interiorfielddescr(self, descr):
+        assert isinstance(descr, InteriorFieldDescr)
+        arraydescr = descr.arraydescr
+        ofs = arraydescr.get_base_size(self.cpu.translate_support_code)
+        itemsize = arraydescr.get_item_size(self.cpu.translate_support_code)
+        fieldsize = descr.fielddescr.get_field_size(self.cpu.translate_support_code)
+        sign = descr.fielddescr.is_field_signed()
+        ofs += descr.fielddescr.offset
+        return ofs, itemsize, fieldsize, sign
 
     prepare_op_float_add = prepare_float_op(name='float_add')
     prepare_op_float_sub = prepare_float_op(name='float_sub')


More information about the pypy-commit mailing list