Author: Richard Plangger <[email protected]>
Branch: s390x-backend
Changeset: r80273:caf09586d9e8
Date: 2015-10-16 15:56 +0200
http://bitbucket.org/pypy/pypy/changeset/caf09586d9e8/
Log: work in progress commit, added argument types to provide correct
input for the test cases
diff --git a/rpython/jit/backend/zarch/codebuilder.py
b/rpython/jit/backend/zarch/codebuilder.py
--- a/rpython/jit/backend/zarch/codebuilder.py
+++ b/rpython/jit/backend/zarch/codebuilder.py
@@ -27,24 +27,31 @@
class Operand(object):
pass
-def arguments(args_str):
- """
- Available names:
- r - register
- i4 - immediate 4 bits (signed)
- u4 - immediate 4 bits (unsigend)
- bd - base displacement
- l4db - length base displacement (4 bit)
- l8db - length base displacement (8 bit)
- """
- def impl(func):
- func._arguments_ = args_str.split(',')
- return func
- return impl
+class builder(object):
+ """ NOT_RPYTHON """
+ @staticmethod
+ def arguments(args_str):
+ """ NOT_RPYTHON """
+ """
+ Available names:
+ r - register
+ r/m - register or mask
+ iX - immediate X bits (signed)
+ uX - immediate X bits (unsigend)
+ bd - base displacement
+ ibd - index base displacement
+ l4bd - length base displacement (4 bit)
+ l8bd - length base displacement (8 bit)
+ """
+ def impl(func):
+ func._arguments_ = args_str.split(',')
+ return func
+ return impl
BIT_MASK_4 = 0xF
BIT_MASK_12 = 0xFFF
BIT_MASK_20 = 0xFFFFF
+BIT_MASK_32 = 0xFFFFFFFF
@always_inline
def encode_base_displace(mc, base_displace):
@@ -55,6 +62,7 @@
mc.writechar(chr(displace & 0xff))
def build_rr(mnemonic, (opcode,)):
+ @builder.arguments('r,r')
def encode_rr(self, reg1, reg2):
self.writechar(opcode)
operands = ((reg1 & 0x0f) << 4) | (reg2 & 0xf)
@@ -63,6 +71,7 @@
def build_rre(mnemonic, (opcode,)):
opcode1,opcode2 = opcode
+ @builder.arguments('r,r')
def encode_rr(self, reg1, reg2):
self.writechar(opcode1)
self.writechar(opcode2)
@@ -72,6 +81,7 @@
return encode_rr
def build_rx(mnemonic, (opcode,)):
+ @builder.arguments('r/m,ibd')
def encode_rx(self, reg_or_mask, idxbasedisp):
self.writechar(opcode)
index = idxbasedisp.index
@@ -85,6 +95,7 @@
return encode_rx
def build_rxy(mnemonic, (opcode1,opcode2)):
+ @builder.arguments('r/m,ibdl')
def encode_rxy(self, reg_or_mask, idxbasedisp):
self.writechar(opcode1)
index = idxbasedisp.index
@@ -101,6 +112,7 @@
return encode_rxy
def build_ri(mnemonic, (opcode,halfopcode)):
+ @builder.arguments('r/m,i16')
def encode_ri(self, reg_or_mask, imm16):
self.writechar(opcode)
byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
@@ -109,7 +121,18 @@
self.writechar(chr(imm16 & 0xff))
return encode_ri
+def build_ril(mnemonic, (opcode,halfopcode)):
+ @builder.arguments('r/m,a32')
+ def encode_ri(self, reg_or_mask, imm32):
+ self.writechar(opcode)
+ byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
+ self.writechar(chr(byte))
+ self.write_s32(imm32)
+ return encode_ri
+
+
def build_si(mnemonic, (opcode,)):
+ @builder.arguments('bd,u8')
def encode_si(self, base_displace, uimm8):
self.writechar(opcode)
self.writechar(chr(uimm8))
@@ -117,6 +140,7 @@
return encode_si
def build_siy(mnemonic, (opcode1,opcode2)):
+ @builder.arguments('bd,u8')
def encode_siy(self, base_displace, uimm8):
self.writechar(opcode1)
self.writechar(chr(uimm8))
@@ -127,6 +151,7 @@
return encode_siy
def build_ssa(mnemonic, (opcode1,)):
+ @builder.arguments('l8bd,bd')
def encode_ssa(self, len_base_disp, base_displace):
self.writechar(opcode1)
self.writechar(chr(len_base_disp.length & 0xff))
@@ -135,6 +160,7 @@
return encode_ssa
def build_ssb(mnemonic, (opcode1,)):
+ @builder.arguments('l8bd,l8bd')
def encode_ssb(self, len_base_disp1, len_base_disp2):
self.writechar(opcode1)
byte = (len_base_disp1.length & 0xf) << 4 | len_base_disp2.length & 0xf
@@ -144,8 +170,8 @@
return encode_ssb
def build_ssc(mnemonic, (opcode1,)):
- @arguments('lbp,lbp,u4')
- def encode_ssc(self, len_base_disp1, len_base_disp2, uimm4):
+ @builder.arguments('u4,l4bd,l4bd')
+ def encode_ssc(self, uimm4, len_base_disp1, len_base_disp2):
self.writechar(opcode1)
byte = (len_base_disp1.length & 0xf) << 4 | uimm4 & 0xf
self.writechar(chr(byte))
@@ -154,7 +180,7 @@
return encode_ssc
def build_ssd(mnemonic, (opcode,)):
- @arguments('rbd,bd,r')
+ @builder.arguments('ibd,bd,r')
def encode_ssd(self, index_base_disp, base_disp, reg):
self.writechar(opcode)
byte = (index_base_disp.index & 0xf) << 4 | reg & 0xf
@@ -164,7 +190,7 @@
return encode_ssd
def build_sse(mnemonic, (opcode,)):
- @arguments('r,bd,r,bd')
+ @builder.arguments('r,r,bd,bd')
def encode_sse(self, reg1, reg3, base_disp2, base_disp4):
self.writechar(opcode)
byte = (reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4
@@ -174,6 +200,7 @@
return encode_sse
def build_ssf(mnemonic, (opcode,)):
+ @builder.arguments('bd,l8bd')
def encode_ssf(self, base_disp, len_base_disp):
self.writechar(opcode)
self.writechar(chr(len_base_disp.length & 0xff))
@@ -198,25 +225,21 @@
'MVCK': (build_ssd, ['\xD9']),
'LMD': (build_sse, ['\xEF']),
'PKA': (build_ssf, ['\xE9']),
+ 'BRASL': (build_ril, ['\xC0','\x05']),
}
def build_instr_codes(clazz):
-
for mnemonic, (builder, args) in _mnemonic_codes.items():
func = builder(mnemonic, args)
name = mnemonic + "_" + builder.__name__.split("_")[1]
setattr(clazz, name, func)
class AbstractZARCHBuilder(object):
- def write32(self, word):
+ def write_s32(self, word):
+ self.writechar(chr((word >> 24) & 0xFF))
+ self.writechar(chr((word >> 16) & 0xFF))
+ self.writechar(chr((word >> 8) & 0xFF))
self.writechar(chr(word & 0xFF))
- self.writechar(chr((word >> 8) & 0xFF))
- self.writechar(chr((word >> 16) & 0xFF))
- self.writechar(chr((word >> 24) & 0xFF))
-
- def AR_rr(self, reg1, reg2):
- self.writechar(chr(0x1A))
- self.writechar(encode_rr(reg1, reg2))
build_instr_codes(AbstractZARCHBuilder)
@@ -262,8 +285,6 @@
def currpos(self):
return self.get_relative_pos()
-#define_instructions(AbstractARMBuilder)
-
_classes = (AbstractZARCHBuilder,)
# Used to build the MachineCodeBlockWrapper
diff --git a/rpython/jit/backend/zarch/test/test_auto_encoding.py
b/rpython/jit/backend/zarch/test/test_auto_encoding.py
--- a/rpython/jit/backend/zarch/test/test_auto_encoding.py
+++ b/rpython/jit/backend/zarch/test/test_auto_encoding.py
@@ -27,14 +27,11 @@
if (char == self.accept_unnecessary_prefix
and self.index == self.instrindex):
return # ignore the extra character '\x40'
- print self.op
- post = self.expected[self.index+1:self.index+1+15]
+ post = self.expected[self.index+1:self.index+15]
generated = "\x09from codebuilder.py: " +
hexdump(self.expected[self.instrindex:self.index]) + "!" + \
- hexdump([char])+ "!"
+hexdump(post)
- print generated
+ hexdump([char])+ "!"
+hexdump(post) + "..."
expected = "\x09from gnu as: " +
hexdump(self.expected[self.instrindex:self.index+15])+"..."
- print expected
- raise Exception("Differs:\n" + generated + "\n" + expected)
+ raise Exception("Asm line:" + self.op + "\n" + generated + "\n" +
expected)
self.index += 1
def done(self):
@@ -105,12 +102,15 @@
__repr__ = __str__
-def test_range(bits, signed=False, count=24):
+def test_range(bits, signed=False, count=24, alignment=0):
if isinstance(bits, tuple):
bits, signed = bits
if signed:
bits -= 1
maximum = 2**bits
+ if alignment == 16:
+ # TODO
+ return [-32,-16,0,16,32]
return [-maximum,-1,0,1,maximum-1] +
[random.randrange(-maximum,maximum) for i in range(count)]
maximum = 2**bits
return [0,1,maximum-1] + [random.randrange(0,maximum) for i in
range(count)]
@@ -126,97 +126,52 @@
break
return results
+REGS = range(15+1)
+REGNAMES = ['%%r%d' % i for i in REGS]
+TEST_CASE_GENERATE = {
+ 'r': REGS,
+ 'r/m': REGS,
+ 'i4': test_range(4, signed=True),
+ 'i8': test_range(8, signed=True),
+ 'i16': test_range(16, signed=True),
+ 'i32': test_range(32, signed=True),
+ 'a32': test_range(32, signed=True, alignment=16),
+ 'i64': test_range(64, signed=True),
+ 'u4': test_range(4),
+ 'u8': test_range(8),
+ 'u16': test_range(16),
+ 'u32': test_range(32),
+ 'u64': test_range(64),
+ 'bd': build_fake(FakeBaseDisplace,4,12),
+ 'ibd': build_fake(FakeIndexBaseDisplace,4,4,12),
+ 'ibdl': build_fake(FakeIndexBaseDisplace,4,4,(20,True)),
+ 'l8bd': build_fake(FakeLengthBaseDisplace,8,4,12),
+ 'l4bd': build_fake(FakeLengthBaseDisplace,4,4,12),
+}
+
class TestZARCH(object):
WORD = 8
TESTDIR = 'zarch'
- REGS = range(15+1)
- REGNAMES = ['%%r%d' % i for i in REGS]
accept_unnecessary_prefix = None
methname = '?'
- BASE_DISPLACE = build_fake(FakeBaseDisplace,4,12)
- BASE_DISPLACE_LONG = build_fake(FakeBaseDisplace,4,(20,True))
- INDEX_BASE_DISPLACE = build_fake(FakeIndexBaseDisplace,4,4,12)
- INDEX_BASE_DISPLACE_LONG = build_fake(FakeIndexBaseDisplace,4,4,(20,True))
- LENGTH4_BASE_DISPLACE = build_fake(FakeLengthBaseDisplace,4,4,12)
- LENGTH8_BASE_DISPLACE = build_fake(FakeLengthBaseDisplace,8,4,12)
- def reg_tests(self):
- return self.REGS
-
- def stack_bp_tests(self, count=COUNT1):
- return ([0, 4, -4, 124, 128, -128, -132] +
- [random.randrange(-0x20000000, 0x20000000) * 4
- for i in range(count)])
-
- def stack_sp_tests(self, count=COUNT1):
- return ([0, 4, 124, 128] +
- [random.randrange(0, 0x20000000) * 4
- for i in range(count)])
-
- def memory_tests(self):
- return [(reg, ofs)
- for reg in self.NONSPECREGS
- for ofs in self.stack_bp_tests(5)
- ]
-
- def array_tests(self):
- return [(reg1, reg2, scaleshift, ofs)
- for reg1 in self.NONSPECREGS
- for reg2 in self.NONSPECREGS
- for scaleshift in [0, 1, 2, 3]
- for ofs in self.stack_bp_tests(1)
- ]
-
- def imm_tests(self, name, modes, index):
+ def get_func_arg_types(self, methodname):
from rpython.jit.backend.zarch.codebuilder import AbstractZARCHBuilder
import inspect
- func = getattr(AbstractZARCHBuilder, name)
- args = inspect.getargspec(func).args
- # 1 off, self is first arg
- match = re.compile("(u?imm\d+)").match(args[index+1])
- assert match
- return getattr(self, match.group(1) + "_tests")()
-
- def uimm16_tests(self): return test_range(16)
- def imm16_tests(self): return test_range(16,signed=True)
- def imm8_tests(self): return test_range(8,signed=True)
- def uimm8_tests(self): return test_range(8)
- def uimm4_tests(self): return test_range(4)
- def imm32_tests(self): return test_range(32, signed=True)
-
- def relative_tests(self):
- py.test.skip("explicit test required for %r" % (self.methname,))
+ func = getattr(AbstractZARCHBuilder, methodname)
+ return func._arguments_
def assembler_operand_reg(self, regnum):
- return self.REGNAMES[regnum]
+ return REGNAMES[regnum]
- def get_mapping_asm_to_str(self):
- return {
+ def operand_combinations(self, methodname, modes, arguments):
+ mapping = {
'r': self.assembler_operand_reg,
- 's': lambda x: str(x),
- 'x': lambda x: str(x),
- 'y': lambda x: str(x),
- 'i': lambda x: str(x),
- 'l': lambda x: str(x),
- 'L': lambda x: str(x),
+ 'r/m': self.assembler_operand_reg,
}
-
- def operand_combinations(self, modes, arguments):
- remap = {
- 'rre': 'rr',
- 'rxy': 'rx',
- 'siy': 'si',
- 'ssa': 'Ls',
- 'ssb': 'll',
- 'ssc': 'lsi',
- 'ssd': 'xsr',
- 'sse': 'rrss',
- 'ssf': 'sL',
- }
- mapping = self.get_mapping_asm_to_str()
- modes = remap.get(modes, modes)
- for mode, args in zip(modes, arguments):
- yield mapping[mode](args)
+ arg_types = self.get_func_arg_types(methodname)
+ for mode, args in zip(arg_types, arguments):
+ yield mapping.get(mode, lambda x: str(x))(args)
def run_test(self, methname, instrname, argmodes, args_lists,
instr_suffix=None):
@@ -234,7 +189,7 @@
if instr_suffix is not None:
suffix = instr_suffix # overwrite
#
- ops = self.operand_combinations(argmodes, args)
+ ops = self.operand_combinations(methname, argmodes, args)
op = '\t%s%s %s' % (instrname.lower(), suffix,
', '.join(ops))
g.write('%s\n' % op)
@@ -272,34 +227,12 @@
return mode
def make_all_tests(self, methname, modes, args=[]):
- tests = {
- 'r': lambda i: self.REGS,
- 'x': lambda i: self.INDEX_BASE_DISPLACE,
- 'y': lambda i: self.INDEX_BASE_DISPLACE_LONG,
- 'i': lambda i: self.imm_tests(methname, modes, i),
- 's': lambda i: self.BASE_DISPLACE,
- 'L': lambda i: self.LENGTH8_BASE_DISPLACE,
- 'l': lambda i: self.LENGTH4_BASE_DISPLACE,
- }
- tests_all = {
- 'rxy': (tests['r'], tests['y']),
- 'siy': (lambda i: self.BASE_DISPLACE_LONG, tests['i']),
- 'rre': (tests['r'], tests['r']),
- 'ssa': (tests['L'], tests['s']),
- 'ssb': (tests['l'], tests['l']),
- 'ssc': (tests['l'], tests['s'], tests['i']),
- 'ssd': (tests['x'], tests['s'], tests['r']),
- 'sse': (tests['r'], tests['r'], tests['s'], tests['s']),
- 'ssf': (tests['s'], tests['L']),
- }
- if modes in tests_all:
- combinations = [f(i) for i,f in enumerate(tests_all[modes])]
- else:
- combinations = []
- for i,m in enumerate(modes):
- elems = tests[m](i)
- random.shuffle(elems)
- combinations.append(elems)
+ arg_types = self.get_func_arg_types(methname)
+ combinations = []
+ for i,m in enumerate(arg_types):
+ elems = TEST_CASE_GENERATE[m]
+ random.shuffle(elems)
+ combinations.append(elems)
results = []
for args in itertools.product(*combinations):
results.append(args)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit