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

witulski at codespeak.net witulski at codespeak.net
Mon Sep 8 16:57:41 CEST 2008


Author: witulski
Date: Mon Sep  8 16:57:40 2008
New Revision: 57975

Modified:
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/assembler.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.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:

MOV and JMP now support IMM64 values, but still crash sometimes with a seg. fault


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	Mon Sep  8 16:57:40 2008
@@ -1,4 +1,4 @@
-from pypy.jit.codegen.x86_64.objmodel import Register8, Register64, Immediate8, Immediate32
+from pypy.jit.codegen.x86_64.objmodel import Register8, Register64, Immediate8, Immediate32, Immediate64
 
 
 #Mapping from 64Bit-Register to coding (Rex.W or Rex.B , ModRM)
@@ -108,6 +108,29 @@
         self.write_modRM_byte(mod, modrm2, modrm1)        
     return quadreg_instr
         
+# TODO: comment        
+def make_two_operand_instr_with_alternate_encoding(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
+        # FIXME: rexB?
+        if isinstance(arg1,Register64):
+            rexB, modrm1 = self.get_register_bits(arg1.reg)
+            
+        # exchange the two arguments (modrm2/modrm1)
+        if isinstance(arg2,Immediate64):
+            self.write_rex_byte(rexW, rexR, rexX, rexB)
+            self.write(opcode+chr(modrm1))
+            self.writeImm64(arg2.value)
+    return quadreg_instr
+        
 class X86_64CodeBuilder(object):
     """ creats x86_64 opcodes"""
     def write(self, data):
@@ -139,10 +162,13 @@
      
     _MOV_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0, None, "\xC7", 3, None, 0)
     _MOV_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x89", 3, None, None)
-    
+    _MOV_QWREG_IMM64 = make_two_operand_instr_with_alternate_encoding(1,0,0,None,"\xB8",None,None)
+        
     _IMUL_QWREG_QWREG = make_two_operand_instr(  1, None,    0, None, "\x0F", 3, None, None, None, "\xAF")
     _IMUL_QWREG_IMM32 = make_two_operand_instr(  1, None,    0, None, "\x69", 3, None, "sameReg")
     
+    _JMP_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\xFF", 3, None, 4)
+
     # FIXME: rexW is set 
     _POP_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\x8F", 3, None, 0)
     _PUSH_QWREG      = make_one_operand_instr(   1,    0,    0, None, "\xFF", 3, None, 6)
@@ -169,9 +195,12 @@
         method = getattr(self, "_INC"+op1.to_string())
         method(op1)
         
-    def JMP(self,displ):
-        self.write("\xE9")
-        self.writeImm32(displ)
+    # op1 must be a register
+    def JMP(self,op1):
+        method = getattr(self, "_JMP"+op1.to_string())
+        method(op1)
+        #self.write("\xE9")
+        #self.writeImm32(displ)
         
     def POP(self, op1):
         method = getattr(self, "_POP"+op1.to_string())
@@ -223,6 +252,24 @@
         self.write(chr(int(y[4:6],16)))
         self.write(chr(int(y[2:4],16)))
         self.write(chr(int(y[0:2],16)))
+        
+        
+    # Parse the integervalue to an charakter
+    # and write it
+    def writeImm64(self, imm64):
+        x = hex(imm64)
+        # parse to string and cut "0x" off
+        # fill with zeros if to short
+        y = "0"*(18-len(x))+x[2:len(x)]
+        assert len(y) == 16    
+        self.write(chr(int(y[14:16],16))) 
+        self.write(chr(int(y[12:14],16)))
+        self.write(chr(int(y[10:12],16)))
+        self.write(chr(int(y[8:10],16)))        
+        self.write(chr(int(y[6:8],16))) 
+        self.write(chr(int(y[4:6],16)))
+        self.write(chr(int(y[2:4],16)))
+        self.write(chr(int(y[0:2],16)))
             
     
     # Rex-Prefix 4WRXB see AMD vol3 page 45

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	Mon Sep  8 16:57:40 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 Register8, Register64, Immediate8, Immediate32
+from pypy.jit.codegen.x86_64.objmodel import Register8, Register64, Immediate8, Immediate32, Immediate64
 from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder
 #TODO: understand llTypesystem
 from pypy.rpython.lltypesystem import llmemory, lltype 
