Author: Armin Rigo <[email protected]>
Branch: jit-constptr-2
Changeset: r83491:fd234418525e
Date: 2016-04-01 16:14 +0200
http://bitbucket.org/pypy/pypy/changeset/fd234418525e/

Log:    x86-32 support

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
@@ -4,7 +4,7 @@
 
 from rpython.jit.backend.llsupport import symbolic, jitframe, rewrite, 
gcreftracer
 from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler,
-                                                DEBUG_COUNTER, debug_bridge)
+                                                DEBUG_COUNTER)
 from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.metainterp.history import (Const, VOID, ConstInt)
@@ -523,10 +523,10 @@
             looptoken.number, loopname,
             r_uint(rawstart + looppos),
             r_uint(rawstart + size_excluding_failure_stuff),
-            r_uint(rawstart)))
-        debug_print("       gc table: 0x%x" % r_uint(rawstart))
+            r_uint(rawstart + functionpos)))
+        debug_print("       gc table: 0x%x" % r_uint(self.gc_table_addr))
         debug_print("       function: 0x%x" % r_uint(rawstart + functionpos))
-        debug_print("           loop: 0x%x" % r_uint(rawstart + looppos))
+        debug_print("         resops: 0x%x" % r_uint(rawstart + looppos))
         debug_print("       failures: 0x%x" % r_uint(rawstart +
                                                  size_excluding_failure_stuff))
         debug_print("            end: 0x%x" % r_uint(rawstart + full_size))
@@ -591,7 +591,16 @@
         self.patch_gcref_table(original_loop_token, rawstart)
         self.patch_stack_checks(frame_depth_no_fixed_size + 
JITFRAME_FIXED_SIZE,
                                 rawstart)
-        debug_bridge(descr_number, rawstart, codeendpos)
+        debug_start("jit-backend-addr")
+        debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" %
+                    (r_uint(descr_number), r_uint(rawstart + startpos),
+                        r_uint(rawstart + codeendpos)))
+        debug_print("       gc table: 0x%x" % r_uint(self.gc_table_addr))
+        debug_print("    jump target: 0x%x" % r_uint(rawstart + startpos))
+        debug_print("         resops: 0x%x" % r_uint(rawstart + 
bridgestartpos))
+        debug_print("       failures: 0x%x" % r_uint(rawstart + codeendpos))
+        debug_print("            end: 0x%x" % r_uint(rawstart + fullsize))
+        debug_stop("jit-backend-addr")
         self.patch_pending_failure_recoveries(rawstart)
         # patch the jump from original guard
         self.patch_jump_for_descr(faildescr, rawstart + startpos)
@@ -667,18 +676,32 @@
         self.patch_jump_for_descr(faildescr, rawstart)
 
     def reserve_gcref_table(self, allgcrefs):
-        assert IS_X86_64, "XXX"
         gcref_table_size = len(allgcrefs) * WORD
-        # align to a multiple of 16
-        gcref_table_size = (gcref_table_size + 15) & ~15
-        mc = self.mc
-        assert mc.get_relative_pos() == 0
-        for i in range(gcref_table_size):
-            mc.writechar('\x00')
+        if IS_X86_64:
+            # align to a multiple of 16 and reserve space at the beginning
+            # of the machine code for the gc table.  This lets us write
+            # machine code with relative addressing (%rip - constant).
+            gcref_table_size = (gcref_table_size + 15) & ~15
+            mc = self.mc
+            assert mc.get_relative_pos() == 0
+            for i in range(gcref_table_size):
+                mc.writechar('\x00')
+        elif IS_X86_32:
+            # allocate the gc table right now.  This lets us write
+            # machine code with absolute 32-bit addressing.
+            self.gc_table_addr = self.datablockwrapper.malloc_aligned(
+                gcref_table_size, alignment=WORD)
+        #
         self.setup_gcrefs_list(allgcrefs)
 
     def patch_gcref_table(self, looptoken, rawstart):
-        assert IS_X86_64, "XXX"
+        if IS_X86_64:
+            # the gc table is at the start of the machine code
+            self.gc_table_addr = rawstart
+        elif IS_X86_32:
+            # the gc table was already allocated by reserve_gcref_table()
+            rawstart = self.gc_table_addr
+        #
         tracer = gcreftracer.make_gcref_tracer(rawstart, self._allgcrefs)
         gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken)
         gcreftracers.append(tracer)    # keepalive
@@ -1396,18 +1419,27 @@
 
     def _patch_load_from_gc_table(self, index):
         # must be called immediately after a "p"-mode instruction
-        # has been emitted
+        # has been emitted.  64-bit mode only.
+        assert IS_X86_64
         address_in_buffer = index * WORD   # at the start of the buffer
         p_location = self.mc.get_relative_pos()
         offset = address_in_buffer - p_location
         self.mc.overwrite32(p_location-4, offset)
 
