[pypy-svn] r67904 - pypy/branch/remove-ri386-multimethod/pypy/jit/backend/x86

arigo at codespeak.net arigo at codespeak.net
Sat Sep 26 11:10:48 CEST 2009


Author: arigo
Date: Sat Sep 26 11:10:48 2009
New Revision: 67904

Modified:
   pypy/branch/remove-ri386-multimethod/pypy/jit/backend/x86/ri386.py
Log:
Revert r67902 and simplify stuff a little bit.


Modified: pypy/branch/remove-ri386-multimethod/pypy/jit/backend/x86/ri386.py
==============================================================================
--- pypy/branch/remove-ri386-multimethod/pypy/jit/backend/x86/ri386.py	(original)
+++ pypy/branch/remove-ri386-multimethod/pypy/jit/backend/x86/ri386.py	Sat Sep 26 11:10:48 2009
@@ -14,58 +14,54 @@
 esi = 6
 edi = 7
 
+# ____________________________________________________________
+# Emit a single char
 
-class CodeStepWriter(object):
-    def encode(self, mc, args, orbyte):
-        mc.writechar(chr(self.encode_byte(args) | orbyte))
-    def _freeze_(self):
-        return True
-    def __or__(self, other):
-        if isinstance(other, int):
-            other = Constant(other)
-        if hasattr(self, 'encode_byte'):
-            return Compose(self, other)
-        if hasattr(other, 'encode_byte'):
-            return Compose(other, self)
-        return NotImplemented
-    __ror__ = __or__
-
-class Constant(CodeStepWriter):
-    def __init__(self, charvalue):
-        self.charvalue = charvalue
-    def encode_byte(self, args):
-        return self.charvalue
-
-class Compose(CodeStepWriter):
-    def __init__(self, operand1, operand2):
-        self.operand1 = operand1
-        self.operand2 = operand2
-    def encode(self, mc, args, orbyte):
-        orbyte |= self.operand1.encode_byte(args)
-        self.operand2.encode(mc, args, orbyte)
-
-class register(CodeStepWriter):
-    def __init__(self, argnum, shift=0):
-        self.argnum = argnum
-        self.shift = shift
-    def __lshift__(self, num):
-        return register(self.argnum, self.shift + num)
-    def encode_byte(self, args):
-        reg = args[self.argnum-1]
-        assert 0 <= reg < 8
-        return reg << self.shift
-
-class imm32(CodeStepWriter):
-    def __init__(self, argnum):
-        self.argnum = argnum
-    def encode(self, mc, args, orbyte):
-        assert orbyte == 0
-        imm = args[self.argnum-1]
-        mc.writechar(chr(imm & 0xFF))
-        mc.writechar(chr((imm >> 8) & 0xFF))
-        mc.writechar(chr((imm >> 16) & 0xFF))
-        mc.writechar(chr((imm >> 24) & 0xFF))
+def encode_char(mc, _, char, orbyte):
+    mc.writechar(chr(char | orbyte))
+    return 0
+
+# ____________________________________________________________
+# Encode a register number in the orbyte
+
+ at specialize.arg(2)
+def encode_register(mc, arg, factor, orbyte):
+    assert 0 <= arg < 8
+    return orbyte | (arg * factor)
 
+def register(argnum, factor=1):
+    return encode_register, argnum, factor
+
+# ____________________________________________________________
+# Encode a constant in the orbyte
+
+def encode_orbyte(mc, _, constant, orbyte):
+    return orbyte | constant
+
+def orbyte(value):
+    return encode_orbyte, None, value
+
+# ____________________________________________________________
+# Emit an immediate value
+
+ at specialize.arg(2)
+def encode_immediate(mc, arg, width, orbyte):
+    assert orbyte == 0
+    if width == 'b':
+        mc.writeimm8(arg)
+    elif width == 'h':
+        mc.writeimm16(arg)
+    else:
+        mc.writeimm32(arg)
+    return 0
+
+def immediate(argnum, width='i'):
+    return encode_immediate, argnum, width
+
+# ____________________________________________________________
+# Emit a mod/rm referencing a stack location
+# This depends on the fact that our function prologue contains
+# exactly 4 PUSHes.
 
 def get_ebp_ofs(position):
     # Argument is a stack position (0, 1, 2...).
@@ -77,36 +73,38 @@
 def single_byte(value):
     return -128 <= value < 128
 
-class stack(CodeStepWriter):
-    def __init__(self, argnum, allow_single_byte=True):
-        self.argnum = argnum
-        self.allow_single_byte = allow_single_byte
-    def encode(self, mc, args, orbyte):
-        offset = get_ebp_ofs(args[self.argnum-1])
-        if self.allow_single_byte and single_byte(offset):
-            mc.writechar(chr(0x40 | ebp | orbyte))
-            mc.writechar(chr(offset & 0xFF))
-        else:
-            mc.writechar(chr(0x80 | ebp | orbyte))
-            mc.writechar(chr(offset & 0xFF))
-            mc.writechar(chr((offset >> 8) & 0xFF))
-            mc.writechar(chr((offset >> 16) & 0xFF))
-            mc.writechar(chr((offset >> 24) & 0xFF))
+ at specialize.arg(2)
+def encode_stack(mc, arg, allow_single_byte, orbyte):
+    offset = get_ebp_ofs(arg)
+    if allow_single_byte and single_byte(offset):
+        mc.writechar(chr(0x40 | ebp | orbyte))
+        mc.writeimm8(offset)
+    else:
+        mc.writechar(chr(0x80 | ebp | orbyte))
+        mc.writeimm32(offset)
+    return 0
+
+def stack(argnum, allow_single_byte=True):
+    return encode_stack, argnum, allow_single_byte
 
 # ____________________________________________________________
 
 def insn(*encoding):
     def encode(mc, *args):
-        for step in encoding_steps:
-            step.encode(mc, args, 0)
+        orbyte = 0
+        for encode_step, arg, extra in encoding_steps:
+            if arg is not None:
+                arg = args[arg-1]
+            orbyte = encode_step(mc, arg, extra, orbyte)
+        assert orbyte == 0
     #
     encoding_steps = []
     for step in encoding:
         if isinstance(step, str):
             for c in step:
-                encoding_steps.append(Constant(ord(c)))
+                encoding_steps.append((encode_char, None, ord(c)))
         else:
-            assert isinstance(step, CodeStepWriter)
+            assert type(step) is tuple and len(step) == 3
             encoding_steps.append(step)
     encoding_steps = unrolling_iterable(encoding_steps)
     return encode
@@ -120,12 +118,25 @@
     def writechar(self, char):
         raise NotImplementedError
 
-    MOV_ri = insn(0xB8 | register(1), imm32(2))
-    MOV_si = insn('\xC7', 0<<3 | stack(1), imm32(2))
-    MOV_rr = insn('\x89', 0xC0 | register(2)<<3 | register(1))
-    MOV_sr = insn('\x89', stack(1) | register(2)<<3)
-    MOV_rs = insn('\x8B', register(1)<<3 | stack(2))
+    def writeimm8(self, imm):
+        self.writechar(chr(imm & 0xFF))
+
+    def writeimm16(self, imm):
+        self.writechar(chr(imm & 0xFF))
+        self.writechar(chr((imm >> 8) & 0xFF))
+
+    def writeimm32(self, imm):
+        self.writechar(chr(imm & 0xFF))
+        self.writechar(chr((imm >> 8) & 0xFF))
+        self.writechar(chr((imm >> 16) & 0xFF))
+        self.writechar(chr((imm >> 24) & 0xFF))
+
+    MOV_ri = insn(register(1), '\xB8', immediate(2))
+    MOV_si = insn('\xC7', orbyte(0<<3), stack(1), immediate(2))
+    MOV_rr = insn('\x89', register(2,8), register(1), '\xC0')
+    MOV_sr = insn('\x89', register(2,8), stack(1))
+    MOV_rs = insn('\x8B', register(1,8), stack(2))
 
     NOP = insn('\x90')
 
-    ADD_rr = insn('\x01', 0xC0 | register(2)<<3 | register(1))
+    ADD_rr = insn('\x01', register(2,8), register(1), '\xC0')



More information about the Pypy-commit mailing list