Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r70202:913db8f92462
Date: 2014-03-23 16:09 +0100
http://bitbucket.org/pypy/pypy/changeset/913db8f92462/
Log: fixes fixes fixes fixes
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -59,6 +59,18 @@
self.stack_check_slowpath = 0
self.propagate_exception_path = 0
self.teardown()
+ #
+ self.SEGMENT_NO = rx86.SEGMENT_NO
+ if translate_support_code and cpu.gc_ll_descr.stm:
+ assert IS_X86_64
+ self.SEGMENT_GC = rx86.SEGMENT_GS
+ self.SEGMENT_TL = rx86.SEGMENT_FS
+ self.SEGMENT_FRAME = rx86.SEGMENT_GS
+ # ^^^ same as SEGMENT_GC, but use it for accessing %ebp
+ else:
+ self.SEGMENT_GC = rx86.SEGMENT_NO
+ self.SEGMENT_TL = rx86.SEGMENT_NO
+ self.SEGMENT_FRAME = rx86.SEGMENT_NO
def setup_once(self):
BaseAssembler.setup_once(self)
@@ -73,7 +85,7 @@
if WORD == 8:
self.pending_memoryerror_trampoline_from = []
self.error_trampoline_64 = 0
- self.mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ self.mc = codebuf.MachineCodeBlockWrapper()
#assert self.datablockwrapper is None --- but obscure case
# possible, e.g. getting MemoryError and continuing
allblocks = self.get_asmmemmgr_blocks(looptoken)
@@ -109,15 +121,15 @@
def set_extra_stack_depth(self, mc, value):
if self._is_asmgcc():
extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth')
- mc.MOV_bi(extra_ofs, value)
+ mc.MOV_bi((self.SEGMENT_FRAME, extra_ofs), value)
def build_frame_realloc_slowpath(self):
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
self._push_all_regs_to_frame(mc, [], self.cpu.supports_floats)
# this is the gcmap stored by push_gcmap(mov=True) in
_check_stack_frame
mc.MOV_rs(ecx.value, WORD)
gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- mc.MOV_br(gcmap_ofs, ecx.value)
+ mc.MOV_br((self.SEGMENT_FRAME, gcmap_ofs), ecx.value)
if IS_X86_64:
mc.MOV_rs(esi.value, WORD*2)
@@ -147,7 +159,7 @@
self._load_shadowstack_top_in_ebx(mc, gcrootmap)
mc.MOV_mr((ebx.value, -WORD), eax.value)
- mc.MOV_bi(gcmap_ofs, 0)
+ mc.MOV_bi((self.SEGMENT_FRAME, gcmap_ofs), 0)
self._pop_all_regs_from_frame(mc, [], self.cpu.supports_floats)
mc.RET()
self._frame_realloc_slowpath = mc.materialize(self.cpu.asmmemmgr, [])
@@ -156,7 +168,7 @@
""" This builds a general call slowpath, for whatever call happens to
come.
"""
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
# copy registers to the frame, with the exception of the
# 'cond_call_register_arguments' and eax, because these have already
# been saved by the caller. Note that this is not symmetrical:
@@ -196,11 +208,11 @@
This function does not have to preserve registers. It expects
all registers to be saved in the caller.
"""
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
# store the gc pattern
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
mc.MOV_rs(ecx.value, WORD)
- mc.MOV_br(ofs, ecx.value)
+ mc.MOV_br((self.SEGMENT_FRAME, ofs), ecx.value)
#
# align on 16b boundary (there is a retaddr on the stack)
mc.SUB_ri(esp.value, 16 - WORD)
@@ -220,7 +232,7 @@
#
mc.ADD_ri(esp.value, 16 - WORD)
# clear the gc pattern
- mc.MOV_bi(ofs, 0)
+ mc.MOV_bi((self.SEGMENT_FRAME, ofs), 0)
#
# Fill the stm resume buffer. Don't do it before the call!
# The previous transaction may still be aborted during the call
@@ -253,12 +265,12 @@
This function must preserve all registers apart from eax and edi.
"""
assert kind in ['fixed', 'str', 'unicode', 'var']
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
self._push_all_regs_to_frame(mc, [eax, edi], self.cpu.supports_floats)
# store the gc pattern
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
mc.MOV_rs(ecx.value, WORD)
- mc.MOV_br(ofs, ecx.value)
+ mc.MOV_br((self.SEGMENT_FRAME, ofs), ecx.value)
#
if kind == 'fixed':
addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
@@ -309,10 +321,9 @@
self.set_extra_stack_depth(mc, 0)
self._pop_all_regs_from_frame(mc, [eax, edi], self.cpu.supports_floats)
nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr()
- mc.SEGC7()
- mc.MOV(edi, heap(nursery_free_adr)) # load this in EDI
+ mc.MOV(edi, heap(self.SEGMENT_GC, nursery_free_adr)) # load this in EDI
# clear the gc pattern
- mc.MOV_bi(ofs, 0)
+ mc.MOV_bi((self.SEGMENT_FRAME, ofs), 0)
mc.RET()
#
# If the slowpath malloc failed, we raise a MemoryError that
@@ -331,17 +342,17 @@
if not self.cpu.propagate_exception_descr:
return # not supported (for tests, or non-translated)
#
- self.mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ self.mc = codebuf.MachineCodeBlockWrapper()
#
# read and reset the current exception
self._store_and_reset_exception(self.mc, eax)
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
- self.mc.MOV_br(ofs, eax.value)
+ self.mc.MOV_br((self.SEGMENT_FRAME, ofs), eax.value)
propagate_exception_descr = rffi.cast(lltype.Signed,
cast_instance_to_gcref(self.cpu.propagate_exception_descr))
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
- self.mc.MOV(RawEbpLoc(ofs), imm(propagate_exception_descr))
+ self.mc.MOV(self.raw_stack(ofs), imm(propagate_exception_descr))
#
self._call_footer()
rawstart = self.mc.materialize(self.cpu.asmmemmgr, [])
@@ -363,7 +374,7 @@
# | my own retaddr | <-- esp
# +---------------------+
#
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
#
if IS_X86_64:
# on the x86_64, we have to save all the registers that may
@@ -384,9 +395,7 @@
else:
mc.ADD_ri(esp.value, WORD)
#
- ea = mc.in_tl_segment(self.cpu.pos_exception())
- mc.SEGTL()
- mc.MOV(eax, heap(ea))
+ mc.MOV(eax, self.heap_tl(self.cpu.pos_exception()))
mc.TEST_rr(eax.value, eax.value)
mc.J_il8(rx86.Conditions['NZ'], 0)
jnz_location = mc.get_relative_pos()
@@ -423,7 +432,7 @@
# all XMM registers. It takes a single argument just pushed
# on the stack even on X86_64. It must restore stack alignment
# accordingly.
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
#
if not for_frame:
self._push_all_regs_to_frame(mc, [], withfloats, callee_only=True)
@@ -500,7 +509,7 @@
#
# make the stm_longjmp_callback() function, with signature
# void (*longjmp_callback)(void *stm_resume_buffer)
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
#
# 'edi' contains the stm resume buffer, so the new stack
# location that we have to enforce is 'edi - FRAME_FIXED_SIZE * WORD'.
@@ -511,10 +520,8 @@
#
# restore the shadowstack pointer from stm_resume_buffer[1]
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
- rst = mc.in_tl_segment(gcrootmap.get_root_stack_top_addr())
mc.MOV_rs(eax.value, (FRAME_FIXED_SIZE + 1) * WORD)
- mc.SEGTL()
- mc.MOV_jr(rst, eax.value)
+ mc.MOV(self.heap_tl(gcrootmap.get_root_stack_top_addr()), eax)
#
# must restore 'ebp' from its saved value in the shadowstack
self._reload_frame_if_necessary(mc)
@@ -683,7 +690,7 @@
assert rx86.fits_in_32bits(relative_target)
#
if not tok.is_guard_not_invalidated:
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
mc.writeimm32(relative_target)
mc.copy_to_raw_memory(addr)
else:
@@ -708,7 +715,7 @@
if WORD == 8:
for pos_after_jz in self.pending_memoryerror_trampoline_from:
assert self.error_trampoline_64 != 0 # only if non-empty
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
mc.writeimm32(self.error_trampoline_64 - pos_after_jz)
mc.copy_to_raw_memory(rawstart + pos_after_jz - 4)
@@ -728,7 +735,7 @@
"""
descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
- mc.CMP_bi(ofs, 0xffffff) # force writing 32 bit
+ mc.CMP_bi((self.SEGMENT_FRAME, ofs), 0xffffff) # force writing 32 bit
stack_check_cmp_ofs = mc.get_relative_pos() - 4
mc.J_il8(rx86.Conditions['GE'], 0)
jg_location = mc.get_relative_pos()
@@ -751,7 +758,7 @@
return
descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
- mc.CMP_bi(ofs, 0xffffff)
+ mc.CMP_bi((self.SEGMENT_FRAME, ofs), 0xffffff)
stack_check_cmp_ofs = mc.get_relative_pos() - 4
mc.J_il8(rx86.Conditions['GE'], 0)
jg_location = mc.get_relative_pos()
@@ -767,7 +774,7 @@
self.frame_depth_to_patch.append(ofs2)
def _patch_frame_depth(self, adr, allocated_depth):
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
mc.writeimm32(allocated_depth)
mc.copy_to_raw_memory(adr)
@@ -792,7 +799,7 @@
# that. Otherwise, leave the original rel32 to the recovery stub in
# place, but clobber the recovery stub with a jump to the real
# target.
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
if rx86.fits_in_32bits(offset):
mc.writeimm32(offset)
mc.copy_to_raw_memory(adr_jump_offset)
@@ -881,14 +888,11 @@
# there could have been a collection in invalidate_jmp_buf()
# reload the frame into eax, while at the same time popping
# it off the shadowstack
- rst = self.mc.in_tl_segment(gcrootmap.get_root_stack_top_addr())
- assert rx86.fits_in_32bits(rst)
- self.mc.SEGTL()
- self.mc.MOV_rj(ebx.value, rst)
+ rst = self.heap_tl(gcrootmap.get_root_stack_top_addr())
+ self.mc.MOV(ebx, rst)
self.mc.SUB_ri(ebx.value, -WORD)
self.mc.MOV_rm(eax.value, (ebx.value, 0))
- self.mc.SEGTL()
- self.mc.MOV_jr(rst, ebx.value)
+ self.mc.MOV(rst, ebx)
else:
# the return value is the jitframe
self.mc.MOV_rr(eax.value, ebp.value)
@@ -906,46 +910,23 @@
def _load_shadowstack_top_in_ebx(self, mc, gcrootmap):
"""Loads the shadowstack top in ebx, and returns an integer
- that gives the address of the stack top. If this integer doesn't
- fit in 32 bits, it will be loaded in r11.
+ that gives the address of the stack top.
"""
- rst = mc.in_tl_segment(gcrootmap.get_root_stack_top_addr())
- if rx86.fits_in_32bits(rst):
- mc.SEGTL()
- mc.MOV_rj(ebx.value, rst) # MOV ebx, [rootstacktop]
- else:
- mc.MOV_ri(X86_64_SCRATCH_REG.value, rst) # MOV r11, rootstacktop
- mc.MOV_rm(ebx.value, (X86_64_SCRATCH_REG.value, 0))
- # MOV ebx, [r11]
- #
- return rst
+ mc.MOV(ebx, self.heap_tl(gcrootmap.get_root_stack_top_addr()))
def _call_header_shadowstack(self, gcrootmap):
# put the frame in ebp on the shadowstack for the GC to find
# (ebp is a writeable object and does not need a write-barrier
# again (ensured by the code calling the loop))
- rst = self._load_shadowstack_top_in_ebx(self.mc, gcrootmap)
+ self._load_shadowstack_top_in_ebx(self.mc, gcrootmap)
self.mc.MOV_mr((ebx.value, 0), ebp.value) # MOV [ebx], ebp
self.mc.ADD_ri(ebx.value, WORD)
-
- if rx86.fits_in_32bits(rst):
- self.mc.SEGTL()
- self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], ebx
- else:
- # The integer 'rst' doesn't fit in 32 bits, so we know that
- # _load_shadowstack_top_in_ebx() above loaded it in r11.
- # Reuse it. Be careful not to overwrite r11 in the middle!
- self.mc.MOV_mr((X86_64_SCRATCH_REG.value, 0),
- ebx.value) # MOV [r11], ebx
+ self.mc.MOV(self.heap_tl(gcrootmap.get_root_stack_top_addr()), ebx)
+ # MOV [rootstacktop], ebx
def _call_footer_shadowstack(self, gcrootmap):
- rst = self.mc.in_tl_segment(gcrootmap.get_root_stack_top_addr())
- if rx86.fits_in_32bits(rst):
- self.mc.SEGTL()
- self.mc.SUB_ji8(rst, WORD) # SUB [rootstacktop], WORD
- else:
- self.mc.MOV_ri(ebx.value, rst) # MOV ebx, rootstacktop
- self.mc.SUB_mi8((ebx.value, 0), WORD) # SUB [ebx], WORD
+ self.mc.SUB(self.heap_tl(gcrootmap.get_root_stack_top_addr()), WORD)
+ # SUB [rootstacktop], WORD
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
# some minimal sanity checking
@@ -961,7 +942,7 @@
baseofs = self.cpu.get_baseofs_of_frame_field()
newlooptoken.compiled_loop_token.update_frame_info(
oldlooptoken.compiled_loop_token, baseofs)
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
mc.JMP(imm(target))
if WORD == 4: # keep in sync with prepare_loop()
assert mc.get_relative_pos() == 5
@@ -1003,8 +984,8 @@
self.mc.MOVSD_sx(0, loc.value)
elif WORD == 4 and isinstance(loc, FrameLoc) and loc.get_width() == 8:
# XXX evil trick
- self.mc.PUSH_b(loc.value + 4)
- self.mc.PUSH_b(loc.value)
+ self.mc.PUSH_b((loc.segment, loc.value + 4))
+ self.mc.PUSH_b((loc.segment, loc.value))
else:
self.mc.PUSH(loc)
@@ -1014,8 +995,8 @@
self.mc.ADD_ri(esp.value, 8) # = size of doubles
elif WORD == 4 and isinstance(loc, FrameLoc) and loc.get_width() == 8:
# XXX evil trick
- self.mc.POP_b(loc.value)
- self.mc.POP_b(loc.value + 4)
+ self.mc.POP_b((loc.segment, loc.value))
+ self.mc.POP_b((loc.segment, loc.value + 4))
else:
self.mc.POP(loc)
@@ -1028,8 +1009,8 @@
low_part = intmask(low_part)
high_part = intmask(high_part)
if isinstance(to_loc, RawEbpLoc):
- self.mc.MOV32_bi(to_loc.value, low_part)
- self.mc.MOV32_bi(to_loc.value + 4, high_part)
+ self.mc.MOV32_bi((to_loc.segment, to_loc.value), low_part)
+ self.mc.MOV32_bi((to_loc.segment, to_loc.value + 4), high_part)
else:
assert isinstance(to_loc, RawEspLoc)
self.mc.MOV32_si(to_loc.value, low_part)
@@ -1212,10 +1193,8 @@
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap:
if gcrootmap.is_shadow_stack:
- rst = mc.in_tl_segment(gcrootmap.get_root_stack_top_addr())
- mc.SEGTL()
- mc.MOV(ecx, heap(rst))
- mc.MOV(ebp, mem(ecx, -WORD))
+ mc.MOV(ecx, self.heap_tl(gcrootmap.get_root_stack_top_addr()))
+ mc.MOV(ebp, mem(self.SEGMENT_NO, ecx, -WORD))
#
wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
if gcrootmap and wbdescr:
@@ -1408,7 +1387,7 @@
if isinstance(loc, RegLoc):
self.mc.MOVD_rx(resloc.value, loc.value)
elif isinstance(loc, FrameLoc):
- self.mc.MOV_rb(resloc.value, loc.value)
+ self.mc.MOV(resloc, loc)
else:
not_implemented("llong_to_int: %s" % (loc,))
@@ -1486,10 +1465,9 @@
# ----------
- def load_from_mem(self, resloc, source_addr, size_loc, sign_loc, op):
+ def load_from_mem(self, resloc, source_addr, size_loc, sign_loc):
size = size_loc.value
sign = sign_loc.value
- self.mc.SEGC7_if_gc(op)
self.generate_one_mov_with_extension(resloc, source_addr, size, sign)
def generate_one_mov_with_extension(self, resloc, srcloc, size, sign):
@@ -1516,9 +1494,8 @@
else:
not_implemented("load_from_mem size = %d" % size)
- def save_into_mem(self, dest_addr, value_loc, size_loc, op):
+ def save_into_mem(self, dest_addr, value_loc, size_loc):
size = size_loc.value
- self.mc.SEGC7_if_gc(op)
if isinstance(value_loc, RegLoc) and value_loc.is_xmm:
self.mc.MOVSD(dest_addr, value_loc)
elif size == 1:
@@ -1533,37 +1510,45 @@
else:
assert isinstance(value_loc, FloatImmedLoc)
self.mc.MOV(dest_addr, value_loc.low_part_loc())
- self.mc.SEGC7_if_gc(op)
self.mc.MOV(dest_addr.add_offset(4), value_loc.high_part_loc())
else:
not_implemented("save_into_mem size = %d" % size)
- def genop_getfield_gc(self, op, arglocs, resloc):
+ def _genop_getfield(self, arglocs, resloc, segment):
base_loc, ofs_loc, size_loc, sign_loc = arglocs
assert isinstance(size_loc, ImmedLoc)
- source_addr = AddressLoc(base_loc, ofs_loc)
- self.load_from_mem(resloc, source_addr, size_loc, sign_loc, op)
+ source_addr = AddressLoc(segment, base_loc, ofs_loc)
+ self.load_from_mem(resloc, source_addr, size_loc, sign_loc)
- genop_getfield_raw = genop_getfield_gc
- genop_getfield_raw_pure = genop_getfield_gc
+ def genop_getfield_gc(self, op, arglocs, resloc):
+ self._genop_getfield(arglocs, resloc, self.SEGMENT_GC)
+ def genop_getfield_raw(self, op, arglocs, resloc):
+ self._genop_getfield(arglocs, resloc, self.SEGMENT_NO)
+
genop_getfield_gc_pure = genop_getfield_gc
+ genop_getfield_raw_pure = genop_getfield_raw
- def genop_getarrayitem_gc(self, op, arglocs, resloc):
+ def _genop_getarrayitem(self, arglocs, resloc, segment):
base_loc, ofs_loc, size_loc, ofs, sign_loc = arglocs
assert isinstance(ofs, ImmedLoc)
assert isinstance(size_loc, ImmedLoc)
scale = get_scale(size_loc.value)
- src_addr = addr_add(base_loc, ofs_loc, ofs.value, scale)
- self.load_from_mem(resloc, src_addr, size_loc, sign_loc, op)
+ src_addr = addr_add(segment, base_loc, ofs_loc, ofs.value, scale)
+ self.load_from_mem(resloc, src_addr, size_loc, sign_loc)
+
+ def genop_getarrayitem_gc(self, op, arglocs, resloc, segment):
+ self._genop_getarrayitem(arglocs, resloc, self.SEGMENT_GC)
+ def genop_getarrayitem_raw(self, op, arglocs, resloc, segment):
+ self._genop_getarrayitem(arglocs, resloc, self.SEGMENT_NO)
genop_getarrayitem_gc_pure = genop_getarrayitem_gc
- genop_getarrayitem_raw = genop_getarrayitem_gc
- genop_getarrayitem_raw_pure = genop_getarrayitem_gc
+ genop_getarrayitem_raw_pure = genop_getarrayitem_raw
def genop_raw_load(self, op, arglocs, resloc):
+ assert not isinstance(op.getarg(0), BoxPtr) # not for a GC argument!
base_loc, ofs_loc, size_loc, ofs, sign_loc = arglocs
assert isinstance(ofs, ImmedLoc)
- src_addr = addr_add(base_loc, ofs_loc, ofs.value, 0)
+ src_addr = addr_add(self.SEGMENT_NO, base_loc, ofs_loc, ofs.value, 0)
self.load_from_mem(resloc, src_addr, size_loc, sign_loc, op)
def _imul_const_scaled(self, mc, targetreg, sourcereg, itemsize):
@@ -1609,15 +1594,17 @@
shift = self._imul_const_scaled(self.mc, temp_loc.value,
index_loc.value, itemsize)
assert isinstance(ofs_loc, ImmedLoc)
- return AddressLoc(base_loc, temp_loc, shift, ofs_loc.value)
+ return AddressLoc(self.SEGMENT_GC, base_loc, temp_loc,
+ shift, ofs_loc.value)
def genop_getinteriorfield_gc(self, op, arglocs, resloc):
+ assert not isinstance(op.getarg(0), BoxInt) # only for a GC argument!
(base_loc, ofs_loc, itemsize_loc, fieldsize_loc,
index_loc, temp_loc, sign_loc) = arglocs
src_addr = self._get_interiorfield_addr(temp_loc, index_loc,
itemsize_loc, base_loc,
ofs_loc)
- self.load_from_mem(resloc, src_addr, fieldsize_loc, sign_loc, op)
+ self.load_from_mem(resloc, src_addr, fieldsize_loc, sign_loc)
def genop_discard_increment_debug_counter(self, op, arglocs):
# The argument should be an immediate address. This should
@@ -1625,15 +1612,21 @@
# SETFIELD_RAW. Here we use the direct from-memory-to-memory
# increment operation of x86.
base_loc, = arglocs
- self.mc.INC(mem(base_loc, 0))
+ self.mc.INC(mem(self.SEGMENT_NO, base_loc, 0))
+
+ def _genop_discard_setfield(self, arglocs, segment):
+ base_loc, ofs_loc, size_loc, value_loc = arglocs
+ assert isinstance(size_loc, ImmedLoc)
+ dest_addr = AddressLoc(segment, base_loc, ofs_loc)
+ self.save_into_mem(dest_addr, value_loc, size_loc)
def genop_discard_setfield_gc(self, op, arglocs):
- base_loc, ofs_loc, size_loc, value_loc = arglocs
- assert isinstance(size_loc, ImmedLoc)
- dest_addr = AddressLoc(base_loc, ofs_loc)
- self.save_into_mem(dest_addr, value_loc, size_loc, op)
+ self._genop_discard_setfield(arglocs, self.SEGMENT_GC)
+ def genop_discard_setfield_raw(self, op, arglocs):
+ self._genop_discard_setfield(arglocs, self.SEGMENT_NO)
def genop_discard_setinteriorfield_gc(self, op, arglocs):
+ assert not isinstance(op.getarg(0), BoxInt) # only for a GC argument!
(base_loc, ofs_loc, itemsize_loc, fieldsize_loc,
index_loc, temp_loc, value_loc) = arglocs
dest_addr = self._get_interiorfield_addr(temp_loc, index_loc,
@@ -1641,28 +1634,34 @@
ofs_loc)
self.save_into_mem(dest_addr, value_loc, fieldsize_loc, op)
- genop_discard_setinteriorfield_raw = genop_discard_setinteriorfield_gc
-
- def genop_discard_setarrayitem_gc(self, op, arglocs):
+ def _genop_discard_setarrayitem(self, arglocs, segment):
base_loc, ofs_loc, value_loc, size_loc, baseofs = arglocs
assert isinstance(baseofs, ImmedLoc)
assert isinstance(size_loc, ImmedLoc)
scale = get_scale(size_loc.value)
- dest_addr = AddressLoc(base_loc, ofs_loc, scale, baseofs.value)
- self.save_into_mem(dest_addr, value_loc, size_loc, op)
+ dest_addr = AddressLoc(segment, base_loc, ofs_loc,
+ scale, baseofs.value)
+ self.save_into_mem(dest_addr, value_loc, size_loc)
+
+ def genop_discard_setarrayitem_gc(self, op, arglocs):
+ self._genop_discard_setarrayitem(arglocs, self.SEGMENT_GC)
+ def genop_discard_setarrayitem_raw(self, op, arglocs):
+ self._genop_discard_setarrayitem(arglocs, self.SEGMENT_NO)
def genop_discard_raw_store(self, op, arglocs):
+ assert not isinstance(op.getarg(0), BoxPtr) # not for a GC argument!
base_loc, ofs_loc, value_loc, size_loc, baseofs = arglocs
assert isinstance(baseofs, ImmedLoc)
- dest_addr = AddressLoc(base_loc, ofs_loc, 0, baseofs.value)
- self.save_into_mem(dest_addr, value_loc, size_loc, op)
+ dest_addr = AddressLoc(self.SEGMENT_NO, base_loc, ofs_loc,
+ 0, baseofs.value)
+ self.save_into_mem(dest_addr, value_loc, size_loc)
def genop_discard_strsetitem(self, op, arglocs):
base_loc, ofs_loc, val_loc = arglocs
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
assert itemsize == 1
- dest_addr = AddressLoc(base_loc, ofs_loc, 0, basesize)
+ dest_addr = AddressLoc(self.SEGMENT_GC, base_loc, ofs_loc, 0, basesize)
self.mc.MOV8(dest_addr, val_loc.lowest8bits())
def genop_discard_unicodesetitem(self, op, arglocs):
@@ -1670,15 +1669,14 @@
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
if itemsize == 4:
- self.mc.MOV32(AddressLoc(base_loc, ofs_loc, 2, basesize), val_loc)
+ self.mc.MOV32(AddressLoc(self.SEGMENT_GC, base_loc, ofs_loc,
+ 2, basesize), val_loc)
elif itemsize == 2:
- self.mc.MOV16(AddressLoc(base_loc, ofs_loc, 1, basesize), val_loc)
+ self.mc.MOV16(AddressLoc(self.SEGMENT_GC, base_loc, ofs_loc,
+ 1, basesize), val_loc)
else:
assert 0, itemsize
- genop_discard_setfield_raw = genop_discard_setfield_gc
- genop_discard_setarrayitem_raw = genop_discard_setarrayitem_gc
-
def genop_strlen(self, op, arglocs, resloc):
base_loc = arglocs[0]
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
@@ -1701,16 +1699,19 @@
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
assert itemsize == 1
- self.mc.MOVZX8(resloc, AddressLoc(base_loc, ofs_loc, 0, basesize))
+ self.mc.MOVZX8(resloc, AddressLoc(self.SEGMENT_GC, base_loc,
+ ofs_loc, 0, basesize))
def genop_unicodegetitem(self, op, arglocs, resloc):
base_loc, ofs_loc = arglocs
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
if itemsize == 4:
- self.mc.MOV32(resloc, AddressLoc(base_loc, ofs_loc, 2, basesize))
+ self.mc.MOV32(resloc, AddressLoc(self.SEGMENT_GC, base_loc,
+ ofs_loc, 2, basesize))
elif itemsize == 2:
- self.mc.MOVZX16(resloc, AddressLoc(base_loc, ofs_loc, 1, basesize))
+ self.mc.MOVZX16(resloc, AddressLoc(self.SEGMENT_GC, base_loc,
+ ofs_loc, 1, basesize))
else:
assert 0, itemsize
@@ -1733,9 +1734,7 @@
def genop_guard_guard_no_exception(self, ign_1, guard_op, guard_token,
locs, ign_2):
- ea = self.mc.in_tl_segment(self.cpu.pos_exception())
- self.mc.SEGTL()
- self.mc.CMP(heap(ea), imm0)
+ self.mc.CMP(self.heap_tl(self.cpu.pos_exception()), imm0)
self.implement_guard(guard_token, 'NZ')
def genop_guard_guard_not_invalidated(self, ign_1, guard_op, guard_token,
@@ -1748,9 +1747,7 @@
locs, resloc):
loc = locs[0]
loc1 = locs[1]
- ea = self.mc.in_tl_segment(self.cpu.pos_exception())
- self.mc.SEGTL()
- self.mc.MOV(loc1, heap(ea))
+ self.mc.MOV(loc1, self.heap_tl(self.cpu.pos_exception()))
self.mc.CMP(loc1, loc)
self.implement_guard(guard_token, 'NE')
self._store_and_reset_exception(self.mc, resloc)
@@ -1760,44 +1757,31 @@
""" Resest the exception. If excvalloc is None, then store it on the
frame in jf_guard_exc
"""
- eva = mc.in_tl_segment(self.cpu.pos_exc_value())
- ea = mc.in_tl_segment(self.cpu.pos_exception())
- #
if excvalloc is not None:
assert excvalloc.is_core_reg()
- mc.SEGTL()
- mc.MOV(excvalloc, heap(eva))
+ mc.MOV(excvalloc, self.heap_tl(self.cpu.pos_exc_value()))
elif tmploc is not None: # if both are None, just ignore
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
- mc.SEGTL()
- mc.MOV(tmploc, heap(eva))
- mc.MOV(RawEbpLoc(ofs), tmploc)
+ mc.MOV(tmploc, self.heap_tl(self.cpu.pos_exc_value()))
+ mc.MOV(self.raw_stack(ofs), tmploc)
#
if exctploc is not None:
assert exctploc.is_core_reg()
- mc.SEGTL()
- mc.MOV(exctploc, heap(ea))
+ mc.MOV(exctploc, self.heap_tl(self.cpu.pos_exception()))
#
- mc.SEGTL()
- mc.MOV(heap(ea), imm0)
- mc.SEGTL()
- mc.MOV(heap(eva), imm0)
+ mc.MOV(self.heap_tl(self.cpu.pos_exception()), imm0)
+ mc.MOV(self.heap_tl(self.cpu.pos_exc_value()), imm0)
def _restore_exception(self, mc, excvalloc, exctploc, tmploc=None):
- eva = mc.in_tl_segment(self.cpu.pos_exc_value())
- ea = mc.in_tl_segment(self.cpu.pos_exception())
if excvalloc is not None:
- mc.SEGTL()
- mc.MOV(heap(eva), excvalloc)
+ mc.MOV(heap(self.cpu.pos_exc_value()), excvalloc)
else:
assert tmploc is not None
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
- mc.MOV(tmploc, RawEbpLoc(ofs))
- mc.MOV_bi(ofs, 0)
- mc.SEGTL()
- mc.MOV(heap(eva), tmploc)
- mc.SEGTL()
- mc.MOV(heap(ea), exctploc)
+ mc.MOV(tmploc, self.raw_stack(ofs))
+ mc.MOV_bi((self.SEGMENT_FRAME, ofs), 0)
+ mc.MOV(self.heap_tl(self.cpu.pos_exc_value()), tmploc)
+ mc.MOV(self.heap_tl(self.cpu.pos_exception()), exctploc)
def _gen_guard_overflow(self, guard_op, guard_token):
guard_opnum = guard_op.getopnum()
@@ -1838,7 +1822,7 @@
def _cmp_guard_class(self, locs):
offset = self.cpu.vtable_offset
if offset is not None:
- self.mc.CMP(mem(locs[0], offset), locs[1])
+ self.mc.CMP(mem(self.SEGMENT_NO, locs[0], offset), locs[1])
else:
# XXX hard-coded assumption: to go from an object to its class
# we use the following algorithm:
@@ -1864,9 +1848,11 @@
expected_typeid = classptr - sizeof_ti - type_info_group
if IS_X86_32:
expected_typeid >>= 2
- self.mc.CMP16(mem(locs[0], 0), ImmedLoc(expected_typeid))
+ self.mc.CMP16(mem(self.SEGMENT_NO, locs[0], 0),
+ ImmedLoc(expected_typeid))
elif IS_X86_64:
- self.mc.CMP32_mi((locs[0].value, 0), expected_typeid)
+ self.mc.CMP32_mi((self.SEGMENT_NO, locs[0].value, 0),
+ expected_typeid)
def genop_guard_guard_class(self, ign_1, guard_op, guard_token, locs,
ign_2):
self._cmp_guard_class(locs)
@@ -1923,15 +1909,15 @@
else:
assert store
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- mc.MOV(raw_stack(ofs), imm(rffi.cast(lltype.Signed, gcmap)))
+ mc.MOV(self.raw_stack(ofs), imm(rffi.cast(lltype.Signed, gcmap)))
def pop_gcmap(self, mc):
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- mc.MOV_bi(ofs, 0)
+ mc.MOV_bi((self.SEGMENT_FRAME, ofs), 0)
def new_stack_loc(self, i, pos, tp):
base_ofs = self.cpu.get_baseofs_of_frame_field()
- return FrameLoc(i, get_ebp_ofs(base_ofs, i), tp)
+ return FrameLoc(self.SEGMENT_FRAME, i, get_ebp_ofs(base_ofs, i), tp)
def setup_failure_recovery(self):
self.failure_recovery_code = [0, 0, 0, 0]
@@ -1947,7 +1933,7 @@
for gpr in regs:
if gpr not in ignored_regs:
v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
- mc.MOV_br(v * WORD + base_ofs, gpr.value)
+ mc.MOV_br((self.SEGMENT_FRAME, v * WORD + base_ofs), gpr.value)
if withfloats:
if IS_X86_64:
coeff = 1
@@ -1956,7 +1942,8 @@
# Push all XMM regs
ofs = len(gpr_reg_mgr_cls.all_regs)
for i in range(len(xmm_reg_mgr_cls.all_regs)):
- mc.MOVSD_bx((ofs + i * coeff) * WORD + base_ofs, i)
+ mc.MOVSD_bx((self.SEGMENT_FRAME,
+ (ofs + i * coeff) * WORD + base_ofs), i)
def _pop_all_regs_from_frame(self, mc, ignored_regs, withfloats,
callee_only=False):
@@ -1969,7 +1956,7 @@
for gpr in regs:
if gpr not in ignored_regs:
v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
- mc.MOV_rb(gpr.value, v * WORD + base_ofs)
+ mc.MOV_rb(gpr.value, (self.SEGMENT_FRAME, v * WORD + base_ofs))
if withfloats:
# Pop all XMM regs
if IS_X86_64:
@@ -1978,27 +1965,23 @@
coeff = 2
ofs = len(gpr_reg_mgr_cls.all_regs)
for i in range(len(xmm_reg_mgr_cls.all_regs)):
- mc.MOVSD_xb(i, (ofs + i * coeff) * WORD + base_ofs)
+ mc.MOVSD_xb(i, (self.SEGMENT_FRAME,
+ (ofs + i * coeff) * WORD + base_ofs))
def _build_failure_recovery(self, exc, withfloats=False):
- mc = codebuf.MachineCodeBlockWrapper(self.cpu)
+ mc = codebuf.MachineCodeBlockWrapper()
self.mc = mc
self._push_all_regs_to_frame(mc, [], withfloats)
if exc:
# We might have an exception pending. Load it into ebx...
- eva = mc.in_tl_segment(self.cpu.pos_exc_value())
- ea = mc.in_tl_segment(self.cpu.pos_exception())
- mc.SEGTL()
- mc.MOV(ebx, heap(eva))
- mc.SEGTL()
- mc.MOV(heap(ea), imm0)
- mc.SEGTL()
- mc.MOV(heap(eva), imm0)
+ mc.MOV(ebx, self.heap_tl(self.cpu.pos_exc_value()))
+ mc.MOV(self.heap_tl(self.cpu.pos_exception()), imm0)
+ mc.MOV(self.heap_tl(self.cpu.pos_exc_value()), imm0)
# ...and save ebx into 'jf_guard_exc'
offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
- mc.MOV_br(offset, ebx.value)
+ mc.MOV_br((self.SEGMENT_FRAME, offset), ebx.value)
# now we return from the complete frame, which starts from
# _call_header_with_stack_check(). The LEA in _call_footer below
@@ -2006,8 +1989,8 @@
# did just above.
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- mc.POP_b(ofs2)
- mc.POP_b(ofs)
+ mc.POP_b((self.SEGMENT_FRAME, ofs2))
+ mc.POP_b((self.SEGMENT_FRAME, ofs))
self._call_footer()
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
@@ -2022,11 +2005,11 @@
size = WORD * 2
else:
size = WORD
- self.save_into_mem(raw_stack(base_ofs), return_val, imm(size), op)
+ self.save_into_mem(self.raw_stack(base_ofs), return_val, imm(size))
else:
[fail_descr_loc] = arglocs
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
- self.mov(fail_descr_loc, RawEbpLoc(ofs))
+ self.mov(fail_descr_loc, self.raw_stack(ofs))
arglist = op.getarglist()
if arglist and arglist[0].type == REF:
if self._finish_gcmap:
@@ -2039,7 +2022,7 @@
# note that the 0 here is redundant, but I would rather
# keep that one and kill all the others
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- self.mc.MOV_bi(ofs, 0)
+ self.mc.MOV_bi((self.SEGMENT_FRAME, ofs), 0)
# exit function
self._call_footer()
@@ -2083,12 +2066,12 @@
def _store_force_index(self, guard_op):
faildescr = guard_op.getdescr()
ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr')
- self.mc.MOV(raw_stack(ofs), imm(rffi.cast(lltype.Signed,
+ self.mc.MOV(self.raw_stack(ofs), imm(rffi.cast(lltype.Signed,
cast_instance_to_gcref(faildescr))))
def _emit_guard_not_forced(self, guard_token):
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
- self.mc.CMP_bi(ofs, 0)
+ self.mc.CMP_bi((self.SEGMENT_FRAME, ofs), 0)
self.implement_guard(guard_token, 'NE')
def genop_guard_call_may_force(self, op, guard_op, guard_token,
@@ -2162,7 +2145,7 @@
def _call_assembler_check_descr(self, value, tmploc):
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
- self.mc.CMP(mem(eax, ofs), imm(value))
+ self.mc.CMP(mem(self.SEGMENT_FRAME, eax, ofs), imm(value))
# patched later
self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get
'done_with_this_frame'
return self.mc.get_relative_pos()
@@ -2170,7 +2153,7 @@
def _call_assembler_patch_je(self, result_loc, je_location):
if (IS_X86_32 and isinstance(result_loc, FrameLoc) and
result_loc.type == FLOAT):
- self.mc.FSTPL_b(result_loc.value)
+ self.mc.FSTPL_b((result_loc.segment, result_loc.value))
self.mc.JMP_l8(0) # jump to done, patched later
jmp_location = self.mc.get_relative_pos()
#
@@ -2224,7 +2207,7 @@
loc_base = arglocs[0]
if is_frame:
assert loc_base is ebp
- loc = raw_stack(descr.jit_wb_if_flag_byteofs)
+ loc = self.raw_stack(descr.jit_wb_if_flag_byteofs)
else:
loc = addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs)
mc.TEST8(loc, imm(mask))
@@ -2363,7 +2346,8 @@
if gpr not in should_be_saved:
continue
v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
- self.mc.MOV_br(v * WORD + base_ofs, gpr.value)
+ self.mc.MOV_br((self.SEGMENT_FRAME, v * WORD + base_ofs),
+ gpr.value)
#
# load the 0-to-4 arguments into these registers
from rpython.jit.backend.x86.jump import remap_frame_layout
@@ -2398,11 +2382,9 @@
def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap):
assert size & (WORD-1) == 0 # must be correctly aligned
- self.mc.SEGC7()
- self.mc.MOV(eax, heap(nursery_free_adr))
+ self.mc.MOV(eax, heap(self.SEGMENT_GC, nursery_free_adr))
self.mc.LEA_rm(edi.value, (eax.value, size))
- self.mc.SEGC7()
- self.mc.CMP(edi, heap(nursery_top_adr))
+ self.mc.CMP(edi, heap(self.SEGMENT_GC, nursery_top_adr))
self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
jmp_adr = self.mc.get_relative_pos()
# save the gcmap
@@ -2411,8 +2393,7 @@
offset = self.mc.get_relative_pos() - jmp_adr
assert 0 < offset <= 127
self.mc.overwrite(jmp_adr-1, chr(offset))
- self.mc.SEGC7()
- self.mc.MOV(heap(nursery_free_adr), edi)
+ self.mc.MOV(heap(self.SEGMENT_GC, nursery_free_adr), edi)
def malloc_cond_varsize_frame(self, nursery_free_adr, nursery_top_adr,
sizeloc, gcmap):
@@ -2421,8 +2402,7 @@
if sizeloc is eax:
self.mc.MOV(edi, sizeloc)
sizeloc = edi
- self.mc.SEGC7()
- self.mc.MOV(eax, heap(nursery_free_adr))
+ self.mc.MOV(eax, heap(self.SEGMENT_GC, nursery_free_adr))
if self.cpu.gc_ll_descr.stm:
constsize = self.cpu.get_baseofs_of_frame_field()
shift = get_scale(WORD)
@@ -2432,8 +2412,7 @@
self.mc.ADD_rr(edi.value, eax.value)
else:
self.mc.LEA_ra(edi.value, (eax.value, sizeloc.value, 0, 0))
- self.mc.SEGC7()
- self.mc.CMP(edi, heap(nursery_top_adr))
+ self.mc.CMP(edi, heap(self.SEGMENT_GC, nursery_top_adr))
self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
jmp_adr = self.mc.get_relative_pos()
# save the gcmap
@@ -2442,8 +2421,7 @@
offset = self.mc.get_relative_pos() - jmp_adr
assert 0 < offset <= 127
self.mc.overwrite(jmp_adr-1, chr(offset))
- self.mc.SEGC7()
- self.mc.MOV(heap(nursery_free_adr), edi)
+ self.mc.MOV(heap(self.SEGMENT_GC, nursery_free_adr), edi)
def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr,
lengthloc, itemsize, maxlength, gcmap,
@@ -2463,8 +2441,7 @@
self.mc.J_il8(rx86.Conditions['A'], 0) # patched later
jmp_adr0 = self.mc.get_relative_pos()
- self.mc.SEGC7()
- self.mc.MOV(eax, heap(nursery_free_adr))
+ self.mc.MOV(eax, heap(self.SEGMENT_GC, nursery_free_adr))
if valid_addressing_size(itemsize):
shift = get_scale(itemsize)
else:
@@ -2484,8 +2461,7 @@
self.mc.AND_ri(edi.value, ~(WORD - 1))
# now edi contains the total size in bytes, rounded up to a multiple
# of WORD, plus nursery_free_adr
- self.mc.SEGC7()
- self.mc.CMP(edi, heap(nursery_top_adr))
+ self.mc.CMP(edi, heap(self.SEGMENT_GC, nursery_top_adr))
self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later
jmp_adr1 = self.mc.get_relative_pos()
#
@@ -2514,10 +2490,9 @@
assert 0 < offset <= 127
self.mc.overwrite(jmp_adr1-1, chr(offset))
# write down the tid, but not if it's the result of the CALL
- self.mc.MOV(mem(eax, 0), imm(arraydescr.tid))
+ self.mc.MOV(mem(self.SEGMENT_GC, eax, 0), imm(arraydescr.tid))
# while we're at it, this line is not needed if we've done the CALL
- self.mc.SEGC7()
- self.mc.MOV(heap(nursery_free_adr), edi)
+ self.mc.MOV(heap(self.SEGMENT_GC, nursery_free_adr), edi)
#
offset = self.mc.get_relative_pos() - jmp_location
assert 0 < offset <= 127
@@ -2568,14 +2543,15 @@
base_ofs = self.cpu.get_baseofs_of_frame_field()
for gpr in self._regalloc.rm.reg_bindings.values():
v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
- mc.MOV_br(v * WORD + base_ofs, gpr.value)
+ mc.MOV_br((self.SEGMENT_FRAME, v * WORD + base_ofs), gpr.value)
if IS_X86_64:
coeff = 1
else:
coeff = 2
ofs = len(gpr_reg_mgr_cls.all_regs)
for xr in self._regalloc.xrm.reg_bindings.values():
- mc.MOVSD_bx((ofs + xr.value * coeff) * WORD + base_ofs, xr.value)
+ mc.MOVSD_bx((self.SEGMENT_FRAME,
+ (ofs + xr.value * coeff) * WORD + base_ofs), xr.value)
#
# CALL break function
fn = self.stm_transaction_break_path
@@ -2587,14 +2563,15 @@
base_ofs = self.cpu.get_baseofs_of_frame_field()
for gpr in self._regalloc.rm.reg_bindings.values():
v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
- mc.MOV_rb(gpr.value, v * WORD + base_ofs)
+ mc.MOV_rb(gpr.value, (self.SEGMENT_FRAME, v * WORD + base_ofs))
if IS_X86_64:
coeff = 1
else:
coeff = 2
ofs = len(gpr_reg_mgr_cls.all_regs)
for xr in self._regalloc.xrm.reg_bindings.values():
- mc.MOVSD_xb(xr.value, (ofs + xr.value * coeff) * WORD + base_ofs)
+ mc.MOVSD_xb(xr.value, (self.SEGMENT_FRAME,
+ (ofs + xr.value * coeff) * WORD + base_ofs))
#
# patch the JZ above
offset = mc.get_relative_pos() - jz_location2
@@ -2607,17 +2584,15 @@
todo() # "needed for X86_64_SCRATCH_REG"
mc = self.mc
rmreg = X86_64_SCRATCH_REG.value
- mc.SEGC7()
- mc.MOVZX8_rj(rmreg, rstm.adr_transaction_read_version)
- #
+ mc.MOVZX8_rj(rmreg, (self.SEGMENT_GC,
+ rstm.adr_transaction_read_version))
loc_src, loc_tmp = arglocs
if loc_tmp is None:
assert isinstance(loc_src, ImmedLoc)
assert loc_src.value > 0
mem = loc_src.value >> 4
assert rx86.fits_in_32bits(mem)
- mc.SEGC7()
- mc.MOV8_jr(mem, rmreg | rx86.BYTE_REG_FLAG)
+ mc.MOV8_jr((self.SEGMENT_GC, mem), rmreg | rx86.BYTE_REG_FLAG)
else:
assert isinstance(loc_tmp, RegLoc)
if isinstance(loc_src, ImmedLoc):
@@ -2626,8 +2601,21 @@
if loc_tmp is not loc_src:
mc.MOV(loc_tmp, loc_src)
mc.SHR_ri(loc_tmp.value, 4)
- mc.SEGC7()
- mc.MOV8_mr((loc_tmp.value, 0), rmreg | rx86.BYTE_REG_FLAG)
+ mc.MOV8_mr((self.SEGMENT_GC, loc_tmp.value, 0),
+ rmreg | rx86.BYTE_REG_FLAG)
+
+ def raw_stack(self, offset, type=INT):
+ return RawEbpLoc(self.SEGMENT_FRAME, offset, type)
+
+ def heap_tl(self, adr):
+ """Makes 'adr' relative to threadlocal-base if we run in STM.
+ Returns a heap()-like AddressLoc.
+ """
+ if self.SEGMENT_TL != self.SEGMENT_NO:
+ # only for STM and not during tests
+ adr -= stmtlocal.threadlocal_base()
+ assert rx86.fits_in_32bits(adr)
+ return heap(self.SEGMENT_TL, adr)
genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
@@ -2659,17 +2647,14 @@
genop_list[num] = value
# XXX: ri386 migration shims:
-def addr_add(reg_or_imm1, reg_or_imm2, offset=0, scale=0):
- return AddressLoc(reg_or_imm1, reg_or_imm2, scale, offset)
+def addr_add(segment, reg_or_imm1, reg_or_imm2, offset=0, scale=0):
+ return AddressLoc(segment, reg_or_imm1, reg_or_imm2, scale, offset)
-def addr_add_const(reg_or_imm1, offset):
- return AddressLoc(reg_or_imm1, imm0, 0, offset)
+def addr_add_const(segment, reg_or_imm1, offset):
+ return AddressLoc(segment, reg_or_imm1, imm0, 0, offset)
-def mem(loc, offset):
- return AddressLoc(loc, imm0, 0, offset)
-
-def raw_stack(offset, type=INT):
- return RawEbpLoc(offset, type)
+def mem(segment, loc, offset):
+ return AddressLoc(segment, loc, imm0, 0, offset)
def heap(segment, addr):
return AddressLoc(segment, ImmedLoc(addr), imm0, 0, 0)
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -88,12 +88,14 @@
save_around_call_regs = all_regs
class X86FrameManager(FrameManager):
- def __init__(self, base_ofs):
+ def __init__(self, base_ofs, segment):
FrameManager.__init__(self)
self.base_ofs = base_ofs
+ self.segment = segment
def frame_pos(self, i, box_type):
- return FrameLoc(i, get_ebp_ofs(self.base_ofs, i), box_type)
+ return FrameLoc(self.segment, i,
+ get_ebp_ofs(self.base_ofs, i), box_type)
@staticmethod
def frame_size(box_type):
@@ -134,7 +136,8 @@
def _prepare(self, inputargs, operations, allgcrefs):
cpu = self.assembler.cpu
- self.fm = X86FrameManager(cpu.get_baseofs_of_frame_field())
+ self.fm = X86FrameManager(cpu.get_baseofs_of_frame_field(),
+ self.assembler.SEGMENT_FRAME)
operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations,
allgcrefs)
# compute longevity of variables
@@ -962,8 +965,6 @@
self.perform_discard(op, [base_loc, ofs, itemsize, fieldsize,
index_loc, temp_loc, value_loc])
- consider_setinteriorfield_raw = consider_setinteriorfield_gc
-
def consider_strsetitem(self, op):
args = op.getarglist()
base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args)
diff --git a/rpython/jit/backend/x86/regloc.py
b/rpython/jit/backend/x86/regloc.py
--- a/rpython/jit/backend/x86/regloc.py
+++ b/rpython/jit/backend/x86/regloc.py
@@ -32,7 +32,7 @@
raise NotImplementedError
def value_r(self): return self.value
- def value_b(self): return self.value
+ def value_b(self): raise AssertionError("value_b undefined")
def value_s(self): return self.value
def value_j(self): raise AssertionError("value_j undefined")
def value_i(self): return self.value
@@ -58,10 +58,17 @@
_immutable_ = True
_location_code = 'b'
- def __init__(self, value, type=INT):
+ def __init__(self, segment, value, type=INT):
+ if not we_are_translated():
+ assert segment in (rx86.SEGMENT_NO, rx86.SEGMENT_FS,
+ rx86.SEGMENT_GS)
+ self.segment = segment
self.value = value
self.type = type
+ def value_b(self):
+ return (self.segment, self.value)
+
def get_width(self):
if self.type == FLOAT:
return 8
@@ -112,12 +119,13 @@
class FrameLoc(RawEbpLoc):
_immutable_ = True
-
- def __init__(self, position, ebp_offset, type):
+
+ def __init__(self, segment, position, ebp_offset, type):
# _getregkey() returns self.value; the value returned must not
# conflict with RegLoc._getregkey(). It doesn't a bit by chance,
# so let it fail the following assert if it no longer does.
assert ebp_offset >= 8 + 8 * IS_X86_64
+ self.segment = segment
self.position = position
#if position != 9999:
# assert (position + JITFRAME_FIXED_SIZE) * WORD == ebp_offset
diff --git a/rpython/jit/metainterp/executor.py
b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -338,7 +338,6 @@
rop.DEBUG_MERGE_POINT,
rop.JIT_DEBUG,
rop.SETARRAYITEM_RAW,
- rop.SETINTERIORFIELD_RAW,
rop.CALL_RELEASE_GIL,
rop.QUASIIMMUT_FIELD,
rop.CALL_MALLOC_GC,
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -267,7 +267,6 @@
opnum == rop.SETFIELD_RAW or # no effect on GC struct/array
opnum == rop.SETARRAYITEM_GC or # handled specially
opnum == rop.SETARRAYITEM_RAW or # no effect on GC struct
- opnum == rop.SETINTERIORFIELD_RAW or # no effect on GC struct
opnum == rop.RAW_STORE or # no effect on GC struct
opnum == rop.STRSETITEM or # no effect on GC struct/array
opnum == rop.UNICODESETITEM or # no effect on GC struct/array
diff --git a/rpython/jit/metainterp/resoperation.py
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -494,7 +494,6 @@
'SETARRAYITEM_GC/3d',
'SETARRAYITEM_RAW/3d',
'SETINTERIORFIELD_GC/3d',
- 'SETINTERIORFIELD_RAW/3d', # only used by llsupport/rewrite.py
'RAW_STORE/3d',
'SETFIELD_GC/2d',
'SETFIELD_RAW/2d',
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit