[pypy-svn] r75400 - pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86
jcreigh at codespeak.net
jcreigh at codespeak.net
Mon Jun 14 22:37:16 CEST 2010
Author: jcreigh
Date: Mon Jun 14 22:37:13 2010
New Revision: 75400
Modified:
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/rx86.py
Log:
add a helper to x86 to define the common mod/rm modes to help avoid boilerplate code when defining instructions
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/rx86.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/rx86.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/rx86.py Mon Jun 14 22:37:13 2010
@@ -420,48 +420,6 @@
# ------------------------------ MOV ------------------------------
MOV_ri = insn(rex_w, register(1), '\xB8', immediate(2, 'q'))
- MOV_rr = insn(rex_w, '\x89', register(2,8), register(1), '\xC0')
- MOV_bi = insn(rex_w, '\xC7', stack_bp(1), immediate(2))
- MOV_br = insn(rex_w, '\x89', register(2,8), stack_bp(1))
- MOV_rb = insn(rex_w, '\x8B', register(1,8), stack_bp(2))
- MOV_sr = insn(rex_w, '\x89', register(2,8), stack_sp(1))
- MOV_rs = insn(rex_w, '\x8B', register(1,8), stack_sp(2))
-
- # "MOV reg1, [reg2+offset]" and the opposite direction
- MOV_rm = insn(rex_w, '\x8B', register(1,8), mem_reg_plus_const(2))
- MOV_mr = insn(rex_w, '\x89', register(2,8), mem_reg_plus_const(1))
- MOV_mi = insn(rex_w, '\xC7', orbyte(0<<3), mem_reg_plus_const(1),
- immediate(2, 'i'))
-
- # "MOV reg1, [reg2+reg3*scale+offset]" and the opposite direction
- MOV_ra = insn(rex_w, '\x8B', register(1,8),
- mem_reg_plus_scaled_reg_plus_const(2))
- MOV_ar = insn(rex_w, '\x89', register(2,8),
- mem_reg_plus_scaled_reg_plus_const(1))
- MOV_ai = insn(rex_w, '\xC7', orbyte(0<<3), mem_reg_plus_scaled_reg_plus_const(1), immediate(2))
-
-
- MOV8_mr = insn(rex_w, '\x88', byte_register(2, 8), mem_reg_plus_const(1))
- MOV8_ar = insn(rex_w, '\x88', byte_register(2, 8), mem_reg_plus_scaled_reg_plus_const(1))
- MOV8_mi = insn(rex_w, '\xC6', orbyte(0<<3), mem_reg_plus_const(1), immediate(2, 'b'))
- MOV8_ai = insn(rex_w, '\xC6', orbyte(0<<3), mem_reg_plus_scaled_reg_plus_const(1), immediate(2, 'b'))
-
- MOVZX8_rr = insn(rex_w, '\x0F\xB6', register(1,8), byte_register(2), '\xC0')
- MOVZX8_rm = insn(rex_w, '\x0F\xB6', register(1,8), mem_reg_plus_const(2))
- MOVZX8_ra = insn(rex_w, '\x0F\xB6', register(1,8), mem_reg_plus_scaled_reg_plus_const(2))
-
- MOVZX16_rm = insn(rex_w, '\x0F\xB7', register(1,8), mem_reg_plus_const(2))
- MOVZX16_ra = insn(rex_w, '\x0F\xB7', register(1,8), mem_reg_plus_scaled_reg_plus_const(2))
-
- # FIXME: Only difference between MOV32 and MOV instructions is rex_nw instead of rex_w
- MOV32_ra = insn(rex_nw, '\x8B', register(1,8),
- mem_reg_plus_scaled_reg_plus_const(2))
- MOV32_ar = insn(rex_nw, '\x89', register(2,8),
- mem_reg_plus_scaled_reg_plus_const(1))
- MOV32_rm = insn(rex_nw, '\x8B', register(1,8), mem_reg_plus_const(2))
- MOV32_mr = insn(rex_nw, '\x89', register(2,8), mem_reg_plus_const(1))
- MOV32_mi = insn(rex_nw, '\xC7', orbyte(0<<3), mem_reg_plus_const(1),
- immediate(2, 'i'))
# ------------------------------ Arithmetic ------------------------------
@@ -524,7 +482,9 @@
CALL_r = insn(rex_nw, '\xFF', register(1), chr(0xC0 | (2<<3)))
CALL_b = insn('\xFF', orbyte(2<<3), stack_bp(1))
- XCHG_rm = insn(rex_w, '\x87', register(1,8), mem_reg_plus_const(2))
+ # XXX: Only here for testing purposes..."as" happens the encode the
+ # registers in the opposite order that we would otherwise do in a
+ # register-register exchange
XCHG_rr = insn(rex_w, '\x87', register(1), register(2,8), '\xC0')
JMP_l = insn('\xE9', relative(1))
@@ -548,42 +508,6 @@
# ------------------------------ SSE2 ------------------------------
- MOVSD_xx = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), register(2),
- '\xC0')
- MOVSD_xb = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), stack_bp(2))
- MOVSD_bx = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2,8), stack_bp(1))
- MOVSD_xs = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), stack_sp(2))
- MOVSD_sx = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2,8), stack_sp(1))
- MOVSD_xm = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8),
- mem_reg_plus_const(2))
- MOVSD_xa = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), mem_reg_plus_scaled_reg_plus_const(2))
- MOVSD_mx = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2,8),
- mem_reg_plus_const(1))
- MOVSD_ax = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2,8), mem_reg_plus_scaled_reg_plus_const(1))
-
-
- # Arithmetic
- ADDSD_xx = xmminsn('\xF2', rex_nw, '\x0F\x58', register(1, 8), register(2), '\xC0')
- ADDSD_xb = xmminsn('\xF2', rex_nw, '\x0F\x58', register(1, 8), stack_bp(2))
- ADDSD_xm = xmminsn('\xF2', rex_nw, '\x0F\x58', register(1, 8), mem_reg_plus_const(2))
-
- SUBSD_xx = xmminsn('\xF2', rex_nw, '\x0F\x5C', register(1, 8), register(2), '\xC0')
- SUBSD_xb = xmminsn('\xF2', rex_nw, '\x0F\x5C', register(1, 8), stack_bp(2))
- SUBSD_xm = xmminsn('\xF2', rex_nw, '\x0F\x5C', register(1, 8), mem_reg_plus_const(2))
-
- MULSD_xx = xmminsn('\xF2', rex_nw, '\x0F\x59', register(1, 8), register(2), '\xC0')
- MULSD_xb = xmminsn('\xF2', rex_nw, '\x0F\x59', register(1, 8), stack_bp(2))
- MULSD_xm = xmminsn('\xF2', rex_nw, '\x0F\x59', register(1, 8), mem_reg_plus_const(2))
-
- DIVSD_xx = xmminsn('\xF2', rex_nw, '\x0F\x5E', register(1, 8), register(2), '\xC0')
- DIVSD_xb = xmminsn('\xF2', rex_nw, '\x0F\x5E', register(1, 8), stack_bp(2))
- DIVSD_xm = xmminsn('\xF2', rex_nw, '\x0F\x5E', register(1, 8), mem_reg_plus_const(2))
-
- # Comparision
- UCOMISD_xx = xmminsn('\x66', rex_nw, '\x0F\x2E', register(1, 8), register(2), '\xC0')
- UCOMISD_xb = xmminsn('\x66', rex_nw, '\x0F\x2E', register(1, 8), stack_bp(2))
- UCOMISD_xm = xmminsn('\x66', rex_nw, '\x0F\x2E', register(1, 8), mem_reg_plus_const(2))
-
# Conversion
CVTSI2SD_xr = xmminsn('\xF2', rex_w, '\x0F\x2A', register(1, 8), register(2), '\xC0')
CVTSI2SD_xb = xmminsn('\xF2', rex_w, '\x0F\x2A', register(1, 8), stack_bp(2))
@@ -591,13 +515,6 @@
CVTTSD2SI_rx = xmminsn('\xF2', rex_w, '\x0F\x2C', register(1, 8), register(2), '\xC0')
CVTTSD2SI_rb = xmminsn('\xF2', rex_w, '\x0F\x2C', register(1, 8), stack_bp(2))
- # Bitwise
-
- XORPD_xx = xmminsn('\x66', rex_nw, '\x0F\x57', register(1, 8), register(2), '\xC0')
- XORPD_xm = xmminsn('\x66', rex_nw, '\x0F\x57', register(1, 8), mem_reg_plus_const(2))
-
- ANDPD_xm = xmminsn('\x66', rex_nw, '\x0F\x54', register(1, 8), mem_reg_plus_const(2))
-
# ------------------------------------------------------------
Conditions = {
@@ -623,14 +540,6 @@
class X86_32_CodeBuilder(AbstractX86CodeBuilder):
WORD = 4
- # We can do direct memory references on 32-bit
- MOV_rj = insn(rex_w, '\x8B', register(1,8), '\x05', immediate(2))
- MOV_jr = insn(rex_w, '\x89', register(2,8), '\x05', immediate(1))
- MOV_ji = insn(rex_w, '\xC7', '\x05', immediate(1), immediate(2))
- MOV8_ji = insn(rex_w, '\xC6', orbyte(0<<3), '\x05', immediate(1), immediate(2, 'b'))
- MOV8_jr = insn(rex_w, '\x88', byte_register(2, 8), '\x05', immediate(1))
- MOVZX8_rj = insn(rex_w, '\x0F\xB6', register(1,8), '\x05', immediate(2))
-
CMP_ji8 = insn(rex_w, '\x83', '\x3D', immediate(1), immediate(2, 'b'))
CMP_ji32 = insn(rex_w, '\x81', '\x3D', immediate(1), immediate(2))
CMP_ji = select_8_or_32_bit_immed(CMP_ji8, CMP_ji32)
@@ -640,18 +549,6 @@
# displacement is always enough to encode any address
CALL_j = AbstractX86CodeBuilder.CALL_l
- XCHG_rj = insn(rex_w, '\x87', register(1,8), '\x05', immediate(2))
-
- MOVSD_xj = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1, 8), '\x05', immediate(2))
- MOVSD_jx = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2, 8), '\x05', immediate(1))
- ADDSD_xj = xmminsn('\xF2', rex_nw, '\x0F\x58', register(1, 8), '\x05', immediate(2))
- SUBSD_xj = xmminsn('\xF2', rex_nw, '\x0F\x5C', register(1, 8), '\x05', immediate(2))
- MULSD_xj = xmminsn('\xF2', rex_nw, '\x0F\x59', register(1, 8), '\x05', immediate(2))
- DIVSD_xj = xmminsn('\xF2', rex_nw, '\x0F\x5E', register(1, 8), '\x05', immediate(2))
- UCOMISD_xj = xmminsn('\x66', rex_nw, '\x0F\x2E', register(1, 8), '\x05', immediate(2))
- ANDPD_xj = xmminsn('\x66', rex_nw, '\x0F\x54', register(1, 8), '\x05', immediate(2))
- XORPD_xj = xmminsn('\x66', rex_nw, '\x0F\x57', register(1, 8), '\x05', immediate(2))
-
class X86_64_CodeBuilder(AbstractX86CodeBuilder):
WORD = 8
@@ -691,6 +588,64 @@
# XXX
CALL_j = CALL_l
+def define_modrm_modes(insnname_template, before_modrm, after_modrm=[], regtype='GPR'):
+ def add_insn(code, *modrm):
+ args = before_modrm + list(modrm) + after_modrm
+ methname = insnname_template.replace('*', code)
+ if methname.endswith('_rr') or methname.endswith('_xx'):
+ args.append('\xC0')
+
+ if regtype == 'XMM':
+ insn_func = xmminsn(*args)
+ else:
+ insn_func = insn(*args)
+
+ if not hasattr(AbstractX86CodeBuilder, methname):
+ setattr(AbstractX86CodeBuilder, methname, insn_func)
+
+ modrm_argnum = insnname_template.split('_')[1].index('*')+1
+
+ if regtype == 'GPR':
+ add_insn('r', register(modrm_argnum))
+ elif regtype == 'BYTE':
+ add_insn('r', byte_register(modrm_argnum))
+ elif regtype == 'XMM':
+ add_insn('x', register(modrm_argnum))
+ else:
+ raise AssertionError("Invalid type")
+
+ add_insn('b', stack_bp(modrm_argnum))
+ add_insn('s', stack_sp(modrm_argnum))
+ add_insn('m', mem_reg_plus_const(modrm_argnum))
+ add_insn('a', mem_reg_plus_scaled_reg_plus_const(modrm_argnum))
+ add_insn('j', '\x05', immediate(modrm_argnum))
+
+# Define a regular MOV, and a variant MOV32 that only uses the low 4 bytes of a
+# register
+for insnname, rex_type in [('MOV', rex_w), ('MOV32', rex_nw)]:
+ define_modrm_modes(insnname + '_*r', [rex_type, '\x89', register(2, 8)])
+ define_modrm_modes(insnname + '_r*', [rex_type, '\x8B', register(1, 8)])
+ define_modrm_modes(insnname + '_*i', [rex_type, '\xC7', orbyte(0<<3)], [immediate(2)])
+
+define_modrm_modes('MOV8_*r', [rex_w, '\x88', byte_register(2, 8)], regtype='BYTE')
+define_modrm_modes('MOV8_*i', [rex_w, '\xC6', orbyte(0<<3)], [immediate(2, 'b')], regtype='BYTE')
+
+define_modrm_modes('MOVZX8_r*', [rex_w, '\x0F\xB6', register(1, 8)], regtype='BYTE')
+define_modrm_modes('MOVZX16_r*', [rex_w, '\x0F\xB7', register(1, 8)])
+
+define_modrm_modes('MOVSD_x*', ['\xF2', rex_nw, '\x0F\x10', register(1,8)], regtype='XMM')
+define_modrm_modes('MOVSD_*x', ['\xF2', rex_nw, '\x0F\x11', register(2,8)], regtype='XMM')
+
+define_modrm_modes('XCHG_r*', [rex_w, '\x87', register(1, 8)])
+
+define_modrm_modes('ADDSD_x*', ['\xF2', rex_nw, '\x0F\x58', register(1, 8)], regtype='XMM')
+define_modrm_modes('SUBSD_x*', ['\xF2', rex_nw, '\x0F\x5C', register(1, 8)], regtype='XMM')
+define_modrm_modes('MULSD_x*', ['\xF2', rex_nw, '\x0F\x59', register(1, 8)], regtype='XMM')
+define_modrm_modes('DIVSD_x*', ['\xF2', rex_nw, '\x0F\x5E', register(1, 8)], regtype='XMM')
+define_modrm_modes('UCOMISD_x*', ['\x66', rex_nw, '\x0F\x2E', register(1, 8)], regtype='XMM')
+define_modrm_modes('XORPD_x*', ['\x66', rex_nw, '\x0F\x57', register(1, 8)], regtype='XMM')
+define_modrm_modes('ANDPD_x*', ['\x66', rex_nw, '\x0F\x54', register(1, 8)], regtype='XMM')
+
# ____________________________________________________________
# FIXME: What about 32-bit only or 64-bit only instructions?
More information about the Pypy-commit
mailing list