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

witulski at codespeak.net witulski at codespeak.net
Mon Oct 27 14:57:45 CET 2008


Author: witulski
Date: Mon Oct 27 14:57:42 2008
New Revision: 59446

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
Log:
Added genraisingop2/genraisingop1 to suppoert overflow versions of add and other operations


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 Oct 27 14:57:42 2008
@@ -236,12 +236,13 @@
     #_POP_QWREG  = make_one_operand_instr_with_alternate_encoding(1,0,0,None,"58",None,None)
     #_PUSH_QWREG = make_one_operand_instr_with_alternate_encoding(1,0,0,None,"50",None,None) 
      
-    _SETE_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0,4) 
-    _SETG_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0,15)
-    _SETGE_8REG      = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0,13)
-    _SETL_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0,12) 
-    _SETLE_8REG      = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0,14)   
-    _SETNE_8REG      = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0,5)  
+    _SETE_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0, 4) 
+    _SETG_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0, 15)
+    _SETGE_8REG      = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0, 13)
+    _SETL_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0, 12) 
+    _SETLE_8REG      = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0, 14)
+    _SETO_8REG       = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0, 0)   
+    _SETNE_8REG      = make_one_operand_instr(   0,    0,    0,    0, "\x0F", 3, None, 0, 5)  
      
     _SHL_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\xD3", 3, None, 4)
     _SHR_QWREG       = make_one_operand_instr(   1,    0,    0, None, "\xD3", 3, None, 5) 
@@ -252,7 +253,7 @@
     _XOR_QWREG_IMM32 = make_two_operand_instr(   1,    0,    0, None, "\x81", 3, None, 6)
     _XOR_QWREG_QWREG = make_two_operand_instr(   1, None,    0, None, "\x31", 3, None, None)
     
-    # TODO(all ops): maybe a problem with more ore less than two arg.
+    # TODO(all ops): maybe a problem with more or less than two arg.
     def ADD(self, op1, op2):
         method = getattr(self, "_ADD"+op1.to_string()+op2.to_string())
         method(op1, op2)
@@ -295,6 +296,7 @@
         method = getattr(self, "_INC"+op1.to_string())
         method(op1)
         
+    # near jump (only the same codeseg.)
     # 4 length of the immediate
     # want_jump_to is an 32bit(!) adress
     def JMP(self,want_jump_to):
@@ -304,6 +306,7 @@
         self.writeImm32(want_jump_to-self.tell()-4)
         
     # 4 length of the immediate
+    # want_jump_to is an 32bit(!) adress
     def JNE(self,want_jump_to):
         self.write("\x0F")
         self.write("\x85")
@@ -347,6 +350,10 @@
         method = getattr(self, "_SETL"+op1.to_string())
         method(op1)
         
+    def SETO(self, op1):
+        method = getattr(self, "_SETO"+op1.to_string())
+        method(op1)
+        
     def SETR(self, op1):
         method = getattr(self, "_SETR"+op1.to_string())
         method(op1)
@@ -429,22 +436,24 @@
         self.write(chr(int(y[0:2],16)))
             
     
-    # Rex-Prefix 4WRXB see AMD vol3 page 45
+    # Rex-Prefix 4WRXB see AMD vol3 page 11
     def write_rex_byte(self, rexW, rexR, rexX, rexB):
         byte = (4 << 4) | (rexW << 3) | (rexR << 2) | (rexX << 1) | rexB
         self.write(chr(byte))
-        
+    
+    # modRM see AMD vol3 page 17  
     def write_modRM_byte(self, mod, reg, rm):
         byte = mod << 6 | (reg << 3) | rm
         self.write(chr(byte))
         
+    # SIB see AMD vol3 page 17    
     def write_SIB(self, scale, index, base):
         byte = scale << 6 | (index << 3) | base
         self.write(chr(byte))
         
     # calc. the "Two's complement"
     # and return as pos. hex value.
-    # This method is used to calc jump displ.
+    # This method is used to calc. a (neg.) jump displ.
     def cast_neg_hex32(self,a_int):
         x = hex(int("FFFFFFFF",16)+1 +a_int)
         y = x[2:len(x)]

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 Oct 27 14:57:42 2008
@@ -13,7 +13,7 @@
 
 # This method calls the assembler to generate code.
 # It saves the operands in the helpregister gv_z
-# and determine the Type of the operands,
+# and determine the type of the operands,
 # to choose the right method in assembler.py
 def make_two_argument_method(name):
     def op_int(self, gv_x, gv_y):
@@ -66,6 +66,7 @@
         self.arg_positions = arg_positions
         self.stackdepth = stackdepth
 
+# used by emit_moves
 class MoveEmitter(object):
     def __init__(self, builder):
         self.builder = builder
@@ -101,7 +102,7 @@
               # "r14":None,
               # "r15":None,
                }
-        self._orig_location={}
+        self._orig_location={}# used to restore the location of a gv
         self.known_gv = [] # contains the live genvars (used for spilling and allocation)
         for reg in used_registers:
             del self.freeregisters[reg.location.reg]
@@ -124,19 +125,41 @@
     def genop2(self, opname, gv_arg1, gv_arg2): 
         genmethod = getattr(self, 'op_' + opname)
         return genmethod(gv_arg1, gv_arg2)