+    def _addr_from_gc_table(self, index):
+        # get the address of the gc table entry 'index'.  32-bit mode only.
+        assert IS_X86_32
+        return self.gc_table_addr + index * WORD
+
     def genop_load_from_gc_table(self, op, arglocs, resloc):
         [loc] = arglocs
         assert isinstance(loc, ImmedLoc)
         assert isinstance(resloc, RegLoc)
-        self.mc.MOV_rp(resloc.value, 0)    # %rip-relative
-        self._patch_load_from_gc_table(loc.value)
+        if IS_X86_64:
+            self.mc.MOV_rp(resloc.value, 0)    # %rip-relative
+            self._patch_load_from_gc_table(loc.value)
+        elif IS_X86_32:
+            self.mc.MOV_rj(resloc.value, self._addr_from_gc_table(loc.value))
 
     def genop_int_force_ge_zero(self, op, arglocs, resloc):
         self.mc.TEST(arglocs[0], arglocs[0])
@@ -1905,8 +1937,11 @@
                              guardtok.faildescr, regalloc)
         #
         faildescrindex, target = self.store_info_on_descr(startpos, guardtok)
-        self.mc.PUSH_p(0)     # %rip-relative
-        self._patch_load_from_gc_table(faildescrindex)
+        if IS_X86_64:
+            self.mc.PUSH_p(0)     # %rip-relative
+            self._patch_load_from_gc_table(faildescrindex)
+        elif IS_X86_32:
+            self.mc.PUSH_j(self._addr_from_gc_table(faildescrindex))
         self.push_gcmap(self.mc, guardtok.gcmap, push=True)
         self.mc.JMP(imm(target))
         return startpos
@@ -2021,8 +2056,11 @@
         
         descr = op.getdescr()
         faildescrindex = self.get_gcref_from_faildescr(descr)
-        self.mc.MOV_rp(eax.value, 0)
-        self._patch_load_from_gc_table(faildescrindex)
+        if IS_X86_64:
+            self.mc.MOV_rp(eax.value, 0)
+            self._patch_load_from_gc_table(faildescrindex)
+        elif IS_X86_32:
+            self.mc.MOV_rj(eax.value, self._addr_from_gc_table(faildescrindex))
         self.mov(eax, RawEbpLoc(ofs))
 
         arglist = op.getarglist()
@@ -2095,11 +2133,15 @@
         faildescr = guard_op.getdescr()
         ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr')
 
-        assert IS_X86_64, "XXX uses the scratch reg"
         faildescrindex = self.get_gcref_from_faildescr(faildescr)
-        self.mc.MOV_rp(X86_64_SCRATCH_REG.value, 0)
-        self._patch_load_from_gc_table(faildescrindex)
-        self.mc.MOV(raw_stack(ofs), X86_64_SCRATCH_REG)
+        if IS_X86_64:
+            self.mc.MOV_rp(X86_64_SCRATCH_REG.value, 0)
+            self._patch_load_from_gc_table(faildescrindex)
+            self.mc.MOV(raw_stack(ofs), X86_64_SCRATCH_REG)
+        elif IS_X86_32:
+            # XXX need a scratch reg here for efficiency; be more clever
+            self.mc.PUSH_j(self._addr_from_gc_table(faildescrindex))
+            self.mc.POP(raw_stack(ofs))
 
     def _find_nearby_operation(self, delta):
         regalloc = self._regalloc
diff --git a/rpython/jit/backend/x86/rx86.py b/rpython/jit/backend/x86/rx86.py
--- a/rpython/jit/backend/x86/rx86.py
+++ b/rpython/jit/backend/x86/rx86.py
@@ -600,6 +600,7 @@
     PUS1_r = insn(rex_nw, register(1), '\x50')
     PUS1_b = insn(rex_nw, '\xFF', orbyte(6<<3), stack_bp(1))
     PUS1_m = insn(rex_nw, '\xFF', orbyte(6<<3), mem_reg_plus_const(1))
+    PUS1_j = insn(rex_nw, '\xFF', orbyte(6<<3), abs_(1))
     PUS1_p = insn(rex_nw, '\xFF', orbyte(6<<3), rip_offset(1))
     PUS1_i8 = insn('\x6A', immediate(1, 'b'))
     PUS1_i32 = insn('\x68', immediate(1, 'i'))
@@ -623,6 +624,10 @@
             self.PUS1_i32(immed)
         self.stack_frame_size_delta(+self.WORD)
 
+    def PUSH_j(self, abs_addr):
+        self.PUS1_j(abs_addr)
+        self.stack_frame_size_delta(+self.WORD)
+
     def PUSH_p(self, rip_offset):
         self.PUS1_p(rip_offset)
         self.stack_frame_size_delta(+self.WORD)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to