Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit