Author: Maciej Fijalkowski <[email protected]>
Branch: arm64
Changeset: r96535:682a0e1492d9
Date: 2019-04-22 11:32 +0000
http://bitbucket.org/pypy/pypy/changeset/682a0e1492d9/

Log:    enough to start passing basic field tests

diff --git a/rpython/jit/backend/aarch64/codebuilder.py 
b/rpython/jit/backend/aarch64/codebuilder.py
--- a/rpython/jit/backend/aarch64/codebuilder.py
+++ b/rpython/jit/backend/aarch64/codebuilder.py
@@ -10,7 +10,6 @@
 PC_OFFSET = 0 # XXX
 
 class AbstractAarch64Builder(object):
-    # just copied some values from 
https://gist.github.com/dinfuehr/51a01ac58c0b23e4de9aac313ed6a06a
     def write32(self, word):
         self.writechar(chr(word & 0xFF))
         self.writechar(chr((word >> 8) & 0xFF))
@@ -41,6 +40,18 @@
         self.write32((base << 22) | ((0x7F & (offset >> 3)) << 15) |
                      (reg2 << 10) | (rn << 5) | reg1)
 
+    def STR_size_rr(self, scale, rt, rn, rm):
+        base = 0b111000001
+        assert 0 <= scale <= 3
+        self.wirte32((scale << 30) | (base << 21) | (rm << 16) | (0b11 << 13) |
+                     (0b010 << 10) | (rn << 5) | rt)
+
+    def STR_size_ri(self, scale, rt, rn, imm):
+        assert 0 <= imm < 4096
+        assert 0 <= scale <= 3
+        base = 0b11100100
+        self.write32((scale << 30) | (base << 22) | (imm >> scale << 10) | (rn 
<< 5) | rt)
+
     def MOV_rr(self, rd, rn):
         self.ORR_rr(rd, r.xzr.value, rn)
 
@@ -100,6 +111,18 @@
         assert 0 <= immed <= 1<<15
         assert immed & 0x7 == 0
         self.write32((base << 22) | (immed >> 3 << 10) | (rn << 5) | rt)
+
+    def LDR_rr(self, rt, rn, rm):
+        xxx
+
+    def LDR_size_ri(self, size, rt, rn, ofs):
+        assert 0 <= size <= 3
+        assert 0 <= ofs <= 4096
+        base = 0b11100101
+        self.write32((size << 30) | (base << 22) | (ofs >> size << 10) | (rn 
<< 5) | rt)
+
+    def LDR_size_rr(self, size, rt, rn, rm):
+        xxx
     
     def LDR_r_literal(self, rt, offset):
         base = 0b01011000
@@ -236,9 +259,9 @@
         # XXX use the IMM version if close enough
         target = rffi.cast(lltype.Signed, target)
         self.gen_load_int_full(r.ip0.value, target)
-        self.BLR(r.ip0.value)
+        self.BLR_r(r.ip0.value)
 
-    def BLR(self, reg):
+    def BLR_r(self, reg):
         base = 0b1101011000111111000000
         self.write32((base << 10) | (reg << 5))
 
diff --git a/rpython/jit/backend/aarch64/opassembler.py 
b/rpython/jit/backend/aarch64/opassembler.py
--- a/rpython/jit/backend/aarch64/opassembler.py
+++ b/rpython/jit/backend/aarch64/opassembler.py
@@ -5,8 +5,10 @@
 from rpython.jit.backend.aarch64.callbuilder import Aarch64CallBuilder
 from rpython.jit.backend.arm import conditions as c
 from rpython.jit.backend.aarch64.arch import JITFRAME_FIXED_SIZE
+from rpython.jit.backend.aarch64.locations import imm
 from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
+from rpython.jit.backend.llsupport.regalloc import get_scale
 from rpython.jit.metainterp.history import TargetToken
 
 def gen_comp_op(name, flag):
@@ -152,6 +154,69 @@
         self.mc.ADD_ri(value_loc.value, value_loc.value, 1)
         self.mc.STR_ri(value_loc.value, base_loc.value, 0)
 
+    # -------------------------------- fields -------------------------------
+
+    def emit_op_gc_store(self, op, arglocs):
+        value_loc, base_loc, ofs_loc, size_loc = arglocs
+        scale = get_scale(size_loc.value)
+        self._write_to_mem(value_loc, base_loc, ofs_loc, imm(scale))
+
+    def _emit_op_gc_load(self, op, arglocs):
+        base_loc, ofs_loc, res_loc, nsize_loc = arglocs
+        nsize = nsize_loc.value
+        signed = (nsize < 0)
+        scale = get_scale(abs(nsize))
+        self._load_from_mem(res_loc, base_loc, ofs_loc, imm(scale), signed)
+
+    emit_op_gc_load_i = _emit_op_gc_load
+    emit_op_gc_load_r = _emit_op_gc_load
+    emit_op_gc_load_f = _emit_op_gc_load
+
+    def _write_to_mem(self, value_loc, base_loc, ofs_loc, scale):
+        # Write a value of size '1 << scale' at the address
+        # 'base_ofs + ofs_loc'.  Note that 'scale' is not used to scale
+        # the offset!
+        assert base_loc.is_core_reg()
+        if scale.value == 3:
+            # WORD size
+            if ofs_loc.is_imm():
+                self.mc.STR_ri(value_loc.value, base_loc.value,
+                                ofs_loc.value)
+            else:
+                self.mc.STR_rr(value_loc.value, base_loc.value,
+                                ofs_loc.value)
+        else:
+            if ofs_loc.is_imm():
+                self.mc.STR_size_ri(scale.value, value_loc.value, 
base_loc.value,
+                                     ofs_loc.value)
+            else:
+                self.mc.STR_size_rr(scale.value, value_loc.value, 
base_loc.value,
+                                     ofs_loc.value)
+
+    def _load_from_mem(self, res_loc, base_loc, ofs_loc, scale,
+                                            signed=False):
+        # Load a value of '1 << scale' bytes, from the memory location
+        # 'base_loc + ofs_loc'.  Note that 'scale' is not used to scale
+        # the offset!
+        #
+        if scale.value == 3:
+            # WORD
+            if ofs_loc.is_imm():
+                self.mc.LDR_ri(res_loc.value, base_loc.value,
+                                ofs_loc.value)
+            else:
+                self.mc.LDR_rr(res_loc.value, base_loc.value,
+                                ofs_loc.value)
+        else:
+            if ofs_loc.is_imm():
+                self.mc.LDR_size_ri(scale.value, res_loc.value, base_loc.value,
+                                    ofs_loc.value)
+            else:
+                self.mc.LDR_size_rr(scale.value, res_loc.value, base_loc.value,
+                                    ofs_loc.value)
+
+    # -------------------------------- guard --------------------------------
+
     def build_guard_token(self, op, frame_depth, arglocs, offset, fcond):
         descr = op.getdescr()
         assert isinstance(descr, AbstractFailDescr)
@@ -191,6 +256,8 @@
         self._emit_guard(guard_op, c.get_opposite_of(fcond), arglocs)
     emit_guard_op_guard_overflow = emit_guard_op_guard_false
 
+    # ----------------------------- call ------------------------------
+
     def _genop_call(self, op, arglocs):
         return self._emit_call(op, arglocs)
     emit_op_call_i = _genop_call
@@ -272,11 +339,11 @@
                 gcmap = self._finish_gcmap
             else:
                 gcmap = self.gcmap_for_finish
-            self.push_gcmap(self.mc, gcmap, store=True)
+            self.push_gcmap(self.mc, gcmap)
         elif self._finish_gcmap:
             # we're returning with a guard_not_forced_2
             gcmap = self._finish_gcmap
-            self.push_gcmap(self.mc, gcmap, store=True)
+            self.push_gcmap(self.mc, gcmap)
         else:
             # note that the 0 here is redundant, but I would rather
             # keep that one and kill all the others
diff --git a/rpython/jit/backend/aarch64/regalloc.py 
b/rpython/jit/backend/aarch64/regalloc.py
--- a/rpython/jit/backend/aarch64/regalloc.py
+++ b/rpython/jit/backend/aarch64/regalloc.py
@@ -410,6 +410,42 @@
     prepare_op_int_neg = prepare_unary
     prepare_op_int_invert = prepare_unary
 
+    # --------------------------------- fields --------------------------
+
+    def prepare_op_gc_store(self, op):
+        boxes = op.getarglist()
+        base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
+        ofs = boxes[1].getint()
+        value_loc = self.make_sure_var_in_reg(boxes[2], boxes)
+        size = boxes[3].getint()
+        if check_imm_arg(ofs):
+            ofs_loc = imm(ofs)
+        else:
+            ofs_loc = r.ip1
+            self.assembler.load(ofs_loc, imm(ofs))
+        return [value_loc, base_loc, ofs_loc, imm(size)]
+
+    def _prepare_op_gc_load(self, op):
+        a0 = op.getarg(0)
+        ofs = op.getarg(1).getint()
+        nsize = op.getarg(2).getint()    # negative for "signed"
+        base_loc = self.make_sure_var_in_reg(a0)
+        immofs = imm(ofs)
+        if check_imm_arg(ofs):
+            ofs_loc = immofs
+        else:
+            ofs_loc = r.ip1
+            self.assembler.load(ofs_loc, immofs)
+        self.possibly_free_vars_for_op(op)
+        res_loc = self.force_allocate_reg(op)
+        return [base_loc, ofs_loc, res_loc, imm(nsize)]
+
+    prepare_op_gc_load_i = _prepare_op_gc_load
+    prepare_op_gc_load_r = _prepare_op_gc_load
+    prepare_op_gc_load_f = _prepare_op_gc_load
+
+    # --------------------------------- call ----------------------------
+
     def _prepare_op_call(self, op):
         calldescr = op.getdescr()
         assert calldescr is not None
diff --git a/rpython/jit/backend/test/runner_test.py 
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -709,6 +709,7 @@
         shortdescr = self.cpu.fielddescrof(self.S, 'short')
         self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(250)],
                                'void', descr=fielddescr2)
+
         self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(133)],
                                'void', descr=fielddescr1)
         self.execute_operation(rop.SETFIELD_GC, [t_box, InputArgInt(1331)],
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to