Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r48496:38058e92147d Date: 2011-10-27 10:56 +0200 http://bitbucket.org/pypy/pypy/changeset/38058e92147d/
Log: merge heads diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -1596,11 +1596,24 @@ genop_getarrayitem_gc_pure = genop_getarrayitem_gc genop_getarrayitem_raw = genop_getarrayitem_gc + def _get_interiorfield_index(self, temp_loc, index_loc, itemsize_loc): + assert isinstance(itemsize_loc, ImmedLoc) + if isinstance(index_loc, ImmedLoc): + return imm(index_loc.value * itemsize_loc.value) + else: + # XXX should not use IMUL in most cases + assert isinstance(temp_loc, RegLoc) + assert isinstance(index_loc, RegLoc) + self.mc.IMUL_rri(temp_loc.value, index_loc.value, + itemsize_loc.value) + return temp_loc + def genop_getinteriorfield_gc(self, op, arglocs, resloc): - base_loc, ofs_loc, itemsize_loc, fieldsize_loc, index_loc, sign_loc = arglocs - # XXX should not use IMUL in most cases - self.mc.IMUL(index_loc, itemsize_loc) - src_addr = AddressLoc(base_loc, index_loc, 0, ofs_loc.value) + (base_loc, ofs_loc, itemsize_loc, fieldsize_loc, + index_loc, sign_loc) = arglocs + temp_loc = self._get_interiorfield_index(resloc, index_loc, + itemsize_loc) + src_addr = AddressLoc(base_loc, temp_loc, 0, ofs_loc.value) self.load_from_mem(resloc, src_addr, fieldsize_loc, sign_loc) @@ -1611,13 +1624,11 @@ self.save_into_mem(dest_addr, value_loc, size_loc) def genop_discard_setinteriorfield_gc(self, op, arglocs): - base_loc, ofs_loc, itemsize_loc, fieldsize_loc, index_loc, value_loc = arglocs - # XXX should not use IMUL in most cases - if isinstance(index_loc, ImmedLoc): - index_loc = imm(index_loc.value * itemsize_loc.value) - else: - self.mc.IMUL(index_loc, itemsize_loc) - dest_addr = AddressLoc(base_loc, index_loc, 0, ofs_loc.value) + (base_loc, ofs_loc, itemsize_loc, fieldsize_loc, + index_loc, temp_loc, value_loc) = arglocs + temp_loc = self._get_interiorfield_index(temp_loc, index_loc, + itemsize_loc) + dest_addr = AddressLoc(base_loc, temp_loc, 0, ofs_loc.value) self.save_into_mem(dest_addr, value_loc, fieldsize_loc) def genop_discard_setarrayitem_gc(self, op, arglocs): diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -1046,16 +1046,26 @@ need_lower_byte = True else: need_lower_byte = False - base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args) - tempvar = TempBox() - index_loc = self.rm.force_result_in_reg(tempvar, op.getarg(1), args) - # we're free to modify index now - value_loc = self.make_sure_var_in_reg(op.getarg(2), args + [tempvar], + box_base, box_index, box_value = args + base_loc = self.rm.make_sure_var_in_reg(box_base, args) + index_loc = self.rm.make_sure_var_in_reg(box_index, args) + value_loc = self.make_sure_var_in_reg(box_value, args, need_lower_byte=need_lower_byte) - self.rm.possibly_free_var(tempvar) - self.possibly_free_vars(args) + # If 'index_loc' is not an immediate, then we need a 'temp_loc' that + # is a register whose value will be destroyed. It's fine to destroy + # the same register as 'index_loc', but not the other ones. + self.rm.possibly_free_var(box_index) + if not isinstance(index_loc, ImmedLoc): + tempvar = TempBox() + temp_loc = self.rm.force_allocate_reg(tempvar, [box_base, + box_value]) + self.rm.possibly_free_var(tempvar) + else: + temp_loc = None + self.rm.possibly_free_var(box_base) + self.possibly_free_var(box_value) self.PerformDiscard(op, [base_loc, ofs, itemsize, fieldsize, - index_loc, value_loc]) + index_loc, temp_loc, value_loc]) def consider_strsetitem(self, op): args = op.getarglist() @@ -1126,13 +1136,14 @@ else: sign_loc = imm0 args = op.getarglist() - tmpvar = TempBox() base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args) - index_loc = self.rm.force_result_in_reg(tmpvar, op.getarg(1), - args) - self.rm.possibly_free_vars_for_op(op) - self.rm.possibly_free_var(tmpvar) - result_loc = self.force_allocate_reg(op.result) + index_loc = self.rm.make_sure_var_in_reg(op.getarg(1), args) + # 'base' and 'index' are put in two registers (or one if 'index' + # is an immediate). 'result' can be in the same register as + # 'index' but must be in a different register than 'base'. + self.rm.possibly_free_var(op.getarg(1)) + result_loc = self.force_allocate_reg(op.result, [op.getarg(0)]) + self.rm.possibly_free_var(op.getarg(0)) self.Perform(op, [base_loc, ofs, itemsize, fieldsize, index_loc, sign_loc], result_loc) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit