[pypy-svn] pypy default: Merged upstream.
alex_gaynor
commits-noreply at bitbucket.org
Fri Apr 22 03:14:11 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r43521:7f0e4cc0910a
Date: 2011-04-21 21:13 -0400
http://bitbucket.org/pypy/pypy/changeset/7f0e4cc0910a/
Log: Merged upstream.
diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py
--- a/pypy/jit/backend/x86/rx86.py
+++ b/pypy/jit/backend/x86/rx86.py
@@ -308,14 +308,17 @@
# XXX: Hack. Ignore REX.W if we are using 16-bit operands
if mc._use_16_bit_immediate:
basevalue &= ~REX_W
- if basevalue != 0x40 or rexbyte != 0:
+ if basevalue != 0 or rexbyte != 0:
+ if basevalue == 0:
+ basevalue = 0x40
mc.writechar(chr(basevalue | rexbyte))
else:
assert rexbyte == 0
return 0
-rex_w = encode_rex, 0, (0x40 | REX_W), None
-rex_nw = encode_rex, 0, 0x40, None
+rex_w = encode_rex, 0, (0x40 | REX_W), None # a REX.W prefix
+rex_nw = encode_rex, 0, 0, None # an optional REX prefix
+rex_fw = encode_rex, 0, 0x40, None # a forced REX prefix
# ____________________________________________________________
@@ -460,6 +463,7 @@
# ------------------------------ MOV ------------------------------
MOV_ri = insn(rex_w, register(1), '\xB8', immediate(2, 'q'))
+ MOV8_ri = insn(rex_fw, byte_register(1), '\xB0', immediate(2, 'b'))
# ------------------------------ Arithmetic ------------------------------
@@ -485,11 +489,11 @@
CMP32_mi = insn(rex_nw, '\x81', orbyte(7<<3), mem_reg_plus_const(1), immediate(2))
- CMP8_ri = insn(rex_nw, '\x80', byte_register(1), '\xF8', immediate(2, 'b'))
+ CMP8_ri = insn(rex_fw, '\x80', byte_register(1), '\xF8', immediate(2, 'b'))
- AND8_rr = insn(rex_w, '\x20', byte_register(1), byte_register(2,8), '\xC0')
+ AND8_rr = insn(rex_fw, '\x20', byte_register(1), byte_register(2,8), '\xC0')
- OR8_rr = insn(rex_w, '\x08', byte_register(1), byte_register(2,8), '\xC0')
+ OR8_rr = insn(rex_fw, '\x08', byte_register(1), byte_register(2,8), '\xC0')
NEG_r = insn(rex_w, '\xF7', register(1), '\xD8')
@@ -672,8 +676,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('MOV8_*r', [rex_fw, '\x88', byte_register(2, 8)], regtype='BYTE')
+define_modrm_modes('MOV8_*i', [rex_fw, '\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('MOVSX8_r*', [rex_w, '\x0F\xBE', register(1, 8)], regtype='BYTE')
diff --git a/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py b/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
--- a/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
+++ b/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
@@ -10,8 +10,9 @@
END_TAG = '<<<rx86-test-end>>>'
class CodeCheckerMixin(object):
- def __init__(self, expected):
+ def __init__(self, expected, accept_unnecessary_prefix):
self.expected = expected
+ self.accept_unnecessary_prefix = accept_unnecessary_prefix
self.index = 0
def begin(self, op):
@@ -20,6 +21,9 @@
def writechar(self, char):
if char != self.expected[self.index:self.index+1]:
+ if (char == self.accept_unnecessary_prefix
+ and self.index == self.instrindex):
+ return # ignore the extra character '\x40'
print self.op
print "\x09from rx86.py:", hexdump(self.expected[self.instrindex:self.index] + char)+"..."
print "\x09from 'as': ", hexdump(self.expected[self.instrindex:self.index+15])+"..."
@@ -43,15 +47,21 @@
TESTDIR = 'rx86_32'
X86_CodeBuilder = rx86.X86_32_CodeBuilder
REGNAMES = ['%eax', '%ecx', '%edx', '%ebx', '%esp', '%ebp', '%esi', '%edi']
+ REGNAMES8 = ['%al', '%cl', '%dl', '%bl', '%ah', '%ch', '%dh', '%bh']
XMMREGNAMES = ['%%xmm%d' % i for i in range(16)]
REGS = range(8)
+ REGS8 = [i|rx86.BYTE_REG_FLAG for i in range(8)]
NONSPECREGS = [rx86.R.eax, rx86.R.ecx, rx86.R.edx, rx86.R.ebx,
rx86.R.esi, rx86.R.edi]
+ accept_unnecessary_prefix = None
methname = '?'
def reg_tests(self):
return self.REGS
+ def reg8_tests(self):
+ return self.REGS8
+
def xmm_reg_tests(self):
return self.reg_tests()
@@ -97,12 +107,14 @@
def get_all_tests(self):
return {
'r': self.reg_tests,
+ 'r8': self.reg8_tests,
'x': self.xmm_reg_tests,
'b': self.stack_bp_tests,
's': self.stack_sp_tests,
'm': self.memory_tests,
'a': self.array_tests,
'i': self.imm32_tests,
+ 'i8': self.imm8_tests,
'j': self.imm32_tests,
'l': self.relative_tests,
}
@@ -110,6 +122,10 @@
def assembler_operand_reg(self, regnum):
return self.REGNAMES[regnum]
+ def assembler_operand_reg8(self, regnum):
+ assert regnum & rx86.BYTE_REG_FLAG
+ return self.REGNAMES8[regnum &~ rx86.BYTE_REG_FLAG]
+
def assembler_operand_xmm_reg(self, regnum):
return self.XMMREGNAMES[regnum]
@@ -137,16 +153,19 @@
def get_all_assembler_operands(self):
return {
'r': self.assembler_operand_reg,
+ 'r8': self.assembler_operand_reg8,
'x': self.assembler_operand_xmm_reg,
'b': self.assembler_operand_stack_bp,
's': self.assembler_operand_stack_sp,
'm': self.assembler_operand_memory,
'a': self.assembler_operand_array,
'i': self.assembler_operand_imm,
+ 'i8': self.assembler_operand_imm,
'j': self.assembler_operand_imm_addr,
}
- def run_test(self, methname, instrname, argmodes, args_lists):
+ def run_test(self, methname, instrname, argmodes, args_lists,
+ instr_suffix=None):
global labelcount
labelcount = 0
oplist = []
@@ -169,6 +188,9 @@
if (self.WORD == 8) and instrname.startswith('CVT'):
suffix = suffixes[self.WORD]
+ if instr_suffix is not None:
+ suffix = instr_suffix # overwrite
+
following = ""
if False: # instr.indirect:
suffix = ""
@@ -196,11 +218,22 @@
oplist.append(op)
g.write('\t.string "%s"\n' % END_TAG)
g.close()
- os.system('as --%d "%s" -o "%s"' % (self.WORD*8, inputname, filename))
+ f, g = os.popen4('as --%d "%s" -o "%s"' %
+ (self.WORD*8, inputname, filename), 'r')
+ f.close()
+ got = g.read()
+ g.close()
+ error = [line for line in got.splitlines() if 'error' in line.lower()]
+ if error:
+ raise Exception("Assembler got an error: %r" % error[0])
+ error = [line for line in got.splitlines()
+ if 'warning' in line.lower()]
+ if error:
+ raise Exception("Assembler got a warning: %r" % error[0])
try:
f = open(filename, 'rb')
except IOError:
- raise Exception("Assembler error")
+ raise Exception("Assembler did not produce output?")
data = f.read()
f.close()
i = data.find(BEGIN_TAG)
@@ -227,13 +260,20 @@
if methname in ('ADD_ri', 'AND_ri', 'CMP_ri', 'OR_ri',
'SUB_ri', 'XOR_ri', 'SBB_ri'):
if args[0] == rx86.R.eax:
- return [] # ADD EAX, constant: there is a special encoding
+ return [] # ADD EAX, constant: there is a special encoding
+ if methname in ('CMP8_ri',):
+ if args[0] == rx86.R.al:
+ return [] # CMP AL, constant: there is a special encoding
if methname == 'XCHG_rr' and rx86.R.eax in args:
return [] # special encoding
if methname == 'MOV_rj' and args[0] == rx86.R.eax:
return [] # MOV EAX, [immediate]: there is a special encoding
if methname == 'MOV_jr' and args[1] == rx86.R.eax:
return [] # MOV [immediate], EAX: there is a special encoding
+ if methname == 'MOV8_rj' and args[0] == rx86.R.al:
+ return [] # MOV AL, [immediate]: there is a special encoding
+ if methname == 'MOV8_jr' and args[1] == rx86.R.al:
+ return [] # MOV [immediate], AL: there is a special encoding
return [args]
@@ -243,7 +283,9 @@
return X86_CodeBuilder
def should_skip_instruction(self, instrname, argmodes):
- is_artificial_instruction = instrname[-1].isdigit() or (argmodes != '' and argmodes[-1].isdigit())
+ is_artificial_instruction = (argmodes != '' and argmodes[-1].isdigit())
+ is_artificial_instruction |= (instrname[-1].isdigit() and
+ instrname[-1] != '8')
return (
is_artificial_instruction or
# XXX: Can't tests shifts automatically at the moment
@@ -274,14 +316,37 @@
if methname == 'WORD':
return
+ if instrname.endswith('8'):
+ instrname = instrname[:-1]
+ if instrname == 'MOVSX' or instrname == 'MOVZX':
+ instr_suffix = 'b' + suffixes[self.WORD]
+ instrname = instrname[:-1]
+ if argmodes[1] == 'r':
+ argmodes = [argmodes[0], 'r8']
+ else:
+ instr_suffix = 'b'
+ realargmodes = []
+ for mode in argmodes:
+ if mode == 'r':
+ mode = 'r8'
+ elif mode == 'i':
+ mode = 'i8'
+ realargmodes.append(mode)
+ argmodes = realargmodes
+ elif instrname == 'CALL' or instrname == 'JMP':
+ instr_suffix = suffixes[self.WORD] + ' *'
+ else:
+ instr_suffix = None
print "Testing %s with argmodes=%r" % (instrname, argmodes)
self.methname = methname
self.is_xmm_insn = getattr(getattr(self.X86_CodeBuilder,
methname), 'is_xmm_insn', False)
ilist = self.make_all_tests(methname, argmodes)
- oplist, as_code = self.run_test(methname, instrname, argmodes, ilist)
- cc = self.get_code_checker_class()(as_code)
+ oplist, as_code = self.run_test(methname, instrname, argmodes, ilist,
+ instr_suffix)
+ cls = self.get_code_checker_class()
+ cc = cls(as_code, self.accept_unnecessary_prefix)
for op, args in zip(oplist, ilist):
if op:
cc.begin(op)
diff --git a/pypy/jit/backend/x86/test/test_rx86_64_auto_encoding.py b/pypy/jit/backend/x86/test/test_rx86_64_auto_encoding.py
--- a/pypy/jit/backend/x86/test/test_rx86_64_auto_encoding.py
+++ b/pypy/jit/backend/x86/test/test_rx86_64_auto_encoding.py
@@ -9,11 +9,16 @@
X86_CodeBuilder = rx86.X86_64_CodeBuilder
REGNAMES = ['%rax', '%rcx', '%rdx', '%rbx', '%rsp', '%rbp', '%rsi', '%rdi',
'%r8', '%r9', '%r10', '%r11', '%r12', '%r13', '%r14', '%r15']
+ REGNAMES8 = ['%al', '%cl', '%dl', '%bl', '%spl', '%bpl', '%sil', '%dil',
+ '%r8b', '%r9b', '%r10b', '%r11b',
+ '%r12b', '%r13b', '%r14b', '%r15b']
REGS = range(16)
+ REGS8 = [i|rx86.BYTE_REG_FLAG for i in range(16)]
NONSPECREGS = [rx86.R.eax, rx86.R.ecx, rx86.R.edx, rx86.R.ebx,
rx86.R.esi, rx86.R.edi,
rx86.R.r8, rx86.R.r9, rx86.R.r10, rx86.R.r11,
rx86.R.r12, rx86.R.r13, rx86.R.r14, rx86.R.r15]
+ accept_unnecessary_prefix = '\x40'
def should_skip_instruction(self, instrname, argmodes):
return (
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -1051,36 +1051,38 @@
documentation/website files in your local checkout
---------------------------------------------------
-Most of the PyPy's documentation and website is kept in
-`pypy/documentation` and `pypy/documentation/website` respectively.
-You can simply edit or add '.txt' files which contain ReST-markuped
+Most of the PyPy's documentation is kept in `pypy/doc`.
+You can simply edit or add '.rst' files which contain ReST-markuped
files. Here is a `ReST quickstart`_ but you can also just look
at the existing documentation and see how things work.
.. _`ReST quickstart`: http://docutils.sourceforge.net/docs/rst/quickref.html
+Note that the web site of http://pypy.org/ is maintained separately.
+For now it is in the repository https://bitbucket.org/pypy/extradoc
+in the directory ``pypy.org``.
+
Automatically test documentation/website changes
------------------------------------------------
-.. _`docutils home page`:
-.. _`docutils`: http://docutils.sourceforge.net/
+.. _`sphinx home page`:
+.. _`sphinx`: http://sphinx.pocoo.org/
We automatically check referential integrity and ReST-conformance. In order to
-run the tests you need docutils_ installed. Then go to the local checkout
-of the documentation directory and run the tests::
+run the tests you need sphinx_ installed. Then go to the local checkout
+of the documentation directory and run the Makefile::
- cd .../pypy/documentation
- python ../test_all.py
+ cd pypy/doc
+ make html
If you see no failures chances are high that your modifications at least
-don't produce ReST-errors or wrong local references. A side effect of running
-the tests is that you have `.html` files in the documentation directory
-which you can point your browser to!
+don't produce ReST-errors or wrong local references. Now you will have `.html`
+files in the documentation directory which you can point your browser to!
Additionally, if you also want to check for remote references inside
the documentation issue::
- python ../test_all.py --checkremote
+ make linkcheck
which will check that remote URLs are reachable.
More information about the Pypy-commit
mailing list