[pypy-commit] pypy stmgc-c7: In-progress: add the %fs or %gs segment prefix in the core of

arigo noreply at buildbot.pypy.org
Sun Mar 23 13:42:49 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r70196:0a1abc01bb9f
Date: 2014-03-23 13:42 +0100
http://bitbucket.org/pypy/pypy/changeset/0a1abc01bb9f/

Log:	In-progress: add the %fs or %gs segment prefix in the core of the
	assembler production. We'll have to fix all places that use memory
	references, which is the point here because we'll need a segment
	prefix for any GC pointer, with stm.

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
@@ -49,6 +49,10 @@
 def fits_in_32bits(value):
     return -2147483648 <= value <= 2147483647
 
+SEGMENT_NO = '\x00'
+SEGMENT_FS = '\x64'
+SEGMENT_GS = '\x65'
+
 # ____________________________________________________________
 # Emit a single char
 
@@ -146,7 +150,7 @@
 # Emit a mod/rm referencing a stack location [EBP+offset]
 
 @specialize.arg(2)
-def encode_stack_bp(mc, offset, force_32bits, orbyte):
+def encode_stack_bp(mc, (segment, offset), force_32bits, orbyte):
     if not force_32bits and single_byte(offset):
         mc.writechar(chr(0x40 | orbyte | R.ebp))
         mc.writeimm8(offset)
@@ -155,8 +159,12 @@
         mc.writeimm32(offset)
     return 0
 
+def rex_stack_bp(mc, (segment, offset), _):
+    mc.write_segment_prefix(segment)
+    return 0
+
 def stack_bp(argnum, force_32bits=False):
-    return encode_stack_bp, argnum, force_32bits, None
+    return encode_stack_bp, argnum, force_32bits, rex_stack_bp
 
 # ____________________________________________________________
 # Emit a mod/rm referencing a stack location [ESP+offset]
@@ -182,7 +190,7 @@
 # ____________________________________________________________
 # Emit a mod/rm referencing a memory location [reg1+offset]
 
-def encode_mem_reg_plus_const(mc, (reg, offset), _, orbyte):
+def encode_mem_reg_plus_const(mc, (segment, reg, offset), _, orbyte):
     assert reg != R.esp and reg != R.ebp
     #
     reg1 = reg_number_3bits(mc, reg)
@@ -209,7 +217,8 @@
         mc.writeimm32(offset)
     return 0
 
-def rex_mem_reg_plus_const(mc, (reg, offset), _):
+def rex_mem_reg_plus_const(mc, (segment, reg, offset), _):
+    mc.write_segment_prefix(segment)
     if reg >= 8:
         return REX_B
     return 0
@@ -220,9 +229,8 @@
 # ____________________________________________________________
 # Emit a mod/rm referencing an array memory location [reg1+reg2*scale+offset]
 
-def encode_mem_reg_plus_scaled_reg_plus_const(mc,
-                                              (reg1, reg2, scaleshift, offset),
-                                              _, orbyte):
+def encode_mem_reg_plus_scaled_reg_plus_const(
+        mc, (segment, reg1, reg2, scaleshift, offset), _, orbyte):
     # emit "reg1 + (reg2 << scaleshift) + offset"
     assert reg1 != R.ebp and reg2 != R.esp
     assert 0 <= scaleshift < 4
@@ -262,9 +270,9 @@
         mc.writeimm32(offset)
     return 0
 
-def rex_mem_reg_plus_scaled_reg_plus_const(mc,
-                                           (reg1, reg2, scaleshift, offset),
-                                           _):
+def rex_mem_reg_plus_scaled_reg_plus_const(
+        mc, (segment, reg1, reg2, scaleshift, offset), _):
+    mc.write_segment_prefix(segment)
     rex = 0
     if reg1 >= 8: rex |= REX_B
     if reg2 >= 8: rex |= REX_X
@@ -280,7 +288,7 @@
 # with immediate(argnum)).
 
 @specialize.arg(2)
-def encode_abs(mc, immediate, _, orbyte):
+def encode_abs(mc, (segment, immediate), _, orbyte):
     # expands to either '\x05' on 32-bit, or '\x04\x25' on 64-bit
     if mc.WORD == 8:
         mc.writechar(chr(0x04 | orbyte))
@@ -291,8 +299,12 @@
     mc.writeimm32(immediate)
     return 0
 
+def rex_abs(mc, (segment, immediate), _):
+    mc.write_segment_prefix(segment)
+    return 0
+
 def abs_(argnum):
-    return encode_abs, argnum, None, None
+    return encode_abs, argnum, None, rex_abs
 
 # ____________________________________________________________
 # For 64-bits mode: the REX.W, REX.R, REX.X, REG.B prefixes
@@ -330,7 +342,7 @@
 def insn(*encoding):
     def encode(mc, *args):
         rexbyte = 0
-        if mc.WORD == 8:
+        if 1:   #mc.WORD == 8: always needed for the SEGMENT_xx prefix
             # compute the REX byte, if any
             for encode_step, arg, extra, rex_step in encoding_steps:
                 if rex_step:
@@ -465,6 +477,10 @@
         self.writechar(chr((imm >> 16) & 0xFF))
         self.writechar(chr((imm >> 24) & 0xFF))
 
+    def write_segment_prefix(self, segment):
+        if segment != SEGMENT_NO:
+            self.writechar(segment)
+
     # ------------------------------ MOV ------------------------------
 
     MOV_ri = insn(register(1), '\xB8', immediate(2))
diff --git a/rpython/jit/backend/x86/test/test_rx86.py b/rpython/jit/backend/x86/test/test_rx86.py
--- a/rpython/jit/backend/x86/test/test_rx86.py
+++ b/rpython/jit/backend/x86/test/test_rx86.py
@@ -33,51 +33,69 @@
 
 def test_mov_br():
     s = CodeBuilder32()
-    s.MOV_br(-36, edx)
+    s.MOV_br((SEGMENT_NO, -36), edx)
     assert s.getvalue() == '\x89\x55\xDC'
 
+def test_mov_br_segment():
+    s = CodeBuilder32()
+    s.MOV_br((SEGMENT_FS, -36), edx)
+    assert s.getvalue() == '\x64\x89\x55\xDC'
+
 def test_mov_rb():
     s = CodeBuilder32()
-    s.MOV_rb(edx, -36)
+    s.MOV_rb(edx, (SEGMENT_NO, -36))
     assert s.getvalue() == '\x8B\x55\xDC'
 
 def test_mov_rm():
     s = CodeBuilder32()
-    s.MOV_rm(edx, (edi, 0))
-    s.MOV_rm(edx, (edi, -128))
-    s.MOV_rm(edx, (edi, 128))
+    s.MOV_rm(edx, (SEGMENT_NO, edi, 0))
+    s.MOV_rm(edx, (SEGMENT_NO, edi, -128))
+    s.MOV_rm(edx, (SEGMENT_NO, edi, 128))
     assert s.getvalue() == '\x8B\x17\x8B\x57\x80\x8B\x97\x80\x00\x00\x00'
 
+def test_mov_rm_segment():
+    s = CodeBuilder32()
+    s.MOV_rm(edx, (SEGMENT_FS, edi, 0))
+    s.MOV_rm(edx, (SEGMENT_GS, edi, -128))
+    assert s.getvalue() == '\x64\x8B\x17\x65\x8B\x57\x80'
+
 def test_mov_mr():
     s = CodeBuilder32()
-    s.MOV_mr((edi, 0), edx)
-    s.MOV_mr((edi, -128), edx)
-    s.MOV_mr((edi, 128), edx)
+    s.MOV_mr((SEGMENT_NO, edi, 0), edx)
+    s.MOV_mr((SEGMENT_NO, edi, -128), edx)
+    s.MOV_mr((SEGMENT_NO, edi, 128), edx)
     assert s.getvalue() == '\x89\x17\x89\x57\x80\x89\x97\x80\x00\x00\x00'
 
 def test_mov_ra():
     s = CodeBuilder32()
-    s.MOV_ra(edx, (esi, edi, 2, 0))
-    s.MOV_ra(edx, (esi, edi, 2, -128))
-    s.MOV_ra(edx, (esi, edi, 2, 128))
+    s.MOV_ra(edx, (SEGMENT_NO, esi, edi, 2, 0))
+    s.MOV_ra(edx, (SEGMENT_NO, esi, edi, 2, -128))
+    s.MOV_ra(edx, (SEGMENT_NO, esi, edi, 2, 128))
     assert s.getvalue() == ('\x8B\x14\xBE' +
                             '\x8B\x54\xBE\x80' +
                             '\x8B\x94\xBE\x80\x00\x00\x00')
 
+def test_mov_ra_segment():
+    s = CodeBuilder32()
+    s.MOV_ra(edx, (SEGMENT_GS, esi, edi, 2, 0))
+    s.MOV_ra(edx, (SEGMENT_FS, esi, edi, 2, -128))
+    assert s.getvalue() == ('\x65\x8B\x14\xBE' +
+                            '\x64\x8B\x54\xBE\x80')
+
 def test_mov_ra_no_base():
     s = CodeBuilder32()
-    s.MOV_ra(edx, (NO_BASE_REGISTER, edi, 2, 0))
+    s.MOV_ra(edx, (SEGMENT_NO, NO_BASE_REGISTER, edi, 2, 0))
     assert s.getvalue() == '\x8B\x14\xBD\x00\x00\x00\x00'
 
     s = CodeBuilder32()
-    s.MOV_ra(edx, (NO_BASE_REGISTER, edi, 2, 0xCD))
+    s.MOV_ra(edx, (SEGMENT_NO, NO_BASE_REGISTER, edi, 2, 0xCD))
     assert s.getvalue() == '\x8B\x14\xBD\xCD\x00\x00\x00'
 
 def test_mov_ar():
     s = CodeBuilder32()
-    s.MOV_ar((esi, edi, 2, 0), edx)
-    s.MOV_ar((esi, edi, 2, -128), edx)
-    s.MOV_ar((esi, edi, 2, 128), edx)
+    s.MOV_ar((SEGMENT_NO, esi, edi, 2, 0), edx)
+    s.MOV_ar((SEGMENT_NO, esi, edi, 2, -128), edx)
+    s.MOV_ar((SEGMENT_NO, esi, edi, 2, 128), edx)
     assert s.getvalue() == ('\x89\x14\xBE' +
                             '\x89\x54\xBE\x80' +
                             '\x89\x94\xBE\x80\x00\x00\x00')
@@ -90,12 +108,12 @@
 
 def test_lea_rb():
     s = CodeBuilder32()
-    s.LEA_rb(ecx, -36)
+    s.LEA_rb(ecx, (SEGMENT_NO, -36))
     assert s.getvalue() == '\x8D\x4D\xDC'
 
 def test_lea32_rb():
     s = CodeBuilder32()
-    s.LEA32_rb(ecx, -36)
+    s.LEA32_rb(ecx, (SEGMENT_NO, -36))
     assert s.getvalue() == '\x8D\x8D\xDC\xFF\xFF\xFF'
 
 def test_call_l(s=None):
@@ -120,17 +138,22 @@
 
 def test_movsd_rj():
     s = CodeBuilder32()
-    s.MOVSD_xj(xmm2, 0x01234567)
+    s.MOVSD_xj(xmm2, (SEGMENT_NO, 0x01234567))
     assert s.getvalue() == '\xF2\x0F\x10\x15\x67\x45\x23\x01'
 
+def test_movsd_rj_segment():
+    s = CodeBuilder32()
+    s.MOVSD_xj(xmm2, (SEGMENT_GS, 0x01234567))
+    assert s.getvalue() == '\x65\xF2\x0F\x10\x15\x67\x45\x23\x01'
+
 def test_movzx8_rm():
     s = CodeBuilder32()
-    s.MOVZX8_rm(ecx, (eax, 16))
+    s.MOVZX8_rm(ecx, (SEGMENT_NO, eax, 16))
     assert s.getvalue() == '\x0F\xB6\x48\x10'
 
 def test_movzx16_rm():
     s = CodeBuilder32()
-    s.MOVZX16_rm(ecx, (eax, 16))
+    s.MOVZX16_rm(ecx, (SEGMENT_NO, eax, 16))
     assert s.getvalue() == '\x0F\xB7\x48\x10'
 
 def test_div():
@@ -169,17 +192,19 @@
     assert_encodes_as(CodeBuilder32, 'OR8_rr', (bl, bh), '\x08\xFB')
 
 def test_test8_mi():
-    assert_encodes_as(CodeBuilder32, 'TEST8_mi', ((edx, 16), 99),
+    assert_encodes_as(CodeBuilder32, 'TEST8_mi', ((SEGMENT_NO, edx, 16), 99),
                       '\xF6\x42\x10\x63')
 
 def test_test8_ji():
-    assert_encodes_as(CodeBuilder32, 'TEST8_ji', (0x12345678, 99),
+    assert_encodes_as(CodeBuilder32, 'TEST8_ji', ((SEGMENT_NO,0x12345678), 99),
                       '\xF6\x05\x78\x56\x34\x12\x63')
 
 def test_mov8():
     cb = CodeBuilder32
-    assert_encodes_as(cb, 'MOV8_mi', ((edx, 16), 99), '\xC6\x42\x10\x63')
-    assert_encodes_as(cb, 'MOV8_ai', ((ebx, ecx, 2, 16), 99), '\xC6\x44\x8B\x10\x63')
+    assert_encodes_as(cb, 'MOV8_mi', ((SEGMENT_NO, edx, 16), 99),
+                      '\xC6\x42\x10\x63')
+    assert_encodes_as(cb, 'MOV8_ai', ((SEGMENT_NO, ebx, ecx, 2, 16), 99),
+                      '\xC6\x44\x8B\x10\x63')
 
 def test_push32():
     cb = CodeBuilder32
@@ -188,9 +213,9 @@
 
 def test_sub_ji8():
     cb = CodeBuilder32
-    assert_encodes_as(cb, 'SUB_ji8', (11223344, 55),
-                      '\x83\x2D\x30\x41\xAB\x00\x37')
-    assert_encodes_as(cb, 'SUB_mi8', ((edx, 16), 55),
+    assert_encodes_as(cb, 'SUB_ji8', ((SEGMENT_FS, 11223344), 55),
+                      '\x64\x83\x2D\x30\x41\xAB\x00\x37')
+    assert_encodes_as(cb, 'SUB_mi8', ((SEGMENT_NO, edx, 16), 55),
                       '\x83\x6A\x10\x37')
 
 class CodeBuilder64(CodeBuilderMixin, X86_64_CodeBuilder):
@@ -215,17 +240,17 @@
 
 def test_mov_rm_64():
     s = CodeBuilder64()
-    s.MOV_rm(edx, (edi, 0))
-    s.MOV_rm(edx, (r12, 0))
-    s.MOV_rm(edx, (r13, 0))
+    s.MOV_rm(edx, (SEGMENT_NO, edi, 0))
+    s.MOV_rm(edx, (SEGMENT_NO, r12, 0))
+    s.MOV_rm(edx, (SEGMENT_NO, r13, 0))
     assert s.getvalue() == '\x48\x8B\x17\x49\x8b\x14\x24\x49\x8b\x55\x00'
 
 def test_mov_rm_negative_64():
     s = CodeBuilder64()
-    s.MOV_rm(edx, (edi, -1))
+    s.MOV_rm(edx, (SEGMENT_NO, edi, -1))
     assert s.getvalue() == '\x48\x8B\x57\xFF'
 
 def test_movsd_xj_64():
     s = CodeBuilder64()
-    s.MOVSD_xj(xmm2, 0x01234567)
+    s.MOVSD_xj(xmm2, (SEGMENT_NO, 0x01234567))
     assert s.getvalue() == '\xF2\x0F\x10\x14\x25\x67\x45\x23\x01'


More information about the pypy-commit mailing list