Ejemplo n.º 1
0
 def _gen_address(self, result, base_loc, scaled_loc, scale=0, static_offset=0):
     assert scaled_loc.is_core_reg()
     assert base_loc.is_core_reg()
     assert check_imm_arg(scale)
     assert check_imm_arg(static_offset)
     if scale > 0:
         self.mc.LSL_ri(r.ip.value, scaled_loc.value, scale)
         scaled_loc = r.ip
     else:
         scaled_loc = scaled_loc
     self.mc.ADD_rr(result.value, base_loc.value, scaled_loc.value)
     self.mc.ADD_ri(result.value, result.value, static_offset)
Ejemplo n.º 2
0
 def _adjust_sp(self, n):
     # adjust the current stack pointer by n bytes
     if n > 0:
         if check_imm_arg(n):
             self.mc.ADD_ri(r.sp.value, r.sp.value, n)
         else:
             self.mc.gen_load_int(r.ip.value, n)
             self.mc.ADD_rr(r.sp.value, r.sp.value, r.ip.value)
     elif n < 0:
         n = abs(n)
         if check_imm_arg(n):
             self.mc.SUB_ri(r.sp.value, r.sp.value, n)
         else:
             self.mc.gen_load_int(r.ip.value, n)
             self.mc.SUB_rr(r.sp.value, r.sp.value, r.ip.value)
Ejemplo n.º 3
0
 def _adjust_sp(self, n):
     # adjust the current stack pointer by n bytes
     if n > 0:
         if check_imm_arg(n):
             self.mc.ADD_ri(r.sp.value, r.sp.value, n)
         else:
             self.mc.gen_load_int(r.ip.value, n)
             self.mc.ADD_rr(r.sp.value, r.sp.value, r.ip.value)
     elif n < 0:
         n = abs(n)
         if check_imm_arg(n):
             self.mc.SUB_ri(r.sp.value, r.sp.value, n)
         else:
             self.mc.gen_load_int(r.ip.value, n)
             self.mc.SUB_rr(r.sp.value, r.sp.value, r.ip.value)
Ejemplo n.º 4
0
 def _call_assembler_load_result(self, op, result_loc):
     if op.result is not None:
         # load the return value from (tmploc, 0)
         kind = op.result.type
         descr = self.cpu.getarraydescr_for_frame(kind)
         if kind == FLOAT:
             ofs = self.cpu.unpack_arraydescr(descr)
             assert check_imm_arg(ofs)
             assert result_loc.is_vfp_reg()
             # we always have a register here, since we have to sync them
             # before call_assembler
             self.load_reg(self.mc, result_loc, r.r0, ofs=ofs)
         else:
             assert result_loc is r.r0
             ofs = self.cpu.unpack_arraydescr(descr)
             assert check_imm_arg(ofs)
             self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs)
Ejemplo n.º 5
0
 def prepare_op_gc_store_indexed(self, op, fcond):
     boxes = op.getarglist()
     base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
     value_loc = self.make_sure_var_in_reg(boxes[2], boxes)
     index_loc = self.make_sure_var_in_reg(boxes[1], boxes)
     assert boxes[3].getint() == 1  # scale
     ofs = boxes[4].getint()
     size = boxes[5].getint()
     assert check_imm_arg(ofs)
     return [value_loc, base_loc, index_loc, imm(size), imm(ofs)]
Ejemplo n.º 6
0
 def prepare_op_gc_store_indexed(self, op, fcond):
     boxes = op.getarglist()
     base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
     value_loc = self.make_sure_var_in_reg(boxes[2], boxes)
     index_loc = self.make_sure_var_in_reg(boxes[1], boxes)
     assert boxes[3].getint() == 1    # scale
     ofs = boxes[4].getint()
     size = boxes[5].getint()
     assert check_imm_arg(ofs)
     return [value_loc, base_loc, index_loc, imm(size), imm(ofs)]
Ejemplo n.º 7
0
 def _call_assembler_check_descr(self, value, tmploc):
     ofs = self.cpu.get_ofs_of_frame_field("jf_descr")
     self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs)
     if check_imm_arg(value):
         self.mc.CMP_ri(r.ip.value, imm=value)
     else:
         self.mc.gen_load_int(r.lr.value, value)
         self.mc.CMP_rr(r.ip.value, r.lr.value)
     pos = self.mc.currpos()
     self.mc.BKPT()
     return pos
Ejemplo n.º 8
0
 def _prepare_op_gc_load_indexed(self, op, fcond):
     boxes = op.getarglist()
     base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
     index_loc = self.make_sure_var_in_reg(boxes[1], boxes)
     assert boxes[2].getint() == 1  # scale
     ofs = boxes[3].getint()
     nsize = boxes[4].getint()
     assert check_imm_arg(ofs)
     self.possibly_free_vars_for_op(op)
     self.free_temp_vars()
     res_loc = self.force_allocate_reg(op)
     return [res_loc, base_loc, index_loc, imm(nsize), imm(ofs)]
Ejemplo n.º 9
0
 def _prepare_op_gc_load_indexed(self, op, fcond):
     boxes = op.getarglist()
     base_loc = self.make_sure_var_in_reg(boxes[0], boxes)
     index_loc = self.make_sure_var_in_reg(boxes[1], boxes)
     assert boxes[2].getint() == 1    # scale
     ofs = boxes[3].getint()
     nsize = boxes[4].getint()
     assert check_imm_arg(ofs)
     self.possibly_free_vars_for_op(op)
     self.free_temp_vars()
     res_loc = self.force_allocate_reg(op)
     return [res_loc, base_loc, index_loc, imm(nsize), imm(ofs)]
Ejemplo n.º 10
0
 def prepare_op_gc_store(self, op, fcond):
     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()
     ofs_size = default_imm_size if size < 8 else VMEM_imm_size
     if check_imm_arg(ofs, size=ofs_size):
         ofs_loc = imm(ofs)
     else:
         ofs_loc = self.get_scratch_reg(INT, boxes)
         self.assembler.load(ofs_loc, imm(ofs))
     return [value_loc, base_loc, ofs_loc, imm(size)]
Ejemplo n.º 11
0
 def prepare_op_gc_store(self, op, fcond):
     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()
     ofs_size = default_imm_size if size < 8 else VMEM_imm_size
     if check_imm_arg(ofs, size=ofs_size):
         ofs_loc = imm(ofs)
     else:
         ofs_loc = self.get_scratch_reg(INT, boxes)
         self.assembler.load(ofs_loc, imm(ofs))
     return [value_loc, base_loc, ofs_loc, imm(size)]
Ejemplo n.º 12
0
 def _prepare_op_gc_load(self, op, fcond):
     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)
     ofs_size = default_imm_size if abs(nsize) < 8 else VMEM_imm_size
     if check_imm_arg(ofs, size=ofs_size):
         ofs_loc = immofs
     else:
         ofs_loc = self.get_scratch_reg(INT, [a0])
         self.assembler.load(ofs_loc, immofs)
     self.possibly_free_vars_for_op(op)
     self.free_temp_vars()
     res_loc = self.force_allocate_reg(op)
     return [base_loc, ofs_loc, res_loc, imm(nsize)]
Ejemplo n.º 13
0
 def _prepare_op_gc_load(self, op, fcond):
     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)
     ofs_size = default_imm_size if abs(nsize) < 8 else VMEM_imm_size
     if check_imm_arg(ofs, size=ofs_size):
         ofs_loc = immofs
     else:
         ofs_loc = self.get_scratch_reg(INT, [a0])
         self.assembler.load(ofs_loc, immofs)
     self.possibly_free_vars_for_op(op)
     self.free_temp_vars()
     res_loc = self.force_allocate_reg(op)
     return [base_loc, ofs_loc, res_loc, imm(nsize)]
Ejemplo n.º 14
0
    def emit_op_zero_array(self, op, arglocs, regalloc, fcond):
        from rpython.jit.backend.llsupport.descr import unpack_arraydescr

        assert len(arglocs) == 0
        size_box = op.getarg(2)
        if isinstance(size_box, ConstInt) and size_box.getint() == 0:
            return fcond  # nothing to do
        itemsize, baseofs, _ = unpack_arraydescr(op.getdescr())
        args = op.getarglist()
        #
        # ZERO_ARRAY(base_loc, start, size, 1, 1)
        # 'start' and 'size' are both expressed in bytes,
        # and the two scaling arguments should always be ConstInt(1) on ARM.
        assert args[3].getint() == 1
        assert args[4].getint() == 1
        #
        base_loc = regalloc.rm.make_sure_var_in_reg(args[0], args)
        startbyte_box = args[1]
        if isinstance(startbyte_box, ConstInt):
            startbyte_loc = None
            startbyte = startbyte_box.getint()
            assert startbyte >= 0
        else:
            startbyte_loc = regalloc.rm.make_sure_var_in_reg(startbyte_box, args)
            startbyte = -1

        # base_loc and startbyte_loc are in two regs here (or startbyte_loc
        # is an immediate).  Compute the dstaddr_loc, which is the raw
        # address that we will pass as first argument to memset().
        # It can be in the same register as either one, but not in
        # args[2], because we're still needing the latter.
        dstaddr_box = TempVar()
        dstaddr_loc = regalloc.rm.force_allocate_reg(dstaddr_box, [args[2]])
        if startbyte >= 0:  # a constant
            ofs = baseofs + startbyte
            reg = base_loc.value
        else:
            self.mc.ADD_rr(dstaddr_loc.value, base_loc.value, startbyte_loc.value)
            ofs = baseofs
            reg = dstaddr_loc.value
        if check_imm_arg(ofs):
            self.mc.ADD_ri(dstaddr_loc.value, reg, imm=ofs)
        else:
            self.mc.gen_load_int(r.ip.value, ofs)
            self.mc.ADD_rr(dstaddr_loc.value, reg, r.ip.value)

        # We use STRB, STRH or STR based on whether we know the array
        # item size is a multiple of 1, 2 or 4.
        if itemsize & 1:
            itemsize = 1
        elif itemsize & 2:
            itemsize = 2
        else:
            itemsize = 4
        limit = itemsize
        next_group = -1
        if itemsize < 4 and startbyte >= 0:
            # we optimize STRB/STRH into STR, but this needs care:
            # it only works if startindex_loc is a constant, otherwise
            # we'd be doing unaligned accesses.
            next_group = (-startbyte) & 3
            limit = 4

        if isinstance(size_box, ConstInt) and size_box.getint() <= 14 * limit:  # same limit as GCC
            # Inline a series of STR operations, starting at 'dstaddr_loc'.
            #
            self.mc.gen_load_int(r.ip.value, 0)
            i = 0
            total_size = size_box.getint()
            while i < total_size:
                sz = itemsize
                if i == next_group:
                    next_group += 4
                    if next_group <= total_size:
                        sz = 4
                if sz == 4:
                    self.mc.STR_ri(r.ip.value, dstaddr_loc.value, imm=i)
                elif sz == 2:
                    self.mc.STRH_ri(r.ip.value, dstaddr_loc.value, imm=i)
                else:
                    self.mc.STRB_ri(r.ip.value, dstaddr_loc.value, imm=i)
                i += sz

        else:
            if isinstance(size_box, ConstInt):
                size_loc = imm(size_box.getint())
            else:
                # load size_loc in a register different than dstaddr_loc
                size_loc = regalloc.rm.make_sure_var_in_reg(size_box, [dstaddr_box])
            #
            # call memset()
            regalloc.before_call()
            self.simple_call_no_collect(imm(self.memset_addr), [dstaddr_loc, imm(0), size_loc])
            regalloc.rm.possibly_free_var(size_box)
        regalloc.rm.possibly_free_var(dstaddr_box)
        return fcond