+    
+    def genraisingop1(self, opname, gv_arg1):
+        assert opname[len(opname)-4:len(opname)] == "_ovf"
+        
+        genmethod = getattr(self, 'op_' + opname[0:len(opname)-4])
+        gv_result = genmethod(gv_arg1)
+        gv_bool = self.allocate_register("rax", gv_result)
+        self.mc.SETO(IntVar(Register8("al")))
+        return gv_result, gv_bool
+    
+    # This Method creates an overflow method which
+    # return the operations result and a flag(BoolVar)
+    # flag= True if there was an overflow
+    # it works like genop2
+    def genraisingop2(self, opname, gv_arg1, gv_arg2):
+        assert opname[len(opname)-4:len(opname)] == "_ovf"
+        
+        genmethod = getattr(self, 'op_' + opname[0:len(opname)-4])
+        gv_result = genmethod(gv_arg1, gv_arg2)
+        gv_bool = self.allocate_register("rax", gv_result)
+        self.mc.SETO(IntVar(Register8("al")))
+        return gv_result, gv_bool
  
-    op_int_add  = make_two_argument_method("ADD")  # TODO: use inc
-    op_int_and  = make_two_argument_method("AND")
-    op_int_dec  = make_one_argument_method("DEC")  # for debuging
-    op_int_inc  = make_one_argument_method("INC")  # for debuging
-    op_int_mul  = make_two_argument_method("IMUL")
-    op_int_neg  = make_one_argument_method("NEG")
-    op_int_not  = make_one_argument_method("NOT")  # for debuging
-    op_int_or   = make_two_argument_method("OR")
-    op_int_push = make_one_argument_method("PUSH") # for debuging
-    op_int_pop  = make_one_argument_method("POP")  # for debuging
-    op_int_sub  = make_two_argument_method("SUB")  # TODO: use DEC
-    op_int_xor  = make_two_argument_method("XOR")
+    op_int_add     = make_two_argument_method("ADD")  # TODO: use inc
+    op_int_and     = make_two_argument_method("AND")
+    op_int_dec     = make_one_argument_method("DEC")  # for debuging
+    op_int_inc     = make_one_argument_method("INC")  # for debuging
+    op_int_mul     = make_two_argument_method("IMUL")
+    op_int_neg     = make_one_argument_method("NEG")
+    op_int_not     = make_one_argument_method("NOT")  # for debuging
+    op_int_or      = make_two_argument_method("OR")
+    op_int_push    = make_one_argument_method("PUSH") # for debuging
+    op_int_pop     = make_one_argument_method("POP")  # for debuging
+    op_int_sub     = make_two_argument_method("SUB")  # TODO: use DEC
+    op_int_xor     = make_two_argument_method("XOR")
 
     # must return a genvar
     def genop_same_as(self, imm):
@@ -144,6 +167,7 @@
         self.mc.MOV(gv_x, imm)
         return gv_x
         
+    # returns 1 if gv_x is true
     def op_int_is_true(self, gv_x):
         [gv_x, gv_y] = self.move_to_registers([gv_x, Immediate32(1)], None, move_imm_too=True)  
         self.mc.CMP(gv_x, gv_y)
@@ -182,6 +206,9 @@
         self.mc.SHR(gv_x)
         return gv_x
     
+    # called before an assembler operation
+    # ensures that every genVar is
+    # inside of a register
     def move_to_registers(self, registers, dont_alloc = None, move_imm_too = False):
         if dont_alloc is None:
             dont_alloc = []
@@ -212,7 +239,7 @@
         return gv_z 
     
     # IDIV RDX:RAX with QWREG
-    # FIXME: supports only RAX with QWREG
+    # supports only RAX with QWREG
     def op_int_mod(self, gv_x, gv_y):
         gv_z = self.allocate_register("rax")
         gv_w = self.allocate_register("rdx")
@@ -225,6 +252,8 @@
 #    def op_int_invert(self, gv_x):
 #       return self.mc.NOT(gv_x)
     
+    # if a register contains a constant
+    # it will be marked to be don't spilled
     def throw_away_if_const(self, registers):
         for i in range(len(registers)):
             if registers[i].location.contains_genConst:
@@ -313,7 +342,8 @@
         from pypy.tool.sourcetools import func_with_new_name
         def jump(self, gv_condition, args_for_jump_gv): 
             # the targetbuilder must know the registers(live vars) 
-            # of the calling block  
+            # of the calling block and the used stack_pos
+            # to ensure a correct register allocation 
             targetbuilder = Builder(self.stackdepth, args_for_jump_gv, self.used_stack_pos)
             self.mc.CMP(gv_condition, Immediate32(value))
             self.mc.JNE(targetbuilder.mc.tell())
@@ -324,8 +354,8 @@
     jump_if_true  = _new_jump('jump_if_true', 0)
     
     # moves stackpointer if there are
-    # gv on the stack which are not 
-    # need anymore
+    # gv on the stack (which are not 
+    # need anymore)
     def finish_and_return(self, sigtoken, gv_returnvar):
         #self.mc.write("\xB8\x0F\x00\x00\x00")
         self._open()
@@ -542,6 +572,8 @@
         # TODO: Builder._open()
         entrypoint = builder.mc.tell()
         # from http://www.x86-64.org/documentation/abi.pdf
+        # TODO: also return Stackpositions and let the
+        #       builder know 
         register_list = ["rdi","rsi","rdx","rcx","r8","r9"]
         # fill the list with the correct registers
         inputargs_gv = [builder.allocate_register(register_list[i])

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 Oct 27 14:57:42 2008
@@ -584,7 +584,7 @@
     test_from_random_4_direct = skip
     test_from_random_5_direct = skip
     test_genzeroconst = skip
-    test_ovfcheck_adder_direct = skip
+   # test_ovfcheck_adder_direct = skip
     test_ovfcheck1_direct = skip
     test_ovfcheck2_direct = skip
     test_cast_direct = skip



More information about the Pypy-commit mailing list