[pypy-svn] r59034 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test
witulski at codespeak.net
witulski at codespeak.net
Sun Oct 12 16:26:36 CEST 2008
Author: witulski
Date: Sun Oct 12 16:26:33 2008
New Revision: 59034
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:
spilling implemented.
- the args_gv of the label of enter_next_block are now copys (spilling could change refs)
- gv_temp is removed from known_gv in allocate_register to avoid double entrys in that list
- some comments added
- move_back_to_register access the memory if the spilled gv is not the top of stack
- allocate register uses spill_register when are no more free regs. left
- stackdepth calc fixed
- compares return refs of rax
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 Oct 12 16:26:33 2008
@@ -76,11 +76,11 @@
self.write(extra)
self.write_modRM_byte(mod, modrm2, modrm1)
elif isinstance(arg2.location, Stack64):
- self.write_rex_byte(rexW, rexR, rexX, rexB)
+ self.write_rex_byte(rexW, rexB, rexX, rexR)
self.write(opcode)
# exchanged mod1,mod2, dont know why :)
self.write_modRM_byte(mod, modrm1, modrm2)
- # no scale, no index, base = rsp
+ # no scale(has no effect on rsp), no index, base = rsp
self.write_SIB(0, 4, 4)
self.writeImm32(arg2.location.offset)
return quadreg_instr
@@ -206,7 +206,7 @@
_IDIV_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 7)
_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")
+ _IMUL_QWREG_IMM32 = make_two_operand_instr( 1, None, 0, None, "\x69", 3, None, "sameReg")#3 op instr
_NEG_QWREG = make_one_operand_instr( 1, 0, 0, None, "\xF7", 3, None, 3)
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 Oct 12 16:26:33 2008
@@ -103,16 +103,16 @@
@specialize.arg(1)
def genop1(self, opname, gv_arg):
if isinstance(gv_arg, model.GenVar) and isinstance(gv_arg.location, Stack64):
- move_back_to_register(gv_arg)
+ gv_arg = self.move_back_to_register(gv_arg)
genmethod = getattr(self, 'op_' + opname)
return genmethod(gv_arg)
@specialize.arg(1)
def genop2(self, opname, gv_arg1, gv_arg2):
if isinstance(gv_arg1, model.GenVar) and isinstance(gv_arg1.location, Stack64):
- move_back_to_register(gv_arg1)
+ gv_arg1 = self.move_back_to_register(gv_arg1)
if isinstance(gv_arg2, model.GenVar) and isinstance(gv_arg2.location, Stack64):
- move_back_to_register(gv_arg2)
+ gv_arg2 = self.move_back_to_register(gv_arg2)
genmethod = getattr(self, 'op_' + opname)
return genmethod(gv_arg1, gv_arg2)
@@ -191,39 +191,40 @@
# TODO: use also rcx rdx
gv_z = self.allocate_register("rax")
self.mc.SETG(IntVar(Register8("al")))
- return IntVar(Register64("rax"))
+ return gv_z
def op_int_lt(self, gv_x, gv_y):
self.mc.CMP(gv_x, gv_y)
gv_z = self.allocate_register("rax")
self.mc.SETL(IntVar(Register8("al")))
- return IntVar(Register64("rax"))
+ return gv_z
def op_int_le(self, gv_x, gv_y):
self.mc.CMP(gv_x, gv_y)
gv_z = self.allocate_register("rax")
self.mc.SETLE(IntVar(Register8("al")))
- return IntVar(Register64("rax"))
+ return gv_z
def op_int_eq(self, gv_x, gv_y):
self.mc.CMP(gv_x, gv_y)
gv_z = self.allocate_register("rax")
self.mc.SETE(IntVar(Register8("al")))
- return IntVar(Register64("rax"))
+ return gv_z
def op_int_ne(self, gv_x, gv_y):
self.mc.CMP(gv_x, gv_y)
gv_z = self.allocate_register("rax")
self.mc.SETNE(IntVar(Register8("al")))
- return IntVar(Register64("rax"))
+ return gv_z
def op_int_ge(self, gv_x, gv_y):
self.mc.CMP(gv_x, gv_y)
gv_z = self.allocate_register("rax")
self.mc.SETGE(IntVar(Register8("al")))
- return IntVar(Register64("rax"))
+ return gv_z
# the moves to pass arg. when making a jump to a block
+ # the targetvars are only copys
#FIXME: problem with mapping of stackpositions
def _compute_moves(self, outputargs_gv, targetargs_gv):
tar2src = {}
@@ -260,8 +261,14 @@
def finish_and_return(self, sigtoken, gv_returnvar):
#self.mc.write("\xB8\x0F\x00\x00\x00")
self._open()
+ gv_return = self.allocate_register("rax")
+ # if there unused genVars on the stack
+ # pop them away
+ while not self.stackdepth == 0:
+ self.mc.POP(gv_return)
+ self.stackdepth = self.stackdepth -1
if not gv_returnvar == None:#check void return
- self.mc.MOV(IntVar(Register64("rax")), gv_returnvar)
+ self.mc.MOV(gv_return, gv_returnvar)
self.mc.RET()
self._close()
assert self.stackdepth == 0
@@ -281,29 +288,39 @@
self.mc.JMP(target.startaddr)
self._close()
+ # FIXME: returns only ints
+ # FIXME: Double values in known_gv??
# TODO: support the allocation of 8bit Reg
def allocate_register(self, register=None):
if register is None:
if not self.freeregisters:
- #raise NotImplementedError("spilling not implemented")
- return self.spill_register()
+ new_gv = self.spill_register()
+ self.known_gv.append(new_gv)
+ return new_gv
+
new_gv = IntVar(Register64(self.freeregisters.popitem()[0]))
self.known_gv.append(new_gv)
return new_gv
+
else:
if register not in self.freeregisters:
# the register must be in the list!
for i in range(len(self.known_gv)):
- if register == self.known_gv[i].location.reg:
- # move the values from the requiered register
- # to an other one and return the
- # requested one.
- gv = self.allocate_register()
- self.mc.MOV(gv,self.known_gv[i])
+ if isinstance(self.known_gv[i].location, Register64) and register == self.known_gv[i].location.reg:
+ # move the values from the requiered
+ # register to an other one and
+ # return the requested one.
+ gv_temp = self.allocate_register()
+ self.mc.MOV(gv_temp, self.known_gv[i])
new_gv = IntVar(Register64(register))
self.known_gv.append(new_gv)
+ self.known_gv[i].location.reg = gv_temp.location.reg
+ self.known_gv.remove(gv_temp)
return new_gv
- raise NotImplementedError("register moves")
+
+ # raised when the register is not in freereg. and not
+ # used by a gen_var
+ raise Exception("error while register moves")
del self.freeregisters[register]
new_gv = IntVar(Register64(register))
self.known_gv.append(new_gv)
@@ -312,15 +329,22 @@
def end(self):
pass
- #TODO: args_gv muste be a list of unique GenVars
+ # TODO: args_gv muste be a list of unique GenVars
+ # Spilling could change the location of a
+ # genVar after this Label. That will result in
+ # wrong a mapping in _compute_moves when leaving this block.
+ # So the parameters must be inmutable(copy them)
def enter_next_block(self, args_gv):
# move constants into an register
+ copy_args = []
for i in range(len(args_gv)):
if isinstance(args_gv[i],model.GenConst):
gv_x = self.allocate_register()
self.mc.MOV(gv_x, args_gv[i])
args_gv[i] = gv_x
- L = Label(self.mc.tell(), args_gv, 0)
+ # copy the gv
+ copy_args.append(IntVar(Register64(args_gv[i].location.reg)))
+ L = Label(self.mc.tell(), copy_args, 0)
return L
def _close(self):
@@ -333,37 +357,44 @@
# take the first gv which is not
# on the stack
gv_to_spill = None
- for i in range(len(known_gv)):
- if not isinstance(known_gv[i].location, Stack64):
+ for i in range(len(self.known_gv)):
+ if not isinstance(self.known_gv[i].location, Stack64):
gv_to_spill = self.known_gv[i]
break
# there must be genVars which are
# inside an register so:
assert isinstance(gv_to_spill.location, Register64)
-
self.stackdepth = self.stackdepth +1
self.mc.PUSH(gv_to_spill)
new_gv = IntVar(Register64(gv_to_spill.location.reg))
- gv_to_spill.location = Stack64(self.stackdepth)
+ gv_to_spill.location = Stack64(self.stackdepth)
return new_gv
- def move_back_to_register(a_spilled_gv):
- # if top of stack
+ # FIXME: pushed values are not allways poped (if not TOS)
+ def move_back_to_register(self, a_spilled_gv):
+ # if a_spilled_gv is the top of stack
if a_spilled_gv.location.offset == self.stackdepth:
gv_new = self.allocate_register()
self.mc.POP(gv_new)
self.stackdepth = self.stackdepth -1
assert self.stackdepth >= 0
#update all offsets
- for i in range(len(known_gv)):
- if isinstance(known_gv[i].location, Stack64):
+ for i in range(len(self.known_gv)):
+ if isinstance(self.known_gv[i].location, Stack64):
known_gv[i].location.offset = known_gv[i].location.offset -1
a_spilled_gv = gv_new
- # TODO: free gv_new (no double values in known_gv
+ # TODO: free gv_new (no double values in known_gv)
+ # TODO: look if there is a genVar with stackdepth
+ # if not it has already been moved to a reg.
+ # pop it or change the stackpointer
+ return a_spilled_gv
+ else:
# else access the memory
# FIXME: if this genVar becomes the top of stack it will never be pushed
- else:
- pass
+ gv_new = self.allocate_register()
+ self.mc.MOV(gv_new, IntVar(Stack64(8*(self.stackdepth-a_spilled_gv.location.offset))))
+ a_spilled_gv = gv_new
+ return a_spilled_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 Oct 12 16:26:33 2008
@@ -126,6 +126,15 @@
gv_result = builder.genop2(instr_name, gv_x, rgenop.genconst(num))
builder.finish_and_return(sigtoken, gv_result)
builder.end()
+ return gv_op_imm
+
+def make_one_op_imm_instr_args_inv(rgenop, instr_name, num):
+ sigtoken = rgenop.sigToken(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
+ builder, gv_op_imm, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "one_op_imm_instr_args_inv")
+ builder.start_writing()
+ gv_result = builder.genop2(instr_name, rgenop.genconst(num), gv_x)
+ builder.finish_and_return(sigtoken, gv_result)
+ builder.end()
return gv_op_imm
class TestRGenopDirect(AbstractRGenOpTestsDirect):
@@ -174,6 +183,14 @@
mul_function = make_one_op_imm_instr(rgenop, "int_mul", -9876)
fnptr = self.cast(mul_function,1)
res = fnptr(12345)
+ assert res == -121919220
+ mul_function =make_one_op_imm_instr_args_inv(rgenop, "int_mul", 200)
+ fnptr = self.cast(mul_function,1)
+ res = fnptr(210)
+ assert res == 42000
+ mul_function = make_one_op_imm_instr_args_inv(rgenop, "int_mul", -9876)
+ fnptr = self.cast(mul_function,1)
+ res = fnptr(12345)
assert res == -121919220
def test_idiv_imm32(self):
@@ -497,7 +514,7 @@
test_calling_pause_direct = skip
test_longwinded_and_direct = skip
test_condition_result_cross_link_direct = skip
- test_multiple_cmps = skip
+ ##test_multiple_cmps = skip##
test_flipped_cmp_with_immediate = skip
test_jump_to_block_with_many_vars = skip
test_same_as = skip
More information about the Pypy-commit
mailing list