[pypy-commit] pypy arm-backend-2: load 32-bit constants in two instructions
bivab
noreply at buildbot.pypy.org
Wed Jul 13 11:01:44 CEST 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r45524:69b3c1536bfc
Date: 2011-07-09 17:01 +0200
http://bitbucket.org/pypy/pypy/changeset/69b3c1536bfc/
Log: load 32-bit constants in two instructions
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
@@ -178,9 +178,28 @@
self.write32(target)
else:
self.gen_load_int(reg.ip.value, target, cond=c)
- self.ADD_ri(reg.lr.value, reg.pc.value, arch.PC_OFFSET/2)
+ self.MOV_rr(reg.lr.value, reg.pc.value, cond=c)
self.MOV_rr(reg.pc.value, reg.ip.value, cond=c)
+ def MOVT_ri(self, rd, imm16, c=cond.AL):
+ """Move Top writes an immediate value to the top halfword of the
+ destination register. It does not affect the contents of the bottom
+ halfword."""
+ self.write32(c << 28
+ | 0x3 << 24
+ | (1 << 22)
+ | ((imm16 >> 12) & 0xF) << 16
+ | (rd & 0xF) << 12
+ | imm16 & 0xFFF)
+
+ def MOVW_ri(self, rd, imm16, c=cond.AL):
+ """Encoding A2 of MOV, that allow to load a 16 bit constant"""
+ self.write32(c << 28
+ | 0x3 << 24
+ | ((imm16 >> 12) & 0xF) << 16
+ | (rd & 0xF) << 12
+ | imm16 & 0xFFF)
+
DIV = binary_helper_call('int_div')
MOD = binary_helper_call('int_mod')
UDIV = binary_helper_call('uint_div')
@@ -209,30 +228,15 @@
def currpos(self):
raise NotImplementedError
- size_of_gen_load_int = 3 * WORD
+ size_of_gen_load_int = 2 * WORD
def gen_load_int(self, r, value, cond=cond.AL):
"""r is the register number, value is the value to be loaded to the
register"""
- from pypy.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)
-
- #size_of_gen_load_int = 4 * WORD
- 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
- self.MOV_ri(r, (value & 0xFF), cond=c)
- for offset, shift in self.ofs_shift:
- b = (value >> offset) & 0xFF
- if b == 0:
- continue
- t = b | (shift << 8)
- self.ORR_ri(r, r, imm=t, cond=c)
+ bottom = value & 0xFFFF
+ top = value >> 16
+ self.MOVW_ri(r, bottom, cond)
+ if top:
+ self.MOVT_ri(r, top, cond)
class OverwritingBuilder(AbstractARMv7Builder):
def __init__(self, cb, start, size):
diff --git a/pypy/jit/backend/arm/test/test_instr_codebuilder.py b/pypy/jit/backend/arm/test/test_instr_codebuilder.py
--- a/pypy/jit/backend/arm/test/test_instr_codebuilder.py
+++ b/pypy/jit/backend/arm/test/test_instr_codebuilder.py
@@ -156,6 +156,14 @@
self.cb.VMRS(conditions.AL)
self.assert_equal("vmrs APSR_nzcv, fpscr")
+ def test_movw(self):
+ self.cb.MOVW_ri(r.r3.value, 0xFFFF, conditions.NE)
+ self.assert_equal("MOVWNE r3, #65535")
+
+ def test_movt(self):
+ self.cb.MOVT_ri(r.r3.value, 0xFFFF, conditions.NE)
+ self.assert_equal("MOVTNE r3, #65535")
+
class TestInstrCodeBuilderForGeneratedInstr(ASMTest):
def setup_method(self, ffuu_method):
self.cb = CodeBuilder()
More information about the pypy-commit
mailing list