[pypy-svn] r57467 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test

witulski at codespeak.net witulski at codespeak.net
Tue Aug 19 17:52:32 CEST 2008


Author: witulski
Date: Tue Aug 19 17:52:28 2008
New Revision: 57467

Modified:
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py
Log:
Interface MOV, ADD ... Changed
New DEC Instruction added and tested
New PUSH/POP Instruction added but not testet yet.



Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py	Tue Aug 19 17:52:28 2008
@@ -1,4 +1,4 @@
-from pypy.jit.codegen.x86_64.objmodel import Register64, Constant32
+from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32
 
 #Mapping from register to coding (Rex.W or Rex.B , ModRM)
 REGISTER_MAP = {
@@ -21,25 +21,30 @@
                 }
 
 # This method wirtes the bitencodings into
-# the memory. imm32 is used when the operation
-# has an constant as operand
-def make_two_operand_instr(opcode,imm32_mod=None):
+# the memory. The parameters are overwritten
+# if one of the operands is an register
+def make_two_operand_instr(W = None, R = None, X = None, B = None, opcode =None, md1 = None, md2 = None):
     def quadreg_instr(self, arg1, arg2):
+        # move the parameter 
+        # to the inner function
+        modrm1 = md1
+        modrm2 = md2
+        rexW = W
+        rexR = R
+        rexX = X
+        rexB = B
         # Todo: other cases e.g memory as operand
         if isinstance(arg1,Register64):
             rexR, modrm1 = self.get_register_bits(arg1.reg)
             
         if isinstance(arg2,Register64):
             rexB, modrm2 = self.get_register_bits(arg2.reg)
-        if isinstance(arg2,Constant32): # e.g IMMEDIATE32
-            rexB = 0
             
-        # rexW(1) = 64bitMode rexX(0) = doesn't matter
-        # exchange the two arguments (rexB/rexR) (modrm2/modrm1)
-        if isinstance(arg2,Constant32):
-            self.write_rex_byte(1, rexB, 0, rexR)
+        # exchange the two arguments (modrm2/modrm1)
+        if isinstance(arg2,Immediate32):
+            self.write_rex_byte(rexW, rexR, rexX, rexB)
             self.write(opcode)
-            self.write_modRM_byte(3, imm32_mod, modrm1)
+            self.write_modRM_byte(3, modrm2, modrm1)
             # FIXME: Bad solution
             # TODO: support values > 255
             if(arg2.value<256):
@@ -48,25 +53,35 @@
                 self.write(chr(0))
                 self.write(chr(0))
         else:
-            self.write_rex_byte(1, rexB, 0, rexR)
+            # FIXME: exchange the two arguments (rexB/rexR)
+            self.write_rex_byte(rexW, rexB, rexX, rexR)
             self.write(opcode)
             self.write_modRM_byte(3, modrm2, modrm1)        
     return quadreg_instr
         
         
 # This method wirtes the bitencodings into
-# the memory. mod is operation specific
-def make_one_operand_instr(opcode,mod = None):
-    def quadreg_instr(self, arg1):
+# the memory. The parameters are overwritten
+# if one of the operands is an register
+def make_one_operand_instr(W = None, R = None, X = None, B = None, opcode = None,  md1 = None, md2 = None):
+    def quadreg_instr(self, arg1):       
+        # move the parameter 
+        # to the inner function
+        modrm1 = md1
+        modrm2 = md2
+        rexW = W
+        rexR = R
+        rexX = X
+        rexB = B
+        
         # Todo: other cases e.g memory as operand
         if isinstance(arg1,Register64):
             rexB, modrm1 = self.get_register_bits(arg1.reg)
-            rexX = 0
             
         # rexW(1) = 64bitMode 
-        self.write_rex_byte(1, 0, rexX, rexB)
+        self.write_rex_byte(rexW, rexR, rexX, rexB)
         self.write(opcode)
-        self.write_modRM_byte(3, mod, modrm1)        
+        self.write_modRM_byte(3, modrm2, modrm1)        
     return quadreg_instr
     
 class X86_64CodeBuilder(object):
@@ -79,20 +94,58 @@
         """ tells the current position in memory"""
         raise NotImplementedError
     
-    # The opcodes differs depending on the operands
-    ADD_QWREG_IMM32 = make_two_operand_instr("\x81",2)  
-    ADD_QWREG_QWREG = make_two_operand_instr("\x00")
     
-    INC_QWREG       = make_one_operand_instr("\xFF",0)
+    # The opcodes differs depending on the operands
     
-    MOV_QWREG_IMM32 = make_two_operand_instr("\xC7",0)
-    MOV_QWREG_QWREG = make_two_operand_instr("\x89")
+    # FIXME: rexX,rexB are set
+    _ADD_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0,    0, "\x81", None, 2)  
+    _ADD_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x00", None, None)
     
-    SUB_QWREG_QWREG = make_two_operand_instr("\x28")
+    _DEC_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\xFF", None, 1)
+    _INC_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\xFF", None, 0)
+
+     
+    _MOV_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0, None, "\xC7", None, 0)
+    _MOV_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x89", None, None)
+    
+    # FIXME: rexW is set 
+    _POP_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\x8F", None, 0)
+    _PUSH_QWREG      = make_one_operand_instr(   1,    0,    0, None, "\xFF", None, 6)
+     
+    _SUB_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x28", None, None)
+    
+    # TODO: maybe a problem with more ore less than two arg.
+    def ADD(self, op1, op2):
+        method = getattr(self, "_ADD"+op1.to_string()+op2.to_string())
+        method(op1, op2)
+        
+    def DEC(self, op1):
+        method = getattr(self, "_DEC"+op1.to_string())
+        method(op1)
+        
+    def INC(self, op1):
+        method = getattr(self, "_INC"+op1.to_string())
+        method(op1)
+        
+    def POP(self, op1):
+        method = getattr(self, "_POP"+op1.to_string())
+        method(op1)
+        
+    def PUSH(self, op1):
+        method = getattr(self, "_POP"+op1.to_string())
+        method(op1)
+        
+    def MOV(self, op1, op2):
+        method = getattr(self, "_MOV"+op1.to_string()+op2.to_string())
+        method(op1, op2)
     
     def RET(self):
         self.write("\xC3")
         
+    def SUB(self, op1, op2):
+        method = getattr(self, "_SUB"+op1.to_string()+op2.to_string())
+        method(op1, op2)
+        
     def get_register_bits(self, register):
         return REGISTER_MAP[register]
     

Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py	Tue Aug 19 17:52:28 2008
@@ -1,13 +1,25 @@
 from pypy.jit.codegen import model
 # Wrapper Classes
-
+# The opcaodes differ from the type of
+# the operand. So every wrapper is necessary
 class Register64(model.GenVar):
-    _dispatchname = "_QWREG"
     def __init__(self, reg):
         self.reg = reg
+        
+    def to_string(self):
+        return "_QWREG"
 
-# TODO: support 64-bit Constants
-class Constant32(model.GenConst):
-    _dispatchname = "_IMM32"
+class Immediate32(model.GenConst):
+    def __init__(self, value):
+        self.value = value
+        
+    def to_string(self):
+        return "_IMM32"
+    
+# TODO: understand GenConst
+class Immediate64(model.GenConst):
     def __init__(self, value):
         self.value = value
+        
+    def to_string(self):
+        return "_IMM64"
\ No newline at end of file

Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py	Tue Aug 19 17:52:28 2008
@@ -1,6 +1,6 @@
 from pypy.jit.codegen import model
 from pypy.rlib.objectmodel import specialize
-from pypy.jit.codegen.x86_64.objmodel import Register64, Constant32
+from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32
 from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder
 #TODO: understand llTypesystem
 from pypy.rpython.lltypesystem import llmemory, lltype 
@@ -17,27 +17,20 @@
 def make_two_argument_method(name):
     def op_int(self, gv_x, gv_y):
         gv_z = self.allocate_register()
-        self.mc.MOV_QWREG_QWREG(gv_z, gv_x)
-        method = getattr(self.mc, name + type_to_string(gv_x)+type_to_string(gv_y))
+        self.mc.MOV(gv_z, gv_x)
+        method = getattr(self.mc, name)
         method(gv_z, gv_y)
         return gv_z
     return op_int
 
 def make_one_argument_method(name):
     def op_int(self, gv_x):
-        method = getattr(self.mc, name+type_to_string(gv_x))
+        method = getattr(self.mc, name)
         method(gv_x)
         return gv_x
     return op_int
 
 
-
-# helper of "make_two_argument_method" to choose 
-# the right assembler method
-def type_to_string(parse_me):
-    return parse_me._dispatchname
-
-
 # a small helper that provides correct type signature
 def map_arg(arg):
     if isinstance(arg, lltype.Ptr):
