Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit