[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