[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