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

witulski at codespeak.net witulski at codespeak.net
Sun Sep 7 18:58:37 CEST 2008


Author: witulski
Date: Sun Sep  7 18:58:36 2008
New Revision: 57954

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_rgenop.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py
Log:
Added MUL and tests
FIXED IMM32 Problem ( supports now values grather than 255)
Add new Add test for big nums (test is broken)
Add CMP and SETG



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	Sun Sep  7 18:58:36 2008
@@ -1,4 +1,5 @@
-from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32
+from pypy.jit.codegen.x86_64.objmodel import Register8, Register64, Immediate8, Immediate32
+
 
 #Mapping from register to coding (Rex.W or Rex.B , ModRM)
 REGISTER_MAP = {
@@ -19,14 +20,23 @@
                 "r14": (1, 6),
                 "r15": (1, 7),
                 }
-
+                
+REGISTER_MAP_8BIT = {
+                    "al":0,
+                    "cl":1,
+                    "dl":2,
+                    }
+                    
 # This method wirtes the bitencodings into
 # 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):
+# tttn codes the flags and is only used by SETcc
+# extra is an extra byte for long opcodes like imul
+def make_two_operand_instr(W = None, R = None, X = None, B = None, opcode =None, m = None, md1 = None, md2 = None, tttn = None, extra = None):
     def quadreg_instr(self, arg1, arg2):
         # move the parameter 
         # to the inner function
+        mod = m
         modrm1 = md1
         modrm2 = md2
         rexW = W
@@ -36,37 +46,44 @@
         # 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)
+        elif isinstance(arg1,Register8):
+            modrm1 = self.get_register_bits_8Bit(arg1.reg)
             
         # exchange the two arguments (modrm2/modrm1)
         if isinstance(arg2,Immediate32):
+            # e.g: IMUL
+            if(modrm2=="sameReg"):
+                modrm2 = modrm1
+                rexB = rexR
             self.write_rex_byte(rexW, rexR, rexX, rexB)
             self.write(opcode)
             self.write_modRM_byte(3, modrm2, modrm1)
-            # FIXME: Bad solution
-            # TODO: support values > 255
-            if(arg2.value<256):
-                self.write(chr(arg2.value)) 
-                self.write(chr(0))
-                self.write(chr(0))
-                self.write(chr(0))
-        else:
+            self.writeImm32(arg2.value)
+        elif isinstance(arg2,Immediate8):
+            self.write_rex_byte(rexW, rexR, rexX, rexB)
+            self.write(opcode)
+            self.write_modRM_byte(3, modrm2, modrm1)
+            self.write(chr(arg2.value)) 
+        elif isinstance(arg2,Register64):
+            rexB, modrm2 = self.get_register_bits(arg2.reg)            
             # 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)        
+            # used in imul
+            if not extra == None:
+                self.write(extra)
+            self.write_modRM_byte(mod, modrm2, modrm1)        
     return quadreg_instr
         
         
 # This method wirtes the bitencodings into
 # 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 make_one_operand_instr(W = None, R = None, X = None, B = None, opcode = None, m = None, md1 = None, md2 = None, tttn=None, extra = None):
     def quadreg_instr(self, arg1):       
         # move the parameter 
         # to the inner function
+        mod = m
         modrm1 = md1
         modrm2 = md2
         rexW = W
@@ -77,13 +94,18 @@
         # Todo: other cases e.g memory as operand
         if isinstance(arg1,Register64):
             rexB, modrm1 = self.get_register_bits(arg1.reg)
+        if isinstance(arg1,Register8):
+            modrm1 = self.get_register_bits_8Bit(arg1.reg)
             
         # rexW(1) = 64bitMode 
         self.write_rex_byte(rexW, rexR, rexX, rexB)
         self.write(opcode)
-        self.write_modRM_byte(3, modrm2, modrm1)        
+        if not tttn == None:
+            byte = (9 << 4) | tttn
+            self.write(chr(byte))
+        self.write_modRM_byte(mod, modrm2, modrm1)        
     return quadreg_instr
-    
+        
 class X86_64CodeBuilder(object):
     """ creats x86_64 opcodes"""
     def write(self, data):
@@ -96,29 +118,47 @@
     
     
     # The opcodes differs depending on the operands
+    # Params:
+    # W, R, X, B, Opcode, mod, modrm1, modrm2
     
     # 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)
+    _ADD_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0,    0, "\x81", 3, None, 2)  
+    _ADD_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x00", 3, None, None)
     
-    _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)
+    # FIXME: rexB is set
+    _CMP_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0,    1, "\x81", 3, None, 7)
+    _CMP_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x39", 3, None, None)
+    # FIXME: rex B is set
+    _CMP_8REG_IMM8   = make_two_operand_instr(   0,    0,    0,    0, "\x82", 3, None, 7)
+    
+    _DEC_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\xFF", 3, None, 1)
+    _INC_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\xFF", 3, 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)
+    _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)
+    
+    _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")
     
     # 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)
+    _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)
      
-    _SUB_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x28", None, None)
+    _SETG_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0,15)
+     
+    _SUB_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x28", 3, None, None)    
+    _SUB_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0,    0, "\x81", 3, None, 5)
     
     # 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 CMP(self, op1, op2):
+        method = getattr(self, "_CMP"+op1.to_string()+op2.to_string())
+        method(op1, op2)
+        
     def DEC(self, op1):
         method = getattr(self, "_DEC"+op1.to_string())
         method(op1)
@@ -127,6 +167,10 @@
         method = getattr(self, "_INC"+op1.to_string())
         method(op1)
         
+    def JMP(self,displ):
+        self.write("\xE9")
+        self.writeImm32(displ)
+        
     def POP(self, op1):
         method = getattr(self, "_POP"+op1.to_string())
         method(op1)
@@ -138,10 +182,23 @@
     def MOV(self, op1, op2):
         method = getattr(self, "_MOV"+op1.to_string()+op2.to_string())
         method(op1, op2)
+        
+    def IMUL(self, op1, op2):
+        method = getattr(self, "_IMUL"+op1.to_string()+op2.to_string())
+        # exchange the two arguments because 
+        # the result is in the first register 
+        if(op1.to_string()=="_QWREG" and op2.to_string()=="_QWREG"):
+            method(op2, op1)
+        else:
+            method(op1, op2)
     
     def RET(self):
         self.write("\xC3")
         
+    def SETG(self, op1):
+        method = getattr(self, "_SETG"+op1.to_string())
+        method(op1)
+        
     def SUB(self, op1, op2):
         method = getattr(self, "_SUB"+op1.to_string()+op2.to_string())
         method(op1, op2)
@@ -149,6 +206,22 @@
     def get_register_bits(self, register):
         return REGISTER_MAP[register]
     
+    def get_register_bits_8Bit(self, register):
+        return REGISTER_MAP_8BIT[register]
+    
+    # Parse the integervalue to an charakter
+    # and write it
+    def writeImm32(self, imm32):
+        x = hex(imm32)
+        # parse to string and cut "0x" off
+        # fill with zeros if to short
+        y = "0"*(10-len(x))+x[2:len(x)]
+        assert len(y) == 8            
+        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
     def write_rex_byte(self, rexW, rexR, rexX, rexB):

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	Sun Sep  7 18:58:36 2008
@@ -1,7 +1,17 @@
 from pypy.jit.codegen import model
+from pypy.rpython.lltypesystem import lltype, rffi, llmemory
 # Wrapper Classes
 # The opcaodes differ from the type of
 # the operand. So every wrapper is necessary
+# The to string method is used to choose the right
+# method inside the assembler
+class Register8(model.GenVar):
+    def __init__(self, reg):
+        self.reg = reg
+        
+    def to_string(self):
+        return "_8REG"
+
 class Register64(model.GenVar):
     def __init__(self, reg):
         self.reg = reg
@@ -9,6 +19,13 @@
     def to_string(self):
         return "_QWREG"
 
+class Immediate8(model.GenConst):
+    def __init__(self, value):
+        self.value = value
+        
+    def to_string(self):
+        return "_IMM8"
+    
 class Immediate32(model.GenConst):
     def __init__(self, value):
         self.value = value

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	Sun Sep  7 18:58:36 2008
@@ -1,16 +1,17 @@
 from pypy.jit.codegen import model
 from pypy.rlib.objectmodel import specialize
-from pypy.jit.codegen.x86_64.objmodel import Register64, Immediate32
+from pypy.jit.codegen.x86_64.objmodel import Register8, Register64, Immediate8, Immediate32
 from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder
 #TODO: understand llTypesystem
 from pypy.rpython.lltypesystem import llmemory, lltype 
 from pypy.jit.codegen.ia32.objmodel import LL_TO_GENVAR
+from pypy.jit.codegen.model import GenLabel
 
 
 
 # TODO: support zero arg.
 
-# This method calles the assembler to generate code.
+# This method calls the assembler to generate code.
 # It saves the operands in the helpregister gv_z
 # and determine the Type of the operands,
 # to choose the right method in assembler.py
@@ -39,11 +40,18 @@
         arg = lltype.Void
     return LL_TO_GENVAR[arg]
     
+class Label(GenLabel):
+    def __init__(self, startaddr, arg_positions, stackdepth):
+        self.startaddr = startaddr
+        self.arg_positions = arg_positions
+        self.stackdepth = stackdepth
+    
 
 class Builder(model.GenBuilder):
 
     MC_SIZE = 65536
 
+    #FIXME: The MemCodeBuild. is not opend in an _open method
     def __init__(self):
         self.mc = InMemoryCodeBuilder(self.MC_SIZE)
         #callee-saved registers are commented out
@@ -51,18 +59,21 @@
                 "rax":None,
                 "rcx":None,
                 "rdx":None,
-              #  "rbx":None,
+              # "rbx":None,
                 "rsi":None,
                 "rdi":None,
                 "r8": None,
                 "r9": None,
                 "r10":None,
-               # "r11":None,
-               # "r12":None,
-               # "r13":None,
-               # "r14":None,
-               # "r15":None,
+              # "r11":None,
+              # "r12":None,
+              # "r13":None,
+              # "r14":None,
+              # "r15":None,
                }
+               
+    def _open(self):
+        pass
                    
     @specialize.arg(1)
     def genop1(self, opname, gv_arg):
@@ -75,16 +86,42 @@
         return genmethod(gv_arg1, gv_arg2)
     
     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_inc  = make_one_argument_method("INC")
+    op_int_mul  = make_two_argument_method("IMUL")
     op_int_push = make_one_argument_method("PUSH")
     op_int_pop  = make_one_argument_method("POP")
+    op_int_sub  = make_two_argument_method("SUB")
+
+    def jump_if_true(self, gv_condition, args_for_jump_gv):
+        targetbuilder = Builder()
+        self.mc.CMP(gv_condition, Immediate8(0))
+        #targetbuilder.come_from(self.mc, 'JNE')
+        return targetbuilder
+    
+    def op_int_gt(self, gv_x, gv_y):
+        self.mc.CMP(gv_x, gv_y)
+        # You can not use evry register for
+        # 8 bit operations, so you have to
+        # choose rax,rcx or rdx 
+        # TODO: rcx rdx
+        gv_z = self.allocate_register("rax")
+        self.mc.SETG(Register8("al"))
+        return Register8("al")
     
     def finish_and_return(self, sigtoken, gv_returnvar):
         #self.mc.write("\xB8\x0F\x00\x00\x00")
+        self._open()
         self.mc.MOV(Register64("rax"), gv_returnvar)
         self.mc.RET()
+        self._close()
+        
+   #TODO: Implementation
+    def finish_and_goto(self, outputargs_gv, target):
+        self._open()
+        #FIXME: startaddr is maybe not 32bit
+        self.mc.JMP(target.startaddr)
+        self._close()
     
     def allocate_register(self, register=None):
         if register is None:
@@ -97,6 +134,14 @@
         
     def end(self):
         pass
