Armin Rigo avatar Armin Rigo committed d3a468a

Finish the fixes. If I'm correct, I didn't actually made any fix
here, but just fixed the non-standardness of the encoding.
(However, I did change rx86.py in the branch 32ptr-on-64bit,
and there I introduced indirectly a bug.)

Comments (0)

Files changed (3)

pypy/jit/backend/x86/rx86.py

         # 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
 
 # ____________________________________________________________
 
     # ------------------------------ MOV ------------------------------
 
     MOV_ri = insn(rex_w, register(1), '\xB8', immediate(2, 'q'))
-    MOV8_ri = insn(rex_w, byte_register(1), '\xB0', immediate(2, 'b'))
+    MOV8_ri = insn(rex_fw, byte_register(1), '\xB0', immediate(2, 'b'))
 
     # ------------------------------ Arithmetic ------------------------------
 
 
     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')
 
     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')

pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py

 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):
 
     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])+"..."
     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):
         ilist = self.make_all_tests(methname, argmodes)
         oplist, as_code = self.run_test(methname, instrname, argmodes, ilist,
                                         instr_suffix)
-        cc = self.get_code_checker_class()(as_code)
+        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)

pypy/jit/backend/x86/test/test_rx86_64_auto_encoding.py

                    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 (
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.