[pypy-svn] pypy arm-backed-float: start extending the calling convention implementation to support floats
bivab
commits-noreply at bitbucket.org
Fri Apr 1 11:03:14 CEST 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backed-float
Changeset: r43071:44a933e393c8
Date: 2011-03-31 16:00 +0200
http://bitbucket.org/pypy/pypy/changeset/44a933e393c8/
Log: start extending the calling convention implementation to support
floats
diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -641,6 +641,10 @@
assert 0, 'unsupported case'
elif loc.is_reg() and prev_loc.is_reg():
self.mc.MOV_rr(loc.value, prev_loc.value, cond=cond)
+ elif loc.is_reg() and prev_loc.is_vfp_reg():
+ self.mc.VMOV_rc(loc.value, prev_loc.value, cond=cond)
+ elif loc.is_vfp_reg() and prev_loc.is_reg():
+ self.mc.VMOV_cr(loc.value, prev_loc.value, cond=cond)
else:
assert 0, 'unsupported case'
mov_loc_loc = regalloc_mov
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -248,7 +248,8 @@
descr = op.getdescr()
#XXX Hack, Hack, Hack
if op.result and not we_are_translated() and not isinstance(descr, LoopToken):
- loc = regalloc.call_result_location(op.result)
+ #XXX check result type
+ loc = regalloc.rm.call_result_location(op.result)
size = descr.get_result_size(False)
signed = descr.is_result_signed()
self._ensure_result_bit_extension(loc, size, signed)
@@ -258,13 +259,28 @@
# emit_op_call_may_force
# XXX improve freeing of stuff here
def _emit_call(self, adr, args, regalloc, fcond=c.AL, result=None):
- n = 0
n_args = len(args)
- reg_args = min(n_args, 4)
- # prepare arguments passed in registers
- for i in range(0, reg_args):
- l = regalloc.make_sure_var_in_reg(args[i],
- selected_reg=r.all_regs[i])
+ reg_args = 0
+ for x in range(min(n_args, 4)):
+ if args[x].type == FLOAT:
+ reg_args += 2
+ else:
+ reg_args += 1
+ if reg_args > 4:
+ reg_args = x - 1
+ break
+
+ # collect the locations of the arguments and spill those that are in
+ # the caller saved registers
+ locs = []
+ for v in range(reg_args):
+ var = args[v]
+ loc = regalloc.loc(var)
+ if loc in r.caller_resp:
+ regalloc.force_spill(var)
+ loc = regalloc.loc(var)
+ locs.append(loc)
+
# save caller saved registers
if result:
# XXX hack if the call has a result force the value in r0 to be
@@ -274,10 +290,25 @@
t = TempBox()
regalloc.force_allocate_reg(t, selected_reg=regalloc.call_result_location(t))
regalloc.possibly_free_var(t)
- saved_regs = r.caller_resp[1:]
+ if result.type == FLOAT:
+ saved_regs = r.caller_resp[2:]
+ else:
+ saved_regs = r.caller_resp[1:]
else:
saved_regs = r.caller_resp
- with saved_registers(self.mc, saved_regs, regalloc=regalloc):
+
+ with saved_registers(self.mc, saved_regs, r.caller_vfp_resp, regalloc):
+ # move variables to the argument registers
+ num = 0
+ for i in range(reg_args):
+ arg = args[i]
+ reg = r.all_regs[num]
+ self.mov_loc_loc(locs[i], reg)
+ if arg.type == FLOAT:
+ num += 2
+ else:
+ num += 1
+
# all arguments past the 4th go on the stack
if n_args > 4:
stack_args = n_args - 4
@@ -297,7 +328,13 @@
# restore the argumets stored on the stack
if result is not None:
- regalloc.after_call(result)
+ # support floats here
+ resloc = regalloc.after_call(result)
+ if result.type == FLOAT:
+ # XXX ugly and fragile
+ # move result to the allocated register
+ self.mov_loc_loc(resloc, r.r0)
+
return fcond
def emit_op_same_as(self, op, arglocs, regalloc, fcond):
@@ -683,7 +720,7 @@
jd = descr.outermost_jitdriver_sd
assert jd is not None
asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
- with saved_registers(self.mc, r.caller_resp[1:], regalloc=regalloc):
+ with saved_registers(self.mc, r.caller_resp[1:], r.caller_vfp_resp, regalloc=regalloc):
# resbox is allready in r0
self.mov_loc_loc(arglocs[1], r.r1)
self.mc.BL(asm_helper_adr)
diff --git a/pypy/jit/backend/arm/codebuilder.py b/pypy/jit/backend/arm/codebuilder.py
--- a/pypy/jit/backend/arm/codebuilder.py
+++ b/pypy/jit/backend/arm/codebuilder.py
@@ -72,6 +72,41 @@
| 0xB << 8
| nregs)
self.write32(instr)
+
+ def VMOV_rc(self, rt, dm, cond=cond.AL):
+ """This instruction copies two words from two ARM core registers into a
+ doubleword extension register, or from a doubleword extension register
+ to two ARM core registers.
+ This implementation is modified in way that it takes to consecutive
+ core registers (rt and rt+1)"""
+ rt2 = rt + 1
+ op = 1
+ instr = (cond << 28
+ | 0xC << 24
+ | 0x4 << 20
+ | op << 20
+ | (rt2 & 0xF) << 16
+ | (rt & 0xF) << 12
+ | 0xB << 8
+ | (dm & 0xF))
+
+ # VMOV<c> <Dm>, <Rt>, <Rt2>
+ def VMOV_cr(self, dm, rt, cond=cond.AL):
+ """This instruction copies two words from two ARM core registers into a
+ doubleword extension register, or from a doubleword extension register
+ to two ARM core registers.
+ This implementation is modified in way that it takes to consecutive
+ core registers (rt and rt+1)"""
+ rt2 = rt + 1
+ op = 0
+ instr = (cond << 28
+ | 0xC << 24
+ | 0x4 << 20
+ | op << 20
+ | (rt2 & 0xF) << 16
+ | (rt & 0xF) << 12
+ | 0xB << 8
+ | (dm & 0xF))
def VCVT_float_to_int(self, target, source, cond=cond.AL):
opc2 = 0x5
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -69,6 +69,13 @@
def __init__(self, longevity, frame_manager=None, assembler=None):
RegisterManager.__init__(self, longevity, frame_manager, assembler)
+ def after_call(self, v):
+ """ Adjust registers according to the result of the call,
+ which is in variable v.
+ """
+ self._check_type(v)
+ r = self.force_allocate_reg(v)
+ return r
class ARMv7RegisterMananger(RegisterManager):
all_regs = r.all_regs
box_types = None # or a list of acceptable types
@@ -136,6 +143,12 @@
else:
return self.rm.stays_alive(v)
+ def call_result_location(self, v):
+ if v.type == FLOAT:
+ return self.vfprm.call_result_location(v)
+ else:
+ return self.rm.call_result_location(v)
+
def after_call(self, v):
if v.type == FLOAT:
return self.vfprm.after_call(v)
More information about the Pypy-commit
mailing list