Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: arm64
Changeset: r96029:5cb0444d17a2
Date: 2019-02-16 14:41 +0000
http://bitbucket.org/pypy/pypy/changeset/5cb0444d17a2/

Log:    add CMP_rr and push forward to next test

diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/aarch64/TODO
@@ -0,0 +1,2 @@
+* int_add - IMM
+* int_cmp - IMM
diff --git a/rpython/jit/backend/aarch64/assembler.py 
b/rpython/jit/backend/aarch64/assembler.py
--- a/rpython/jit/backend/aarch64/assembler.py
+++ b/rpython/jit/backend/aarch64/assembler.py
@@ -5,8 +5,8 @@
 #from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size
 from rpython.jit.backend.aarch64.opassembler import ResOpAssembler
 from rpython.jit.backend.aarch64.regalloc import (Regalloc,
+    operations as regalloc_operations, guard_operations, comp_operations)
 #    CoreRegisterManager, check_imm_arg, VFPRegisterManager,
-    operations as regalloc_operations)
 #from rpython.jit.backend.arm import callbuilder
 from rpython.jit.backend.aarch64 import registers as r
 from rpython.jit.backend.llsupport import jitframe
@@ -276,6 +276,12 @@
                 regalloc.possibly_free_vars_for_op(op)
             elif not we_are_translated() and op.getopnum() == rop.FORCE_SPILL:
                 regalloc.prepare_force_spill(op)
+            elif i < len(operations) - 1 and 
regalloc.next_op_can_accept_cc(operations, i):
+                arglocs = guard_operations[operations[i + 1].getopnum()](
+                    regalloc, operations[i + 1], op)
+                if arglocs is not None:
+                    xxx
+                regalloc.next_instruction() # advance one more
             else:
                 arglocs = regalloc_operations[opnum](regalloc, op)
                 if arglocs is not None:
@@ -292,6 +298,13 @@
         self.mc.mark_op(None)  # end of the loop
         regalloc.operations = None
 
+    def dispatch_comparison(self, op):
+        opnum = op.getopnum()
+        arglocs = comp_operations[opnum](self._regalloc, op, True)
+        assert arglocs is not None
+        asm_comp_operations[opnum](self, op, arglocs)
+        return arglocs
+
     # regalloc support
     def load(self, loc, value):
         """load an immediate value into a register"""
@@ -415,12 +428,16 @@
     raise NotImplementedError(msg)
 
 
-def notimplemented_op(self, op, arglocs, regalloc):
+def notimplemented_op(self, op, arglocs):
     print "[ARM/asm] %s not implemented" % op.getopname()
     raise NotImplementedError(op)
 
+def notimplemented_comp_op(self, op, arglocs):
+    print "[ARM/asm] %s not implemented" % op.getopname()
+    raise NotImplementedError(op)
 
 asm_operations = [notimplemented_op] * (rop._LAST + 1)
+asm_comp_operations = [notimplemented_comp_op] * (rop._LAST + 1)
 asm_extra_operations = {}
 
 for name, value in ResOpAssembler.__dict__.iteritems():
@@ -432,3 +449,7 @@
         opname = name[len('emit_op_'):]
         num = getattr(rop, opname.upper())
         asm_operations[num] = value
+    elif name.startswith('emit_comp_op_'):
+        opname = name[len('emit_comp_op_'):]
+        num = getattr(rop, opname.upper())
+        asm_comp_operations[num] = value
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
@@ -104,6 +104,10 @@
         base = 0b10001011000
         self.write32((base << 21) | (rm << 16) | (rn << 5) | (rd))
 
+    def CMP_rr(self, rn, rm):
+        base = 0b11101011000
+        self.write32((base << 21) | (rm << 16) | (rn << 5) | 0b11111)
+
     def BRK(self):
         self.write32(0b11010100001 << 21)
 
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
@@ -2,6 +2,7 @@
 from rpython.jit.metainterp.history import (AbstractFailDescr, ConstInt,
                                             INT, FLOAT, REF)
 from rpython.jit.backend.aarch64 import registers as r
+from rpython.jit.backend.arm import conditions as c # yes, arm, not aarch64
 from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler
 
 class ResOpAssembler(BaseAssembler):
@@ -24,6 +25,17 @@
         else:
             self.mc.ADD_rr(res.value, l0.value, l1.value)
 
+    def emit_int_comp_op(self, op, arglocs):
+        l0, l1 = arglocs
+
+        if l1.is_imm():
+            xxx
+            self.mc.CMP_ri(l0.value, imm=l1.getint(), cond=fcond)
+        else:
+            self.mc.CMP_rr(l0.value, l1.value)
+
+    emit_comp_op_int_le = emit_int_comp_op
+
     def emit_op_increment_debug_counter(self, op, arglocs):
         return # XXXX
         base_loc, value_loc = arglocs
@@ -31,6 +43,9 @@
         self.mc.ADD_ri(value_loc.value, value_loc.value, 1)
         self.mc.STR_ri(value_loc.value, base_loc.value, 0)
 
+    def emit_op_label(self, op, arglocs):
+        pass
+
     def emit_op_finish(self, op, arglocs):
         base_ofs = self.cpu.get_baseofs_of_frame_field()
         if len(arglocs) > 0:
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
@@ -177,6 +177,12 @@
         self.possibly_free_vars(list(inputargs))
         return operations
 
+    def loc(self, var):
+        if var.type == FLOAT:
+            return self.vfprm.loc(var)
+        else:
+            return self.rm.loc(var)
+
     def possibly_free_var(self, var):
         if var.type == FLOAT:
             self.vfprm.possibly_free_var(var)
@@ -245,7 +251,7 @@
         #   we would like the boxes to be after the jump.
 
     def _compute_hint_frame_locations_from_descr(self, descr):
-        arglocs = self.assembler.target_arglocs(descr)
+        arglocs = descr._arm_arglocs
         jump_op = self.final_jump_op
         assert len(arglocs) == jump_op.numargs()
         for i in range(jump_op.numargs()):
@@ -271,23 +277,6 @@
         self.free_temp_vars()
         return [base_loc, value_loc]
 
-    def _prepare_op_int_add(self, op, fcond):
-        XXX
-        boxes = op.getarglist()
-        a0, a1 = boxes
-        imm_a0 = check_imm_box(a0)
-        imm_a1 = check_imm_box(a1)
-        if not imm_a0 and imm_a1:
-            l0 = self.make_sure_var_in_reg(a0, boxes)
-            l1 = self.convert_to_imm(a1)
-        elif imm_a0 and not imm_a1:
-            l0 = self.convert_to_imm(a0)
-            l1 = self.make_sure_var_in_reg(a1, boxes)
-        else:
-            l0 = self.make_sure_var_in_reg(a0, boxes)
-            l1 = self.make_sure_var_in_reg(a1, boxes)
-        return [l0, l1]
-
     def prepare_op_int_add(self, op):
         arg0 = op.getarg(0)
         arg1 = op.getarg(1)
@@ -298,6 +287,71 @@
         res = self.force_allocate_reg(op)
         return [l0, l1, res]
 
+
+    def prepare_int_cmp(self, op, res_in_cc):
+        boxes = op.getarglist()
+        arg0, arg1 = boxes
+        imm_a1 = False # XXX check_imm_box(arg1)
+
+        l0 = self.make_sure_var_in_reg(arg0, forbidden_vars=boxes)
+        if imm_a1:
+            l1 = self.convert_to_imm(arg1)
+        else:
+            l1 = self.make_sure_var_in_reg(arg1, forbidden_vars=boxes)
+
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
+        if not res_in_cc:
+            res = self.force_allocate_reg_or_cc(op)
+            return [l0, l1, res]
+        return [l0, l1]
+
+    prepare_comp_op_int_lt = prepare_int_cmp
+    prepare_comp_op_int_le = prepare_int_cmp
+
+    def prepare_op_int_le(self, op):
+        return self.prepare_int_cmp(op, False)
+
+    def prepare_op_label(self, op):
+        descr = op.getdescr()
+        assert isinstance(descr, TargetToken)
+        inputargs = op.getarglist()
+        arglocs = [None] * len(inputargs)
+        #
+        # we use force_spill() on the boxes that are not going to be really
+        # used any more in the loop, but that are kept alive anyway
+        # by being in a next LABEL's or a JUMP's argument or fail_args
+        # of some guard
+        position = self.rm.position
+        for arg in inputargs:
+            assert not isinstance(arg, Const)
+            if self.last_real_usage.get(arg, -1) <= position:
+                self.force_spill_var(arg)
+
+        #
+        for i in range(len(inputargs)):
+            arg = inputargs[i]
+            assert not isinstance(arg, Const)
+            loc = self.loc(arg)
+            arglocs[i] = loc
+            if loc.is_core_reg() or loc.is_vfp_reg():
+                self.frame_manager.mark_as_free(arg)
+        #
+        descr._arm_arglocs = arglocs
+        descr._ll_loop_code = self.assembler.mc.currpos()
+        descr._arm_clt = self.assembler.current_clt
+        self.assembler.target_tokens_currently_compiling[descr] = None
+        self.possibly_free_vars_for_op(op)
+        #
+        # if the LABEL's descr is precisely the target of the JUMP at the
+        # end of the same loop, i.e. if what we are compiling is a single
+        # loop that ends up jumping to this LABEL, then we can now provide
+        # the hints about the expected position of the spilled variables.
+        jump_op = self.final_jump_op
+        if jump_op is not None and jump_op.getdescr() is descr:
+            self._compute_hint_frame_locations_from_descr(descr)
+        return []
+
     def prepare_op_finish(self, op):
         # the frame is in fp, but we have to point where in the frame is
         # the potential argument to FINISH
@@ -308,6 +362,10 @@
             locs = []
         return locs
 
+    def prepare_guard_op_guard_true(self, op, prevop):
+        arglocs = self.assembler.dispatch_comparison(prevop)
+        xxx
+
     prepare_op_nursery_ptr_increment = prepare_op_int_add
 
     def force_allocate_reg(self, var, forbidden_vars=[], selected_reg=None):
@@ -330,8 +388,17 @@
     print "[ARM64/regalloc] %s not implemented" % op.getopname()
     raise NotImplementedError(op)
 
+def notimplemented_guard_op(self, op, prevop):
+    print "[ARM64/regalloc] %s not implemented" % op.getopname()
+    raise NotImplementedError(op)    
+
+def notimplemented_comp_op(self, op, res_in_cc):
+    print "[ARM64/regalloc] %s not implemented" % op.getopname()
+    raise NotImplementedError(op)    
 
 operations = [notimplemented] * (rop._LAST + 1)
+guard_operations = [notimplemented_guard_op] * (rop._LAST + 1)
+comp_operations = [notimplemented_comp_op] * (rop._LAST + 1)
 
 
 for key, value in rop.__dict__.items():
@@ -342,3 +409,12 @@
     if hasattr(Regalloc, methname):
         func = getattr(Regalloc, methname).im_func
         operations[value] = func
+    methname = 'prepare_guard_op_%s' % key
+    if hasattr(Regalloc, methname):
+        func = getattr(Regalloc, methname).im_func
+        guard_operations[value] = func
+    methname = 'prepare_comp_op_%s' % key
+    if hasattr(Regalloc, methname):
+        func = getattr(Regalloc, methname).im_func
+        comp_operations[value] = func
+    
\ No newline at end of file
diff --git a/rpython/jit/backend/aarch64/test/test_instr_builder.py 
b/rpython/jit/backend/aarch64/test/test_instr_builder.py
--- a/rpython/jit/backend/aarch64/test/test_instr_builder.py
+++ b/rpython/jit/backend/aarch64/test/test_instr_builder.py
@@ -124,6 +124,14 @@
         cb.ADD_rr(rd.value, rn.value, rm.value)
         assert cb.hexdump() == assemble("ADD %r, %r, %r" % (rd, rn, rm))
 
+    @settings(max_examples=20)
+    @given(rn=st.sampled_from(r.registers),
+           rm=st.sampled_from(r.registers))
+    def test_CMP_rr(self, rn, rm):
+        cb = CodeBuilder()
+        cb.CMP_rr(rn.value, rm.value)
+        assert cb.hexdump() == assemble("CMP %r, %r" % (rn, rm))
+
     def test_BRK(self):
         cb = CodeBuilder()
         cb.BRK()
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to