[pypy-svn] r78794 - in pypy/branch/arm-backend/pypy/jit/backend/arm: . test
david at codespeak.net
david at codespeak.net
Sat Nov 6 15:27:57 CET 2010
Author: david
Date: Sat Nov 6 15:27:56 2010
New Revision: 78794
Modified:
pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py
pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py
pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py
Log:
Implement extra load store instructions for half word and byte access and refactor tests a bit
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/instruction_builder.py Sat Nov 6 15:27:56 2010
@@ -30,6 +30,77 @@
| (w & 0x1) << 21
| reg_operation(rt, rn, rm, imm, s, shifttype))
return f
+
+def define_extra_load_store_func(name, table):
+ def check_registers(r1, r2):
+ assert r1 % 2 == 0
+ assert r1 + 1 == r2
+ assert r1 != 14
+
+ n = ((table['op1'] & 0x1F) << 20
+ | 0x1 << 7
+ | (table['op2'] & 0x3) << 5
+ | 0x1 << 4)
+ p = 1
+ w = 0
+ rncond = ('rn' in table and table['rn'] == '!0xF')
+ dual = (name[-4] == 'D')
+
+ if dual:
+ if name[-2:] == 'rr':
+ def f(self, rt, rt2, rn, rm, cond=cond.AL):
+ check_registers(rt, rt2)
+ assert not (rncond and rn == 0xF)
+ self.write32(n
+ | cond << 28
+ | (p & 0x1) << 24
+ | (1 & 0x1) << 23
+ | (w & 0x1) << 21
+ | (rn & 0xF) << 16
+ | (rt & 0xF) << 12
+ | (rm & 0xF))
+ else:
+ def f(self, rt, rt2, rn, imm=0, cond=cond.AL):
+ check_registers(rt, rt2)
+ assert not (rncond and rn == 0xF)
+ u, imm = self._encode_imm(imm)
+ self.write32(n
+ | cond << 28
+ | (p & 0x1) << 24
+ | (u & 0x1) << 23
+ | (w & 0x1) << 21
+ | (rn & 0xF) << 16
+ | (rt & 0xF) << 12
+ | ((imm >> 0x4) & 0xF) << 8
+ | (imm & 0xF))
+
+ else:
+ if name[-2:] == 'rr':
+ def f(self, rt, rn, rm, cond=cond.AL):
+ assert not (rncond and rn == 0xF)
+ self.write32(n
+ | cond << 28
+ | (p & 0x1) << 24
+ | (1 & 0x1) << 23
+ | (w & 0x1) << 21
+ | (rn & 0xF) << 16
+ | (rt & 0xF) << 12
+ | (rm & 0xF))
+ else:
+ def f(self, rt, rn, imm=0, cond=cond.AL):
+ assert not (rncond and rn == 0xF)
+ u, imm = self._encode_imm(imm)
+ self.write32(n
+ | cond << 28
+ | (p & 0x1) << 24
+ | (u & 0x1) << 23
+ | (w & 0x1) << 21
+ | (rn & 0xF) << 16
+ | (rt & 0xF) << 12
+ | ((imm >> 0x4) & 0xF) << 8
+ | (imm & 0xF))
+ return f
+
def define_data_proc_imm(name, table):
n = (0x1 << 25
| (table['op'] & 0x1F) << 20)
@@ -194,11 +265,11 @@
def reg_operation(rt, rn, rm, imm, s, shifttype):
# XXX encode shiftype correctly
return ((s & 0x1) << 20
- | (rn & 0xFF) << 16
- | (rt & 0xFF) << 12
+ | (rn & 0xF) << 16
+ | (rt & 0xF) << 12
| (imm & 0x1F) << 7
| (shifttype & 0x3) << 5
- | (rm & 0xFF))
+ | (rm & 0xF))
def define_instruction(builder, key, val, target):
f = builder(key, val)
@@ -206,6 +277,7 @@
def define_instructions(target):
i_g_map = [(instructions.load_store, define_load_store_func),
+ (instructions.extra_load_store, define_extra_load_store_func),
(instructions.data_proc, define_data_proc),
(instructions.data_proc_imm, define_data_proc_imm),
(instructions.supervisor_and_coproc, define_supervisor_and_coproc),
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/instructions.py Sat Nov 6 15:27:56 2010
@@ -10,6 +10,21 @@
'LDRB_ri': {'A':0, 'op1': 0x5, 'B': 0, 'imm': True},
'LDRB_rr': {'A':1, 'op1': 0x5, 'B': 0, 'imm': False},
}
+extra_load_store = { #Section 5.2.8
+ 'STRH_rr': {'op2': 0x1, 'op1': 0x0},
+ 'LDRH_rr': {'op2': 0x1, 'op1': 0x1},
+ 'STRH_ri': {'op2': 0x1, 'op1': 0x4},
+ 'LDRH_ri': {'op2': 0x1, 'op1': 0x5, 'rn':'!0xF'},
+ 'LDRD_rr': {'op2': 0x2, 'op1': 0x0},
+ 'LDRSB_rr': {'op2': 0x2, 'op1': 0x1},
+ 'LDRD_ri': {'op2': 0x2, 'op1': 0x4},
+ 'LDRSB_ri': {'op2': 0x2, 'op1': 0x5, 'rn':'!0xF'},
+ 'STRD_rr': {'op2': 0x3, 'op1': 0x0},
+ 'LDRSH_rr': {'op2': 0x3, 'op1': 0x1},
+ 'STRD_ri': {'op2': 0x3, 'op1': 0x4},
+ 'LDRSH_ri': {'op2': 0x3, 'op1': 0x5, 'rn':'!0xF'},
+}
+
data_proc = {
'AND_rr': {'op1':0x0, 'op2':0, 'op3':0, 'result':True, 'base':True},
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_instr_codebuilder.py Sat Nov 6 15:27:56 2010
@@ -52,9 +52,8 @@
self.assert_equal('MOV r9, #255')
def test_mov_ri_max(self):
- py.test.skip('Check the actual largest thing')
- self.cb.MOV_ri(r.r9.value, 0xFFF)
- self.assert_equal('MOV r9, #4095')
+ self.cb.MOV_ri(r.r9.value, 0xFF)
+ self.assert_equal('MOV r9, #255')
def test_str_ri(self):
self.cb.STR_ri(r.r9.value, r.r14.value)
@@ -109,9 +108,8 @@
self.assert_equal('SUB r2, r4, #123')
def test_sub_ri2(self):
- py.test.skip('XXX check the actual largest value')
- self.cb.SUB_ri(r.r3.value, r.r7.value, 0xFFF)
- self.assert_equal('SUB r3, r7, #4095')
+ self.cb.SUB_ri(r.r3.value, r.r7.value, 0xFF)
+ self.assert_equal('SUB r3, r7, #255')
def test_cmp_ri(self):
self.cb.CMP_ri(r.r3.value, 123)
@@ -157,6 +155,19 @@
test = builder(key, value)
setattr(TestInstrCodeBuilderForGeneratedInstr, test_name % key, test)
+def gen_test_function(name, asm, args, kwargs=None):
+ if kwargs is None:
+ kwargs = {}
+ def f(self):
+ func = getattr(self.cb, name)
+ func(*args, **kwargs)
+ try:
+ f_name = name[:name.index('_')]
+ except ValueError, e:
+ f_name = name
+ self.assert_equal(asm % f_name)
+ return f
+
def gen_test_data_proc_imm_func(name, table):
if table['result'] and table['base']:
def f(self):
@@ -164,32 +175,28 @@
func(r.r3.value, r.r7.value, 23)
self.assert_equal('%s r3, r7, #23' % name[:name.index('_')])
py.test.raises(ValueError, 'func(r.r3.value, r.r7.value, -12)')
- elif not table['base']:
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, 23)
- self.assert_equal('%s r3, #23' % name[:name.index('_')])
else:
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, 23)
- self.assert_equal('%s r3, #23' % name[:name.index('_')])
+ f = gen_test_function(name, '%s r3, #23', [r.r3.value, 23])
return f
def gen_test_imm_func(name, table):
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, r.r7.value, 23)
- self.assert_equal('%s r3, [r7, #23]' % name[:name.index('_')])
- return f
+ return gen_test_function(name, '%s r3, [r7, #23]', [r.r3.value, r.r7.value, 23])
def gen_test_reg_func(name, table):
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, r.r7.value, r.r12.value)
- self.assert_equal('%s r3, [r7, r12]' % name[:name.index('_')])
- return f
+ return gen_test_function(name, '%s r3, [r7, r12]', [r.r3.value, r.r7.value, r.r12.value])
+def gen_test_extra_load_store_func(name, table):
+ if name[-4] == 'D':
+ if name[-2:] == 'rr':
+ f = gen_test_function(name, '%s r4, [r8, r12]', [r.r4.value, r.r5.value, r.r8.value, r.r12.value])
+ else:
+ f = gen_test_function(name, '%s r4, [r8, #223]', [r.r4.value, r.r5.value, r.r8.value, 223])
+ else:
+ if name[-2:] == 'rr':
+ f = gen_test_function(name, '%s r4, [r5, r12]', [r.r4.value, r.r5.value, r.r12.value])
+ else:
+ f = gen_test_function(name, '%s r4, [r5, #223]', [r.r4.value, r.r5.value, 223])
+ return f
def gen_test_mul_func(name, table):
if 'acc' in table and table['acc']:
if 'update_flags' in table and table['update_flags']:
@@ -212,35 +219,20 @@
func(r.r3.value, r.r13.value, r.r7.value, r.r12.value)
self.assert_equal("""%(name)s r3, r13, r7, r12 """ % {'name':name})
else:
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, r.r7.value, r.r12.value)
- self.assert_equal("""%(name)s r3, r7, r12 """ % {'name':name})
+ f = gen_test_function(name, '%s r3, r7, r12 ', [r.r3.value, r.r7.value, r.r12.value])
return f
def gen_test_data_reg_shift_reg_func(name, table):
if name[-2:] == 'rr':
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, r.r7.value, r.r12.value)
- self.assert_equal('%s r3, r7, r12' % name[:name.index('_')])
-
+ f = gen_test_function(name, '%s r3, r7, r12', [r.r3.value, r.r7.value, r.r12.value])
else:
- if 'result' in table and not table['result']:
- result = False
- else:
- result = True
+ result = 'result' not in table or table['result']
if result:
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, r.r7.value, r.r8.value, r.r11.value, shifttype=0x2)
- self.assert_equal('%s r3, r7, r8, ASR r11' % name[:name.index('_')])
+ f = gen_test_function(name, '%s r3, r7, r8, ASR r11',
+ [r.r3.value, r.r7.value, r.r8.value, r.r11.value], {'shifttype':0x2})
else:
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, r.r7.value, r.r11.value, shifttype=0x2)
- self.assert_equal('%s r3, r7, ASR r11' % name[:name.index('_')])
-
+ f = gen_test_function(name, '%s r3, r7, ASR r11',
+ [r.r3.value, r.r7.value, r.r11.value], {'shifttype':0x2})
return f
def gen_test_data_reg_func(name, table):
@@ -263,10 +255,7 @@
%(name)sS r3, r7, r12
""" % {'name':op_name})
else:
- def f(self):
- func = getattr(self.cb, name)
- func(r.r3.value, r.r7.value)
- self.assert_equal("""%(name)s r3, r7""" % {'name':op_name})
+ f = gen_test_function(name, '%s r3, r7', [r.r3.value, r.r7.value])
return f
@@ -279,6 +268,9 @@
f = gen_test_reg_func
build_test(f, key, value, test_name)
+ for key, value in instructions.extra_load_store.iteritems():
+ build_test(gen_test_extra_load_store_func, key, value, 'test_extra_load_store_%s' % test_name)
+
for key, value, in instructions.data_proc.iteritems():
build_test(gen_test_data_reg_func, key, value, test_name)
More information about the Pypy-commit
mailing list