+    
+    #TODO: Implementation
+    def enter_next_block(self, args_gv):
+        print "WriteMe:  enter_next_block"
+        return Label(self.mc.tell(), [], 0)
+    
+    def _close(self):
+        pass
         
 
 class RX86_64GenOp(model.AbstractRGenOp):
@@ -110,7 +155,7 @@
     # wrappes a integer value
     def genconst(self, llvalue):
         T = lltype.typeOf(llvalue)
-        # TODO: other cases(?)
+        # TODO: other cases(?),imm64
         if T is lltype.Signed:
             return Immediate32(llvalue)
         
@@ -122,6 +167,7 @@
         entrypoint = builder.mc.tell()
         # TODO: support more than two reg
         register_list = ["rdi","rsi"]
+        # fill the list with the correct registers
         inputargs_gv = [builder.allocate_register(register_list[i])
                                 for i in range(len(arg_tokens))]
         return builder,Immediate32(entrypoint), inputargs_gv

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	Sun Sep  7 18:58:36 2008
@@ -10,6 +10,24 @@
 def skip(self):
     py.test.skip("not implemented yet")
     
+def make_mul(rgenop):
+    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, gv_y)
+    builder.finish_and_return(sigtoken, gv_result)
+    builder.end()
+    return gv_mul
+    
+def make_mul_im32(rgenop):
+    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))
+    builder.finish_and_return(sigtoken, gv_result)
+    builder.end()
+    return gv_mul
+
 def make_inc(rgenop):
     sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed))
     builder, gv_inc, gv_x = rgenop.newgraph(sigtoken, "inc")
@@ -28,29 +46,63 @@
     builder.end()
     return gv_dec
 
+def make_push(rgenop):
+    sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed))
+    builder, gv_push, gv_x = rgenop.newgraph(sigtoken, "push")
+    builder.start_writing()
+    gv_result = builder.genop1("int_push", gv_x[0])
+    builder.finish_and_return(sigtoken, gv_result)
+    builder.end()
+    return gv_push
+
+def make_pop(rgenop):
+    sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed], lltype.Signed))
+    builder, gv_pop, gv_x = rgenop.newgraph(sigtoken, "pop")
+    builder.start_writing()
+    gv_result = builder.genop1("int_pop", gv_x[0])
+    builder.finish_and_return(sigtoken, gv_result)
+    builder.end()
+    return gv_pop
+
 class TestRGenopDirect(AbstractRGenOpTestsDirect):
     RGenOp = RX86_64GenOp
     
     def test_inc(self):
         rgenop = self.RGenOp()
-        inc_result = make_inc(rgenop)
-        fnptr = self.cast(inc_result,1)
+        inc_function = make_inc(rgenop)
+        fnptr = self.cast(inc_function,1)
         res = fnptr(0)
         assert res == 1
         
     def test_dec(self):
         rgenop = self.RGenOp()
-        dec_result = make_dec(rgenop)
-        fnptr = self.cast(dec_result,1)
+        dec_function = make_dec(rgenop)
+        fnptr = self.cast(dec_function,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
+    def test_mul_im32(self):
+        rgenop = self.RGenOp()
+        mul_function = make_mul_im32(rgenop)
+        fnptr = self.cast(mul_function,1)
+        res = fnptr(210)
+        assert res == 42000
+        
+    def test_mul(self):
+        rgenop = self.RGenOp()
+        mul_function = make_mul(rgenop)
+        fnptr = self.cast(mul_function,2)
+        res = fnptr(1200,300)
+        assert res == 360000
+        
+   # def test_push_and_pop(self):
+   #     rgenop = self.RGenOp()
+   #     push_result = make_push(rgenop)
+   #     fnptr = self.cast(push_result,1)
+   #     pop_result = make_pop(rgenop)
+   #     fnptr = self.cast(pop_result,1)
+   #     res = fnptr(42)
+        #assert res == 1
         
     test_directtesthelper_direct = skip
     test_dummy_compile = skip
@@ -61,7 +113,7 @@
     test_dummy_direct = skip
     test_largedummy_direct = skip
     test_branching_direct = skip
-    test_goto_direct = skip
+    ##test_goto_direct = skip##
     test_if_direct = skip
     test_switch_direct = skip
     test_large_switch_direct = 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	Sun Sep  7 18:58:36 2008
@@ -8,18 +8,28 @@
 
 rgenop = RX86_64GenOp()
 
-def make_testbuilder():
-    FUNC = lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed) #the funtiontype(arguments,returntype) of the graph we will create
+def make_testbuilder(num_of_args):
+    FUNC = lltype.FuncType([lltype.Signed]*num_of_args, lltype.Signed) #the funtiontype(arguments,returntype) of the graph we will create
     token = rgenop.sigToken(FUNC)
     builder, entrypoint, inputargs_gv = rgenop.newgraph(token, "test")
     builder.start_writing() 
-    ctypestypes = [c_long, c_long]
+    ctypestypes = [c_long]*num_of_args
     fp = cast(c_void_p(entrypoint.value),
               CFUNCTYPE(c_long, *ctypestypes))
     return builder, fp, inputargs_gv, token
         
+def test_add_big_num():
+    builder, fp, inputargs_gv, token = make_testbuilder(2)
+    genv0 = inputargs_gv[0] #the first argument "place"
+    genv1 = inputargs_gv[1] 
+    genv_result = builder.genop2("int_add", genv0, genv1) #creates the addition and returns the place(register) of the result in genv_result
+    builder.finish_and_return(token, genv_result)
+    num = fp(1280, 1000)
+    assert num == 2280
+    print num
+    
 def test_add():
-    builder, fp, inputargs_gv, token = make_testbuilder()
+    builder, fp, inputargs_gv, token = make_testbuilder(2)
     genv0 = inputargs_gv[0] #the first argument "place"
     genv1 = inputargs_gv[1] 
     genv_result = builder.genop2("int_add", genv0, genv1) #creates the addition and returns the place(register) of the result in genv_result
@@ -28,20 +38,38 @@
     assert ten == 10
     print ten
     
+def test_add_imm32():
+    builder, fp, inputargs_gv, token = make_testbuilder(1)
+    genv0 = inputargs_gv[0] #the first argument "place"
+    genv_result = builder.genop2("int_add", genv0, rgenop.genconst(1000)) #creates the addition and returns the place(register) of the result in genv_result
+    builder.finish_and_return(token, genv_result)
+    num = fp(1111)
+    assert num == 2111
+    print num
+    
 def test_ret():
-    builder, fp, inputargs_gv, token = make_testbuilder()
+    builder, fp, inputargs_gv, token = make_testbuilder(1)
     builder.finish_and_return(token, inputargs_gv[0])
     print repr("".join(builder.mc._all))
-    four = fp(4, 17)
+    four = fp(4)
     assert four == 4
     print four
     
 def test_sub():
-    builder, fp, inputargs_gv, token = make_testbuilder()
+    builder, fp, inputargs_gv, token = make_testbuilder(2)
     genv0 = inputargs_gv[0] #the first argument "place"
     genv1 = inputargs_gv[1] 
-    genv_result = builder.genop2("int_sub", genv0, genv1) #creates the addition and returns the place(register) of the result in genv_result
+    genv_result = builder.genop2("int_sub", genv0, genv1) #creates the subtraction and returns the place(register) of the result in genv_result
     builder.finish_and_return(token, genv_result)
     four = fp(10, 6)
     assert four == 4
-    print four
\ No newline at end of file
+    print four
+    
+def test_sub_imm32():
+    builder, fp, inputargs_gv, token = make_testbuilder(1)
+    genv0 = inputargs_gv[0] #the first argument "place" 
+    genv_result = builder.genop2("int_sub", genv0, rgenop.genconst(2)) #creates the subtraction and returns the place(register) of the result in genv_result
+    builder.finish_and_return(token, genv_result)
+    eight = fp(10)
+    assert eight == 8
+    print eight
\ No newline at end of file



More information about the Pypy-commit mailing list