@@ -84,10 +77,13 @@
     op_int_add  = make_two_argument_method("ADD")
     op_int_sub  = make_two_argument_method("SUB")
     op_int_inc  = make_one_argument_method("INC")
+    op_int_dec  = make_one_argument_method("DEC")
+    op_int_push = make_one_argument_method("PUSH")
+    op_int_pop  = make_one_argument_method("POP")
     
     def finish_and_return(self, sigtoken, gv_returnvar):
         #self.mc.write("\xB8\x0F\x00\x00\x00")
-        self.mc.MOV_QWREG_QWREG(Register64("rax"), gv_returnvar)
+        self.mc.MOV(Register64("rax"), gv_returnvar)
         self.mc.RET()
     
     def allocate_register(self, register=None):
@@ -116,7 +112,7 @@
         T = lltype.typeOf(llvalue)
         # TODO: other cases(?)
         if T is lltype.Signed:
-            return Constant32(llvalue)
+            return Immediate32(llvalue)
         
     def newgraph(self, sigtoken, name):
         arg_tokens, res_token = sigtoken
@@ -128,5 +124,5 @@
         register_list = ["rdi","rsi"]
         inputargs_gv = [builder.allocate_register(register_list[i])
                                 for i in range(len(arg_tokens))]
-        return builder,Constant32(entrypoint), inputargs_gv
+        return builder,Immediate32(entrypoint), inputargs_gv
     

Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_assembler.py	Tue Aug 19 17:52:28 2008
@@ -1,5 +1,5 @@
 from pypy.jit.codegen.x86_64 import assembler
-from pypy.jit.codegen.x86_64.objmodel import Register64, Constant32
+from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32
 
 class AsmTest(assembler.X86_64CodeBuilder):
     def __init__(self):
@@ -13,12 +13,12 @@
 
 def test_add():
     mc = AsmTest()
-    mc.ADD_QWREG_QWREG(Register64("rax"), Register64("r11"))
+    mc.ADD(Register64("rax"), Register64("r11"))
     assert mc.get_as_string() == "\x4C\x00\xD8"
-    mc.ADD_QWREG_QWREG(Register64("rbx"), Register64("rbx"))
+    mc.ADD(Register64("rbx"), Register64("rbx"))
     assert mc.get_as_string() == "\x4C\x00\xD8\x48\x00\xDB"
     
 def test_mov():
     mc = AsmTest()
-    mc.MOV_QWREG_QWREG(Register64("r15"),Register64("rsp"))
+    mc.MOV(Register64("r15"),Register64("rsp"))
     assert mc.get_as_string() == "\x49\x89\xE7"
\ No newline at end of file

Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_rgenop.py	Tue Aug 19 17:52:28 2008
@@ -19,6 +19,15 @@
     builder.end()
     return gv_inc
 
+def make_dec(rgenop):
+    sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed))
+    builder, gv_dec, gv_x = rgenop.newgraph(sigtoken, "dec")
+    builder.start_writing()
+    gv_result = builder.genop1("int_dec", gv_x[0])
+    builder.finish_and_return(sigtoken, gv_result)
+    builder.end()
+    return gv_dec
+
 class TestRGenopDirect(AbstractRGenOpTestsDirect):
     RGenOp = RX86_64GenOp
     
@@ -29,6 +38,20 @@
         res = fnptr(0)
         assert res == 1
         
+    def test_dec(self):
+        rgenop = self.RGenOp()
+        dec_result = make_dec(rgenop)
+        fnptr = self.cast(dec_result,1)
+        res = fnptr(2)
+        assert res == 1
+        
+    #def test_push_and_pop(self):
+    #    rgenop = self.RGenOp()
+    #    push_result = make_push(rgenop)
+    #    fnptr = self.cast(push_result,1)
+    #    res = fnptr(2)
+    #    assert res == 1
+        
     test_directtesthelper_direct = skip
     test_dummy_compile = skip
     test_cast_raising = skip

Modified: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py	Tue Aug 19 17:52:28 2008
@@ -2,7 +2,7 @@
 from pypy.jit.codegen.x86_64.rgenop import RX86_64GenOp
 from pypy.rpython.lltypesystem import lltype
 from ctypes import cast, c_void_p, CFUNCTYPE, c_long, c_double
-from pypy.jit.codegen.x86_64.objmodel import Register64, Constant32
+from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32
 from pypy.jit.codegen.test.rgenop_tests import AbstractTestBase
 from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTestsDirect
 



More information about the Pypy-commit mailing list