[pypy-svn] r78671 - in pypy/branch/arm-backend/pypy/jit/backend/arm: . helper test
david at codespeak.net
david at codespeak.net
Wed Nov 3 15:10:39 CET 2010
Author: david
Date: Wed Nov 3 15:10:37 2010
New Revision: 78671
Modified:
pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/locations.py
pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py
pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py
pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py
Log:
Implement register spilling on the stack.
Introduce a frame pointer to manage the stack frame
For now with a fixed frame size of 10 words for spilling
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py Wed Nov 3 15:10:37 2010
@@ -57,16 +57,21 @@
while(True):
i += 1
fail_index += 1
- r = enc[i]
- if r == '\xFE':
+ res = enc[i]
+ if res == '\xFE':
continue
- if r == '\xFF':
+ if res == '\xFF':
break
- if r == '\xFD':
+ if res == '\xFD':
# imm value
value = self.decode32(enc, i+1)
i += 4
- else:
+ elif res == '\xFC': # stack location
+ stack_loc = self.decode32(enc, i+1)
+ #XXX ffuu use propper calculation here
+ value = self.decode32(stack, len(r.all_regs)*WORD+40-stack_loc*WORD)
+ i += 4
+ else: # an int for now
reg = ord(enc[i])
value = self.decode32(stack, reg*WORD)
@@ -96,20 +101,24 @@
self.setup_failure_recovery()
functype = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
decode_registers_addr = llhelper(functype, self.failure_recovery_func)
- self.mc.PUSH(range(12)) # registers r0 .. r11
+ self.mc.PUSH([reg.value for reg in r.all_regs]) # registers r0 .. r10
self.mc.MOV_rr(r.r0.value, r.lr.value) # move mem block address, to r0 to pass as
# parameter to next procedure call
self.mc.MOV_rr(r.r1.value, r.sp.value) # pass the current stack pointer as second param
self.mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
self.mc.MOV_rr(r.ip.value, r.r0.value)
- self.mc.LDM(r.sp.value, range(12), w=1) # XXX Replace with POP instr. someday
-
+ self.mc.LDM(r.sp.value, [reg.value for reg in r.all_regs], w=1) # XXX Replace with POP instr. someday
self.mc.MOV_rr(r.r0.value, r.ip.value)
-
self.gen_func_epilog()
def _gen_path_to_exit_path(self, op, args, regalloc, fcond=c.AL):
+ """
+ \xFC = stack location
+ \xFD = imm location
+ \xFE = Empty arg
+ """
+
box = Box()
reg = regalloc.force_allocate_reg(box)
# XXX free this memory
@@ -118,13 +127,18 @@
j = 0
while(i < len(args)):
if args[i]:
- if not isinstance(args[i], ConstInt):
- curreg = regalloc.make_sure_var_in_reg(args[i])
- mem[j] = chr(curreg.value)
+ loc = regalloc.loc(args[i])
+ if loc.is_reg():
+ mem[j] = chr(loc.value)
j += 1
- else:
+ elif loc.is_imm():
mem[j] = '\xFD'
- self.encode32(mem, j+1, args[i].getint())
+ self.encode32(mem, j+1, loc.getint())
+ j += 5
+ else:
+ #print 'Encoding a stack location'
+ mem[j] = '\xFC'
+ self.encode32(mem, j+1, loc.position)
j += 5
else:
mem[j] = '\xFE'
@@ -152,11 +166,14 @@
while(self.mc.curraddr() % FUNC_ALIGN != 0):
self.mc.writechar(chr(0))
+ epilog_size = 2*WORD
def gen_func_epilog(self,cond=c.AL):
+ self.mc.MOV_rr(r.sp.value, r.fp.value)
self.mc.LDM(r.sp.value, [reg.value for reg in r.callee_restored_registers], cond=cond, w=1)
def gen_func_prolog(self):
self.mc.PUSH([reg.value for reg in r.callee_saved_registers])
+ self.mc.MOV_rr(r.fp.value, r.sp.value)
def gen_bootstrap_code(self, inputargs, regalloc, looptoken):
regs = []
@@ -175,6 +192,10 @@
self.align()
loop_start=self.mc.curraddr()
self.gen_func_prolog()
+ # XXX
+ #Patch the sp with a correct value
+ self.mc.SUB_ri(r.sp.value, r.sp.value, 10*WORD)
+ # END
self.gen_bootstrap_code(inputargs, regalloc, looptoken)
loop_head=self.mc.curraddr()
looptoken._arm_bootstrap_code = loop_start
@@ -185,7 +206,7 @@
# XXX consider merging ops with next one if it is an adecuate guard
opnum = op.getopnum()
fcond = self.operations[opnum](self, op, regalloc, fcond)
- self.gen_func_epilog()
+ #self.gen_func_epilog()
if self._debug_asm:
self._dump_trace('loop.asm')
print 'Done assembling'
@@ -213,9 +234,13 @@
def _dump_trace(self, name):
self.mc._dump_trace(name)
- def _check_imm_arg(self, arg, size=0xFF):
+ def _check_imm_arg(self, arg, size=0xFF, allow_zero=True):
+ if allow_zero:
+ lower_bound = arg.getint() >= 0
+ else:
+ lower_bound = arg.getint() > 0
#XXX check ranges for different operations
- return isinstance(arg, ConstInt) and arg.getint() <= size and arg.getint() > 0
+ return isinstance(arg, ConstInt) and arg.getint() <= size and lower_bound
def patch_trace(self, faildescr, bridge_addr):
# XXX make sure there is enough space at patch target
@@ -228,8 +253,13 @@
if prev_loc.is_imm():
# XXX check size of imm for current instr
self.mc.gen_load_int(loc.value, prev_loc.getint())
+ elif loc.is_stack():
+ self.mc.STR_ri(prev_loc.value, r.fp.value, loc.position*-WORD)
+ elif prev_loc.is_stack():
+ self.mc.LDR_ri(loc.value, r.fp.value, prev_loc.position*-WORD)
else:
self.mc.MOV_rr(loc.value, prev_loc.value)
+ mov_loc_loc = regalloc_mov
def make_operation_list():
def notimplemented(self, op, regalloc, fcond):
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py Wed Nov 3 15:10:37 2010
@@ -13,27 +13,29 @@
return fcond
return f
-def gen_emit_op_ri(opname, imm_size=0xFF, commutative=True):
+def gen_emit_op_ri(opname, imm_size=0xFF, commutative=True, allow_zero=True):
def f(self, op, regalloc, fcond):
ri_op = getattr(self.mc, '%s_ri' % opname)
rr_op = getattr(self.mc, '%s_rr' % opname)
arg0 = op.getarg(0)
arg1 = op.getarg(1)
- imm_a0 = self._check_imm_arg(arg0, imm_size)
- imm_a1 = self._check_imm_arg(arg1, imm_size)
- res = regalloc.force_allocate_reg(op.result)
+ imm_a0 = self._check_imm_arg(arg0, imm_size, allow_zero=allow_zero)
+ imm_a1 = self._check_imm_arg(arg1, imm_size, allow_zero=allow_zero)
if commutative and imm_a0:
l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=imm_a0)
l1 = regalloc.make_sure_var_in_reg(arg1)
+ res = regalloc.force_allocate_reg(op.result)
ri_op(res.value, l1.value, imm=l0.getint(), cond=fcond)
elif imm_a1:
l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=False)
l1 = regalloc.make_sure_var_in_reg(arg1, imm_fine=True)
+ res = regalloc.force_allocate_reg(op.result)
ri_op(res.value, l0.value, imm=l1.getint(), cond=fcond)
else:
l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=False)
l1 = regalloc.make_sure_var_in_reg(arg1, imm_fine=False)
+ res = regalloc.force_allocate_reg(op.result)
rr_op(res.value, l0.value, l1.value)
regalloc.possibly_free_vars_for_op(op)
return fcond
@@ -61,17 +63,18 @@
else:
arg0 = op.getarg(1)
arg1 = op.getarg(0)
- res = regalloc.force_allocate_reg(op.result)
# XXX consider swapping argumentes if arg0 is const
imm_a0 = self._check_imm_arg(arg0)
imm_a1 = self._check_imm_arg(arg1)
if imm_a1 and not imm_a0:
l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=False)
- l1 = regalloc.make_sure_var_in_reg(arg1)
+ l1 = regalloc.make_sure_var_in_reg(arg1, [l0])
+ res = regalloc.force_allocate_reg(op.result)
self.mc.CMP_ri(l0.value, imm=l1.getint(), cond=fcond)
else:
l0 = regalloc.make_sure_var_in_reg(arg0, imm_fine=False)
- l1 = regalloc.make_sure_var_in_reg(arg1, imm_fine=False)
+ l1 = regalloc.make_sure_var_in_reg(arg1, [l0], imm_fine=False)
+ res = regalloc.force_allocate_reg(op.result)
self.mc.CMP_rr(l0.value, l1.value)
inv = c.get_opposite_of(condition)
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/locations.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/locations.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/locations.py Wed Nov 3 15:10:37 2010
@@ -1,8 +1,16 @@
+from pypy.jit.metainterp.history import INT
+from pypy.jit.backend.arm.arch import WORD
class AssemblerLocation(object):
pass
def is_imm(self):
return False
+ def is_stack(self):
+ return False
+
+ def is_reg(self):
+ return False
+
class RegisterLocation(AssemblerLocation):
def __init__(self, value):
@@ -11,6 +19,9 @@
def __repr__(self):
return 'r%d' % self.value
+ def is_reg(self):
+ return True
+
class ImmLocation(AssemblerLocation):
_immutable_ = True
def __init__(self, value):
@@ -20,7 +31,32 @@
return self.value
def __repr__(self):
- return "ImmedLoc(%d)" % (self.value)
+ return "imm(%d)" % (self.value)
def is_imm(self):
return True
+
+class StackLocation(AssemblerLocation):
+ _immutable_ = True
+ def __init__(self, position, num_words=1, type=INT):
+ self.position = position
+ self.width = num_words * WORD
+ # One of INT, REF, FLOAT
+ assert num_words == 1
+ assert type == INT
+ #self.type = type
+
+ def frame_size(self):
+ return self.width // WORD
+
+ def __repr__(self):
+ return 'SP+%d' % (self.position,)
+
+ def location_code(self):
+ return 'b'
+
+ def assembler(self):
+ return repr(self)
+
+ def is_stack(self):
+ return True
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py Wed Nov 3 15:10:37 2010
@@ -21,19 +21,17 @@
def emit_op_int_add(self, op, regalloc, fcond):
# assuming only one argument is constant
- res = regalloc.force_allocate_reg(op.result)
a0 = op.getarg(0)
a1 = op.getarg(1)
imm_a0 = isinstance(a0, ConstInt) and (a0.getint() <= 0xFF or -1 * a0.getint() <= 0xFF)
imm_a1 = isinstance(a1, ConstInt) and (a1.getint() <= 0xFF or -1 * a1.getint() <= 0xFF)
- l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=imm_a0)
- l1 = regalloc.make_sure_var_in_reg(a1, imm_fine=imm_a1)
if imm_a0:
imm_a0, imm_a1 = imm_a1, imm_a0
a0, a1 = a1, a0
if imm_a1:
l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
l1 = regalloc.make_sure_var_in_reg(a1, imm_fine=True)
+ res = regalloc.force_allocate_reg(op.result)
if l1.getint() < 0:
self.mc.SUB_ri(res.value, l0.value, -1 * l1.getint())
else:
@@ -41,6 +39,7 @@
else:
l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
l1 = regalloc.make_sure_var_in_reg(a1, imm_fine=False)
+ res = regalloc.force_allocate_reg(op.result)
self.mc.ADD_rr(res.value, l0.value, l1.value)
regalloc.possibly_free_vars_for_op(op)
@@ -48,13 +47,13 @@
def emit_op_int_sub(self, op, regalloc, fcond):
# assuming only one argument is constant
- res = regalloc.force_allocate_reg(op.result)
a0 = op.getarg(0)
a1 = op.getarg(1)
imm_a0 = isinstance(a0, ConstInt) and (a0.getint() <= 0xFF or -1 * a0.getint() <= 0xFF)
imm_a1 = isinstance(a1, ConstInt) and (a1.getint() <= 0xFF or -1 * a1.getint() <= 0xFF)
l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=imm_a0)
l1 = regalloc.make_sure_var_in_reg(a1, imm_fine=imm_a1)
+ res = regalloc.force_allocate_reg(op.result)
if imm_a0:
value = l0.getint()
if value < 0:
@@ -65,7 +64,7 @@
# reverse substract ftw
self.mc.RSB_ri(res.value, l1.value, value)
elif imm_a1:
- value = a1.getint()
+ value = l1.getint()
if value < 0:
self.mc.ADD_ri(res.value, l0.value, -1 * value)
else:
@@ -77,9 +76,9 @@
return fcond
def emit_op_int_mul(self, op, regalloc, fcond):
- res = regalloc.force_allocate_reg(op.result)
reg1 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
reg2 = regalloc.make_sure_var_in_reg(op.getarg(1), imm_fine=False)
+ res = regalloc.force_allocate_reg(op.result)
self.mc.MUL(res.value, reg1.value, reg2.value)
regalloc.possibly_free_vars_for_op(op)
return fcond
@@ -91,7 +90,7 @@
emit_op_int_and = gen_emit_op_ri('AND')
emit_op_int_or = gen_emit_op_ri('ORR')
emit_op_int_xor = gen_emit_op_ri('EOR')
- emit_op_int_lshift = gen_emit_op_ri('LSL', imm_size=0x1F, commutative=False)
+ emit_op_int_lshift = gen_emit_op_ri('LSL', imm_size=0x1F, allow_zero=False, commutative=False)
emit_op_int_rshift = gen_emit_op_ri('ASR', imm_size=0x1F, commutative=False)
emit_op_uint_rshift = gen_emit_op_ri('LSR', imm_size=0x1F, commutative=False)
@@ -143,6 +142,7 @@
descr._failure_recovery_code = memaddr
descr._arm_guard_cond = fcond
descr._arm_guard_size = self.mc.curraddr() - descr._arm_guard_code
+ regalloc.possibly_free_vars_for_op(op)
def emit_op_guard_true(self, op, regalloc, fcond):
assert fcond == c.LE
@@ -162,10 +162,11 @@
def emit_op_jump(self, op, regalloc, fcond):
registers = op.getdescr()._arm_arglocs
for i in range(op.numargs()):
- #XXX we are assuming that every value is in a register for now
- reg = regalloc.make_sure_var_in_reg(op.getarg(i), imm_fine=False)
- inpreg = registers[i]
- self.mc.MOV_rr(inpreg.value, reg.value)
+ # avoid moving stuff twice
+ loc = registers[i]
+ prev_loc = regalloc.loc(op.getarg(i))
+ self.mov_loc_loc(prev_loc, loc)
+
loop_code = op.getdescr()._arm_loop_code
self.mc.B(loop_code, fcond)
return fcond
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py Wed Nov 3 15:10:37 2010
@@ -15,6 +15,7 @@
def update_bindings(self, enc, inputargs):
j = 0
for i in range(len(inputargs)):
+ # XXX decode imm and and stack locs
while enc[j] == '\xFE':
j += 1
self.force_allocate_reg(inputargs[i], selected_reg=r.all_regs[ord(enc[j])])
@@ -24,6 +25,11 @@
return locations.ImmLocation(c.value)
class ARMFrameManager(FrameManager):
+ def __init__(self):
+ FrameManager.__init__(self)
+ self.frame_depth = 1
+
@staticmethod
def frame_pos(loc, type):
- pass
+ # XXX for now we only have one word stack locs
+ return locations.StackLocation(loc)
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py Wed Nov 3 15:10:37 2010
@@ -10,7 +10,7 @@
lr = r14
pc = r15
-all_regs = registers[:12]
+all_regs = registers[:11]
callee_resp = [r4, r5, r6, r7, r8, r9, r10, r11]
callee_saved_registers = callee_resp+[lr]
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py Wed Nov 3 15:10:37 2010
@@ -113,7 +113,8 @@
loop_head = self.a.mc.curraddr()
self.a.mc.ADD_ri(r.r1.value, r.r1.value, 1)
self.a.mc.CMP_ri(r.r1.value, 9)
- self.a.mc.LDR_ri(r.pc.value, r.pc.value, imm=4, cond=c.NE)
+ self.a.mc.LDR_ri(r.pc.value, r.pc.value,
+ imm=self.a.epilog_size, cond=c.NE) # we want to read after the last instr. of gen_func_prolog
self.a.mc.MOV_rr(r.r0.value, r.r1.value)
self.a.gen_func_epilog()
self.a.mc.write32(loop_head)
More information about the Pypy-commit
mailing list