Author: David Schneider <[email protected]>
Branch:
Changeset: r62925:2b5f633c5e12
Date: 2013-04-02 19:27 +0200
http://bitbucket.org/pypy/pypy/changeset/2b5f633c5e12/
Log: Store architecture version on cpu and use the value at runtime to
choose which instructions to emit (so far only in gen_load_int).
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
@@ -59,7 +59,7 @@
if we_are_translated():
self.debug = False
self.current_clt = looptoken.compiled_loop_token
- self.mc = InstrBuilder()
+ self.mc = InstrBuilder(self.cpu.arch_version)
self.pending_guards = []
assert self.datablockwrapper is None
allblocks = self.get_asmmemmgr_blocks(looptoken)
@@ -156,7 +156,7 @@
if not self.cpu.propagate_exception_descr:
return # not supported (for tests, or non-translated)
#
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
self._store_and_reset_exception(mc, r.r0)
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
# make sure ofs fits into a register
@@ -241,7 +241,7 @@
# | my own retaddr | <-- sp
# +-----------------------+
#
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
# save argument registers and return address
mc.PUSH([reg.value for reg in r.argument_regs] + [r.ip.value,
r.lr.value])
# stack is aligned here
@@ -282,7 +282,7 @@
# write barriers. It must save all registers, and optionally
# all vfp registers. It takes a single argument which is in r0.
# It must keep stack alignment accordingly.
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
#
exc0 = exc1 = None
mc.PUSH([r.ip.value, r.lr.value]) # push two words to keep alignment
@@ -326,7 +326,7 @@
self.wb_slowpath[withcards + 2 * withfloats] = rawstart
def _build_malloc_slowpath(self):
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
self._push_all_regs_to_jitframe(mc, [r.r0, r.r1],
self.cpu.supports_floats)
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
# store the gc pattern
@@ -438,7 +438,7 @@
self.load_reg(mc, vfpr, r.fp, ofs)
def _build_failure_recovery(self, exc, withfloats=False):
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
self._push_all_regs_to_jitframe(mc, [], withfloats)
if exc:
@@ -732,7 +732,7 @@
mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs)
stack_check_cmp_ofs = mc.currpos()
if expected_size == -1:
- for _ in range(mc.max_size_of_gen_load_int):
+ for _ in range(mc.get_max_size_of_gen_load_int()):
mc.NOP()
else:
mc.gen_load_int(r.lr.value, expected_size)
@@ -765,7 +765,7 @@
# f) store the address of the new jitframe in the shadowstack
# c) set the gcmap field to 0 in the new jitframe
# g) restore registers and return
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats)
# this is the gcmap stored by push_gcmap(mov=True) in
_check_stack_frame
# and the expected_size pushed in _check_stack_frame
@@ -825,7 +825,7 @@
self.target_tokens_currently_compiling = None
def _patch_stackadjust(self, adr, allocated_depth):
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
mc.gen_load_int(r.lr.value, allocated_depth)
mc.copy_to_raw_memory(adr)
@@ -861,7 +861,7 @@
# patch the guard jumpt to the stub
# overwrite the generate NOP with a B_offs to the pos of the
# stub
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
mc.B_offs(relative_offset, c.get_opposite_of(tok.fcond))
mc.copy_to_raw_memory(guard_pos)
else:
@@ -940,7 +940,7 @@
self.mc.ASR_ri(resloc.value, resloc.value, 16)
def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc):
- b = InstrBuilder()
+ b = InstrBuilder(self.cpu.arch_version)
patch_addr = faildescr._arm_failure_recovery_block
assert patch_addr != 0
b.B(bridge_addr)
diff --git a/rpython/jit/backend/arm/codebuilder.py
b/rpython/jit/backend/arm/codebuilder.py
--- a/rpython/jit/backend/arm/codebuilder.py
+++ b/rpython/jit/backend/arm/codebuilder.py
@@ -28,10 +28,10 @@
return f
-class AbstractARMv7Builder(object):
+class AbstractARMBuilder(object):
- def __init__(self):
- pass
+ def __init__(self, arch_version=7):
+ self.arch_version = arch_version
def align(self):
while(self.currpos() % FUNC_ALIGN != 0):
@@ -250,8 +250,13 @@
def currpos(self):
raise NotImplementedError
- max_size_of_gen_load_int = 2
def gen_load_int(self, r, value, cond=cond.AL):
+ if self.arch_version < 7:
+ self.gen_load_int_v6(r, value, cond)
+ else:
+ self.gen_load_int_v7(r, value, cond)
+
+ def gen_load_int_v7(self, r, value, cond=cond.AL):
"""r is the register number, value is the value to be loaded to the
register"""
bottom = value & 0xFFFF
@@ -260,23 +265,20 @@
if top:
self.MOVT_ri(r, top, cond)
+ def gen_load_int_v6(self, r, value, cond=cond.AL):
+ from rpython.jit.backend.arm.conditions import AL
+ if cond != AL or 0 <= value <= 0xFFFF:
+ self._load_by_shifting(r, value, cond)
+ else:
+ self.LDR_ri(r, reg.pc.value)
+ self.MOV_rr(reg.pc.value, reg.pc.value)
+ self.write32(value)
-class AbstractARMv6Builder(AbstractARMv7Builder):
+ def get_max_size_of_gen_load_int(self):
+ return 4 if self.arch_version < 7 else 2
- def __init__(self):
- AbstractARMv7Builder.__init__(self)
+ ofs_shift = zip(range(8, 25, 8), range(12, 0, -4))
- def gen_load_int(self, r, value, cond=cond.AL):
- from rpython.jit.backend.arm.conditions import AL
- if cond != AL or 0 <= value <= 0xFFFF:
- self._load_by_shifting(r, value, cond)
- else:
- self.LDR_ri(r, reg.pc.value)
- self.MOV_rr(reg.pc.value, reg.pc.value)
- self.write32(value)
-
- max_size_of_gen_load_int = 4
- ofs_shift = zip(range(8, 25, 8), range(12, 0, -4))
def _load_by_shifting(self, r, value, c=cond.AL):
# to be sure it is only called for the correct cases
assert c != cond.AL or 0 <= value <= 0xFFFF
@@ -288,15 +290,10 @@
t = b | (shift << 8)
self.ORR_ri(r, r, imm=t, cond=c)
-if autodetect().startswith('armv7'):
- AbstractBuilder = AbstractARMv7Builder
-else:
- AbstractBuilder = AbstractARMv6Builder
-
-class OverwritingBuilder(AbstractBuilder):
+class OverwritingBuilder(AbstractARMBuilder):
def __init__(self, cb, start, size):
- AbstractBuilder.__init__(self)
+ AbstractARMBuilder.__init__(self, cb.arch_version)
self.cb = cb
self.index = start
self.end = start + size
@@ -310,9 +307,10 @@
self.index += 1
-class InstrBuilder(BlockBuilderMixin, AbstractBuilder):
- def __init__(self):
- AbstractBuilder.__init__(self)
+class InstrBuilder(BlockBuilderMixin, AbstractARMBuilder):
+
+ def __init__(self, arch_version=7):
+ AbstractARMBuilder.__init__(self, arch_version)
self.init_block_builder()
#
# ResOperation --> offset in the assembly.
@@ -366,4 +364,4 @@
return self.get_relative_pos()
-define_instructions(AbstractBuilder)
+define_instructions(AbstractARMBuilder)
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
@@ -1212,7 +1212,7 @@
baseofs = self.cpu.get_baseofs_of_frame_field()
newlooptoken.compiled_loop_token.update_frame_info(
oldlooptoken.compiled_loop_token, baseofs)
- mc = InstrBuilder()
+ mc = InstrBuilder(self.cpu.arch_version)
mc.B(target)
mc.copy_to_raw_memory(oldadr)
diff --git a/rpython/jit/backend/arm/runner.py
b/rpython/jit/backend/arm/runner.py
--- a/rpython/jit/backend/arm/runner.py
+++ b/rpython/jit/backend/arm/runner.py
@@ -26,6 +26,7 @@
frame_reg = fp
use_hf_abi = False # use hard float abi flag
+ arch_version = 7
def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
gcdescr=None):
@@ -88,8 +89,8 @@
old one that already has a bridge attached to it."""
from rpython.jit.backend.arm.codebuilder import InstrBuilder
- for jmp, tgt in looptoken.compiled_loop_token.invalidate_positions:
- mc = InstrBuilder()
+ for jmp, tgt in looptoken.compiled_loop_token.invalidate_positions:
+ mc = InstrBuilder(self.arch_version)
mc.B_offs(tgt)
mc.copy_to_raw_memory(jmp)
# positions invalidated
@@ -126,6 +127,7 @@
class CPU_ARMv6(AbstractARMCPU):
""" ARM v6, uses hardfp ABI, requires vfp"""
use_hf_abi = True
+ arch_version = 6
backend_name = "armv6hf"
supports_floats = False
supports_singlefloats = False
diff --git a/rpython/jit/backend/arm/test/test_instr_codebuilder.py
b/rpython/jit/backend/arm/test/test_instr_codebuilder.py
--- a/rpython/jit/backend/arm/test/test_instr_codebuilder.py
+++ b/rpython/jit/backend/arm/test/test_instr_codebuilder.py
@@ -12,7 +12,8 @@
requires_arm_as()
class CodeBuilder(codebuilder.InstrBuilder):
- def __init__(self):
+ def __init__(self, arch_version=7):
+ self.arch_version = arch_version
self.buffer = []
def writechar(self, char):
@@ -170,6 +171,13 @@
self.cb.MOVT_ri(r.r3.value, 0xFFFF, conditions.NE)
self.assert_equal("MOVTNE r3, #65535")
+
+def test_size_of_gen_load_int():
+ for v, n in [(5, 4), (6, 4), (7, 2)]:
+ c = CodeBuilder(v)
+ assert c.get_max_size_of_gen_load_int() == n
+
+
class TestInstrCodeBuilderForGeneratedInstr(ASMTest):
def setup_method(self, ffuu_method):
self.cb = CodeBuilder()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit