def _prepare_call(self, op, save_all_regs=False, first_arg_index=1): args = [None] * (op.numargs() + 3) calldescr = op.getdescr() assert isinstance(calldescr, CallDescr) assert len(calldescr.arg_classes) == op.numargs() - first_arg_index for i in range(op.numargs()): args[i + 3] = self.loc(op.getarg(i)) size = calldescr.get_result_size() sign = calldescr.is_result_signed() if sign: sign_loc = imm(1) else: sign_loc = imm(0) args[1] = imm(size) args[2] = sign_loc effectinfo = calldescr.get_extra_info() if save_all_regs: gc_level = 2 elif effectinfo is None or effectinfo.check_can_collect(): gc_level = 1 else: gc_level = 0 args[0] = self._call(op, args, gc_level) return args
def prepare_op_gc_store_indexed(self, op): 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() return [value_loc, base_loc, index_loc, imm(size), imm(ofs)]
def _prepare_op_gc_load_indexed(self, op): 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() 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)]
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_guard_exception(self, op): boxes = op.getarglist() arg0 = ConstInt(rffi.cast(lltype.Signed, op.getarg(0).getint())) loc = self.make_sure_var_in_reg(arg0) if op in self.longevity: resloc = self.force_allocate_reg(op, boxes) self.possibly_free_var(op) else: resloc = None pos_exc_value = imm(self.cpu.pos_exc_value()) pos_exception = imm(self.cpu.pos_exception()) arglocs = [loc, resloc, pos_exc_value, pos_exception] + self._guard_impl(op) return arglocs
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)]
def _guard_impl(self, op): arglocs = [None] * (len(op.getfailargs()) + 1) arglocs[0] = imm(self.frame_manager.get_frame_depth()) failargs = op.getfailargs() for i in range(len(failargs)): if failargs[i]: arglocs[i + 1] = self.loc(failargs[i]) return arglocs
def emit_guard_op_guard_not_forced(self, op, guard_op, fcond, arglocs): # arglocs is call locs + guard_locs, split them if rop.is_call_assembler(op.getopnum()): if fcond == 4: [argloc, vloc, result_loc, tmploc] = arglocs[:4] else: [argloc, result_loc, tmploc] = arglocs[:3] vloc = locations.imm(0) guard_locs = arglocs[fcond:] self._store_force_index(guard_op) self.call_assembler(op, argloc, vloc, result_loc, tmploc) else: assert fcond == op.numargs() + 3 call_args = arglocs[:fcond] guard_locs = arglocs[fcond:] self._store_force_index(guard_op) self._emit_call(op, call_args) # process the guard_not_forced ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip0.value, r.fp.value, ofs) self.mc.CMP_ri(r.ip0.value, 0) self._emit_guard(guard_op, c.EQ, guard_locs)
def prepare_op_load_effective_address(self, op): args = op.getarglist() arg0 = self.make_sure_var_in_reg(args[0], args) arg1 = self.make_sure_var_in_reg(args[1], args) res = self.force_allocate_reg(op) return [arg0, arg1, imm(args[2].getint()), imm(args[3].getint()), res]
def prepare_op_guard_class(self, op): assert not isinstance(op.getarg(0), Const) x = self.make_sure_var_in_reg(op.getarg(0)) y_val = rffi.cast(lltype.Signed, op.getarg(1).getint()) arglocs = self._guard_impl(op) return [x, imm(y_val)] + arglocs
def prepare_op_int_signext(self, op): argloc = self.make_sure_var_in_reg(op.getarg(0)) numbytes = op.getarg(1).getint() resloc = self.force_allocate_reg(op) return [argloc, imm(numbytes), resloc]
def imm(self, v): return locations.imm(v)