Author: Armin Rigo <[email protected]>
Branch: portable-threadlocal
Changeset: r74653:c97dcdd74131
Date: 2014-11-23 16:26 +0100
http://bitbucket.org/pypy/pypy/changeset/c97dcdd74131/
Log: in-progress: ARM support
diff --git a/rpython/jit/backend/arm/assembler.py
b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -497,9 +497,11 @@
if self.cpu.supports_floats:
mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers],
cond=cond)
- # pop all callee saved registers and IP to keep the alignment
+ # pop all callee saved registers. This pops 'pc' last.
+ # It also pops the threadlocal_addr back into 'r1', but it
+ # is not needed any more and will be discarded.
mc.POP([reg.value for reg in r.callee_restored_registers] +
- [r.ip.value], cond=cond)
+ [r.r1.value], cond=cond)
mc.BKPT()
def gen_func_prolog(self):
@@ -508,11 +510,16 @@
if self.cpu.supports_floats:
stack_size += len(r.callee_saved_vfp_registers) * 2 * WORD
- # push all callee saved registers and IP to keep the alignment
+ # push all callee saved registers including lr; and push r1 as
+ # well, which contains the threadlocal_addr argument. Note that
+ # we're pushing a total of 10 words, which keeps the stack aligned.
self.mc.PUSH([reg.value for reg in r.callee_saved_registers] +
- [r.ip.value])
+ [r.r1.value])
+ self.saved_threadlocal_addr = 0 # at offset 0 from location 'sp'
if self.cpu.supports_floats:
self.mc.VPUSH([reg.value for reg in r.callee_saved_vfp_registers])
+ self.saved_threadlocal_addr += (
+ len(r.callee_saved_vfp_registers) * 2 * WORD)
assert stack_size % 8 == 0 # ensure we keep alignment
# set fp to point to the JITFRAME
@@ -952,16 +959,11 @@
regalloc._check_invariants()
self.mc.mark_op(None) # end of the loop
- def regalloc_emit_llong(self, op, arglocs, fcond, regalloc):
+ def regalloc_emit_extra(self, op, arglocs, fcond, regalloc):
+ # for calls to a function with a specifically-supported OS_xxx
effectinfo = op.getdescr().get_extra_info()
oopspecindex = effectinfo.oopspecindex
- asm_llong_operations[oopspecindex](self, op, arglocs, regalloc, fcond)
- return fcond
-
- def regalloc_emit_math(self, op, arglocs, fcond, regalloc):
- effectinfo = op.getdescr().get_extra_info()
- oopspecindex = effectinfo.oopspecindex
- asm_math_operations[oopspecindex](self, op, arglocs, regalloc, fcond)
+ asm_extra_operations[oopspecindex](self, op, arglocs, regalloc, fcond)
return fcond
def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc):
@@ -1509,22 +1511,17 @@
asm_operations = [notimplemented_op] * (rop._LAST + 1)
asm_operations_with_guard = [notimplemented_op_with_guard] * (rop._LAST + 1)
-asm_llong_operations = {}
-asm_math_operations = {}
+asm_extra_operations = {}
for name, value in ResOpAssembler.__dict__.iteritems():
if name.startswith('emit_guard_'):
opname = name[len('emit_guard_'):]
num = getattr(rop, opname.upper())
asm_operations_with_guard[num] = value
- elif name.startswith('emit_op_llong_'):
- opname = name[len('emit_op_llong_'):]
- num = getattr(EffectInfo, 'OS_LLONG_' + opname.upper())
- asm_llong_operations[num] = value
- elif name.startswith('emit_op_math_'):
- opname = name[len('emit_op_math_'):]
- num = getattr(EffectInfo, 'OS_MATH_' + opname.upper())
- asm_math_operations[num] = value
+ elif name.startswith('emit_opx_'):
+ opname = name[len('emit_opx_'):]
+ num = getattr(EffectInfo, 'OS_' + opname.upper())
+ asm_extra_operations[num] = value
elif name.startswith('emit_op_'):
opname = name[len('emit_op_'):]
num = getattr(rop, opname.upper())
diff --git a/rpython/jit/backend/arm/opassembler.py
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -19,7 +19,7 @@
from rpython.jit.backend.arm.codebuilder import InstrBuilder,
OverwritingBuilder
from rpython.jit.backend.arm.jump import remap_frame_layout
from rpython.jit.backend.arm.regalloc import TempBox
-from rpython.jit.backend.arm.locations import imm
+from rpython.jit.backend.arm.locations import imm, RawSPStackLocation
from rpython.jit.backend.llsupport import symbolic
from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
from rpython.jit.backend.llsupport.descr import InteriorFieldDescr
@@ -971,7 +971,9 @@
return fcond
def _call_assembler_emit_call(self, addr, argloc, resloc):
- self.simple_call(addr, [argloc], result_loc=resloc)
+ ofs = self.saved_threadlocal_addr
+ threadlocal_loc = RawSPStackLocation(ofs, INT)
+ self.simple_call(addr, [argloc, threadlocal_loc], result_loc=resloc)
def _call_assembler_emit_helper_call(self, addr, arglocs, resloc):
self.simple_call(addr, arglocs, result_loc=resloc)
@@ -1097,7 +1099,7 @@
emit_op_float_neg = gen_emit_unary_float_op('float_neg', 'VNEG')
emit_op_float_abs = gen_emit_unary_float_op('float_abs', 'VABS')
- emit_op_math_sqrt = gen_emit_unary_float_op('math_sqrt', 'VSQRT')
+ emit_opx_math_sqrt = gen_emit_unary_float_op('math_sqrt', 'VSQRT')
emit_op_float_lt = gen_emit_float_cmp_op('float_lt', c.VFP_LT)
emit_op_float_le = gen_emit_float_cmp_op('float_le', c.VFP_LE)
@@ -1131,13 +1133,13 @@
# the following five instructions are only ARMv7;
# regalloc.py won't call them at all on ARMv6
- emit_op_llong_add = gen_emit_float_op('llong_add', 'VADD_i64')
- emit_op_llong_sub = gen_emit_float_op('llong_sub', 'VSUB_i64')
- emit_op_llong_and = gen_emit_float_op('llong_and', 'VAND_i64')
- emit_op_llong_or = gen_emit_float_op('llong_or', 'VORR_i64')
- emit_op_llong_xor = gen_emit_float_op('llong_xor', 'VEOR_i64')
+ emit_opx_llong_add = gen_emit_float_op('llong_add', 'VADD_i64')
+ emit_opx_llong_sub = gen_emit_float_op('llong_sub', 'VSUB_i64')
+ emit_opx_llong_and = gen_emit_float_op('llong_and', 'VAND_i64')
+ emit_opx_llong_or = gen_emit_float_op('llong_or', 'VORR_i64')
+ emit_opx_llong_xor = gen_emit_float_op('llong_xor', 'VEOR_i64')
- def emit_op_llong_to_int(self, op, arglocs, regalloc, fcond):
+ def emit_opx_llong_to_int(self, op, arglocs, regalloc, fcond):
loc = arglocs[0]
res = arglocs[1]
assert loc.is_vfp_reg()
@@ -1271,3 +1273,9 @@
regalloc.rm.possibly_free_var(length_box)
regalloc.rm.possibly_free_var(dstaddr_box)
return fcond
+
+ def emit_opx_threadlocalref_addr(self, op, arglocs, regalloc, fcond):
+ res, = arglocs
+ ofs = self.saved_threadlocal_addr
+ self.load_reg(self.mc, res, r.sp, ofs)
+ return fcond
diff --git a/rpython/jit/backend/arm/regalloc.py
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -373,11 +373,8 @@
return gcmap
# ------------------------------------------------------------
- def perform_llong(self, op, args, fcond):
- return self.assembler.regalloc_emit_llong(op, args, fcond, self)
-
- def perform_math(self, op, args, fcond):
- return self.assembler.regalloc_emit_math(op, args, self, fcond)
+ def perform_extra(self, op, args, fcond):
+ return self.assembler.regalloc_emit_extra(op, args, fcond, self)
def force_spill_var(self, var):
if var.type == FLOAT:
@@ -552,15 +549,19 @@
EffectInfo.OS_LLONG_XOR):
if self.cpu.cpuinfo.arch_version >= 7:
args = self._prepare_llong_binop_xx(op, fcond)
- self.perform_llong(op, args, fcond)
+ self.perform_extra(op, args, fcond)
return
elif oopspecindex == EffectInfo.OS_LLONG_TO_INT:
args = self._prepare_llong_to_int(op, fcond)
- self.perform_llong(op, args, fcond)
+ self.perform_extra(op, args, fcond)
return
elif oopspecindex == EffectInfo.OS_MATH_SQRT:
- args = self.prepare_op_math_sqrt(op, fcond)
- self.perform_math(op, args, fcond)
+ args = self._prepare_op_math_sqrt(op, fcond)
+ self.perform_extra(op, args, fcond)
+ return
+ elif oopspecindex == EffectInfo.OS_THREADLOCALREF_ADDR:
+ args = self._prepare_threadlocalref_addr(op, fcond)
+ self.perform_extra(op, args, fcond)
return
#elif oopspecindex == EffectInfo.OS_MATH_READ_TIMESTAMP:
# ...
@@ -618,6 +619,10 @@
res = self.force_allocate_reg(op.result)
return [loc0, res]
+ def _prepare_threadlocalref_addr(self, op, fcond):
+ res = self.force_allocate_reg(op.result)
+ return [res]
+
def _prepare_guard(self, op, args=None):
if args is None:
args = []
@@ -1278,7 +1283,7 @@
prepare_guard_float_ge = prepare_float_op(guard=True,
float_result=False, name='prepare_guard_float_ge')
- def prepare_op_math_sqrt(self, op, fcond):
+ def _prepare_op_math_sqrt(self, op, fcond):
loc = self.make_sure_var_in_reg(op.getarg(1))
self.possibly_free_vars_for_op(op)
self.free_temp_vars()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit