[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