@@ -20,7 +20,16 @@
         gv_z = self.allocate_register()
         self.mc.MOV(gv_z, gv_x)
         method = getattr(self.mc, name)
-        method(gv_z, gv_y)
+        
+        # Many operations don't support
+        # 64 Bit Immmediates directly
+        if isinstance(gv_y,Immediate64):
+            gv_w = self.allocate_register()
+            self.mc.MOV(gv_w, gv_y)
+            method(gv_z, gv_w)
+        else: 
+            method(gv_z, gv_y)
+            
         return gv_z
     return op_int
 
@@ -96,7 +105,7 @@
 
     def jump_if_true(self, gv_condition, args_for_jump_gv):
         targetbuilder = Builder()
-        self.mc.CMP(gv_condition, Immediate8(0))
+        self.mc.CMP(gv_condition, Immediate32(0))
         #targetbuilder.come_from(self.mc, 'JNE')
         return targetbuilder
     
@@ -117,11 +126,13 @@
         self.mc.RET()
         self._close()
         
-   #TODO: Implementation
+    # if the label is greater than 32bit
+    # it must be in a register
     def finish_and_goto(self, outputargs_gv, target):
         self._open()
-        #FIXME: startaddr is maybe not 32bit
-        self.mc.JMP(target.startaddr)
+        gv_x = self.allocate_register()
+        self.mc.MOV(gv_x,Immediate64(target.startaddr))
+        self.mc.JMP(gv_x)
         self._close()
     
     def allocate_register(self, register=None):
@@ -158,7 +169,10 @@
         T = lltype.typeOf(llvalue)
         # TODO: other cases(?),imm64
         if T is lltype.Signed:
-            return Immediate32(llvalue)
+            if llvalue > int("FFFFFFFF",16):
+                return Immediate64(llvalue)
+            else:
+                return Immediate32(llvalue)
         
     def newgraph(self, sigtoken, name):
         arg_tokens, res_token = sigtoken

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	Mon Sep  8 16:57:40 2008
@@ -29,11 +29,11 @@
     builder.end()
     return gv_mul
     
-def make_mul_im32(rgenop):
+def make_mul_imm(rgenop, num):
     sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
     builder, gv_mul, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "mul")
     builder.start_writing()
-    gv_result = builder.genop2("int_mul", gv_x, rgenop.genconst(200))
+    gv_result = builder.genop2("int_mul", gv_x, rgenop.genconst(num))
     builder.finish_and_return(sigtoken, gv_result)
     builder.end()
     return gv_mul
@@ -77,7 +77,7 @@
 
 class TestRGenopDirect(AbstractRGenOpTestsDirect):
     RGenOp = RX86_64GenOp
-                    
+                        
     def test_inc(self):
         rgenop = self.RGenOp()
         inc_function = make_inc(rgenop)
@@ -94,11 +94,20 @@
         
     def test_mul_im32(self):
         rgenop = self.RGenOp()
-        mul_function = make_mul_im32(rgenop)
+        mul_function = make_mul_imm(rgenop,200)
         fnptr = self.cast(mul_function,1)
         res = fnptr(210)
         assert res == 42000
         
+    # segmentation fault at mov(qwreg,imm64)
+    
+    #def test_mul_im64(self):
+    #    rgenop = self.RGenOp()
+    #    mul_function = make_mul_imm(rgenop,int("123456789",16))
+    #    fnptr = self.cast(mul_function,1)
+    #    res = fnptr(2)
+    #    assert res == int("123456789",16)*2
+        
     def test_mul(self):
         rgenop = self.RGenOp()
         mul_function = make_mul(rgenop)

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	Mon Sep  8 16:57:40 2008
@@ -21,7 +21,7 @@
     return builder, fp, inputargs_gv, token
     
 class TestSimple():   
-     
+    
     def test_add_big_num(self):
         builder, fp, inputargs_gv, token = make_testbuilder(2)
         genv0 = inputargs_gv[0] #the first argument "place"
@@ -76,4 +76,5 @@
         builder.finish_and_return(token, genv_result)
         eight = fp(10)
         assert eight == 8
-        print eight
\ No newline at end of file
+        print eight
+        
\ No newline at end of file



More information about the Pypy-commit mailing list