[pypy-commit] pypy s390x-backend: added division opcode, multiply opcode, int32 imm add and sub, started to implement int_mul, int_div.
plan_rich
noreply at buildbot.pypy.org
Wed Nov 11 09:46:03 EST 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80632:f7d3b4343ec7
Date: 2015-11-11 10:40 +0100
http://bitbucket.org/pypy/pypy/changeset/f7d3b4343ec7/
Log: added division opcode, multiply opcode, int32 imm add and sub,
started to implement int_mul, int_div. for int_mul followed by an
overlfow we probably need a different solution overflow condition is
not set by multiply (or multiply single), can be checked for the a
unsigned integer case with just one compare
diff --git a/rpython/jit/backend/zarch/helper/regalloc.py b/rpython/jit/backend/zarch/helper/regalloc.py
--- a/rpython/jit/backend/zarch/helper/regalloc.py
+++ b/rpython/jit/backend/zarch/helper/regalloc.py
@@ -7,13 +7,16 @@
return lower_bound <= i <= upper_bound
return False
-def prepare_int_add_or_mul(self, op):
+def check_imm32(arg):
+ return check_imm(arg, -2**31, 2**31-1)
+
+def prepare_int_add(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
- if check_imm(a0):
+ if check_imm32(a0):
a0, a1 = a1, a0
l0 = self.ensure_reg(a0)
- if check_imm(a1):
+ if check_imm32(a1):
l1 = imm(a1.getint())
else:
l1 = self.ensure_reg(a1)
@@ -21,6 +24,40 @@
self.free_op_vars()
return [l0, l1]
+def prepare_int_mul(self, op):
+ a0 = op.getarg(0)
+ a1 = op.getarg(1)
+ if check_imm32(a0):
+ a0, a1 = a1, a0
+ l0 = self.ensure_reg(a0)
+ if check_imm32(a1):
+ l1 = imm(a1.getint())
+ else:
+ l1 = self.ensure_reg(a1)
+ self.force_result_in_reg(op, a0)
+ self.free_op_vars()
+ return [l0, l1]
+
+def prepare_int_div(self, op):
+ a0 = op.getarg(0)
+ a1 = op.getarg(1)
+ l0,lr = self.ensure_even_odd_pair(a0)
+ l1 = self.ensure_reg(a1)
+ xxx
+ self.force_result_in_reg(op, a0)
+ self.free_op_vars()
+ return [l0, l1]
+
+def prepare_int_mod(self, op):
+ a0 = op.getarg(0)
+ a1 = op.getarg(1)
+ l0,lr = self.ensure_even_odd_pair(a0)
+ l1 = self.ensure_reg(a1)
+ self.force_arg_to_(op, a0)
+ self.free_op_vars()
+ return [l0, l1]
+
+
def prepare_int_sub(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
diff --git a/rpython/jit/backend/zarch/instruction_builder.py b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -5,7 +5,7 @@
def dummy_argument(arg):
""" NOT_RPYTHON """
- if arg in ('r', 'r/m', 'm', 'f', '-'):
+ if arg in ('r', 'r/m', 'm', 'f', '-', 'eo'):
return 0
if arg.startswith('i') or arg.startswith('u'):
return 0
@@ -24,6 +24,7 @@
f - floating point register
r - register
m - mask
+ eo - even odd pair (= the even register)
r/m - register or mask
iX - immediate X bits (signed)
uX - immediate X bits (unsigend)
@@ -147,8 +148,8 @@
encode_index_base_displace(self, reg_or_mask, idxbasedisp)
return encode_rx
-def build_rxy(mnemonic, (opcode1,opcode2)):
- @builder.arguments('r/m,bidl')
+def build_rxy(mnemonic, (opcode1,opcode2), arguments='r/m,bidl'):
+ @builder.arguments(arguments)
def encode_rxy(self, reg_or_mask, idxbasedisp):
self.writechar(opcode1)
index = idxbasedisp.index
@@ -184,7 +185,7 @@
self.writechar(opcode)
byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
self.writechar(chr(byte))
- if br:
+ if br or mnemonic == 'LARL':
imm32 = imm32 >> 1
# half word boundary, addressing bytes
self.write_i32(imm32 & BIT_MASK_32)
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -9,13 +9,28 @@
}
arith_mnemonic_codes = {
+ # add
'AR': ('rr', ['\x1A']),
'AGR': ('rre', ['\xB9','\x08']),
'AGFR': ('rre', ['\xB9','\x18']),
'A': ('rx', ['\x5A']),
+ 'AGFI': ('ril', ['\xC2','\x08']),
+
+ # sub
'SR': ('rr', ['\x1B']),
'SG': ('rxy', ['\xE3','\x09']),
'SGR': ('rre', ['\xB9','\x09']),
+ # mul
+ 'MSGR': ('rre', ['\xB9','\x0C']),
+ 'MSG': ('rxy', ['\xE3','\x0C']),
+ 'MSGFI': ('ril', ['\xC2','\x00']),
+ # div/mod
+ 'DSGR': ('rre', ['\xB9','\x0D'], 'eo,r'),
+ 'DSG': ('rxy', ['\xE3','\x0D'], 'eo,bidl'),
+ # there is no immidiate divide
+
+
+ # div
'AY': ('rxy', ['\xE3','\x5A']),
'AG': ('rxy', ['\xE3','\x08']),
diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -16,6 +16,15 @@
else:
self.mc.AGR(l0, l1)
+ def emit_int_mul(self, op, arglocs, regalloc):
+ l0, l1 = arglocs
+ if l1.is_imm():
+ self.mc.AGHI(l0, l1)
+ elif l1.is_in_pool():
+ self.mc.AG(l0, l1)
+ else:
+ self.mc.AGR(l0, l1)
+
def emit_int_sub(self, op, arglocs, regalloc):
l0, l1 = arglocs
if l1.is_in_pool():
diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -463,9 +463,12 @@
def prepare_increment_debug_counter(self, op):
pass # XXX
- prepare_int_add = helper.prepare_int_add_or_mul
+ prepare_int_add = helper.prepare_int_add
prepare_int_sub = helper.prepare_int_sub
- prepare_int_mul = helper.prepare_int_add_or_mul
+ prepare_int_mul = helper.prepare_int_mul
+ prepare_int_floordiv = helper.prepare_div
+ prepare_uint_floordiv = helper.prepare_div
+ prepare_int_mod = helper.prepare_mod
prepare_int_le = helper.prepare_cmp_op
prepare_int_lt = helper.prepare_cmp_op
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
@@ -112,6 +112,12 @@
maximum = 2**bits
return [0,1,maximum-1] + [random.randrange(0,maximum) for i in range(count)]
+def range_of_halfword_bits(bits, signed=True, count=24):
+ elems = range_of_bits(bits, signed, count)
+ for i,e in enumerate(elems):
+ elems[i] = (e // 2) >> 1
+ return elems
+
def build_fake(clazz, *arg_bits):
possibilities = itertools.product(*[range_of_bits(b) for b in arg_bits])
results = []
@@ -124,6 +130,7 @@
return results
REGS = range(16)
+EVEN_REGS = range(0,16,2)
REGNAMES = ['%%r%d' % i for i in REGS]
FP_REGS = range(16)
FP_REGNAMES = ['%%f%d' % i for i in FP_REGS]
@@ -131,6 +138,7 @@
'-': [],
'r': REGS,
'f': FP_REGS,
+ 'eo': EVEN_REGS,
'r/m': REGS,
'm': range_of_bits(4),
'i4': range_of_bits(4, signed=True),
@@ -138,6 +146,7 @@
'i16': range_of_bits(16, signed=True),
'i32': range_of_bits(32, signed=True),
'i64': range_of_bits(64, signed=True),
+ 'h32': range_of_halfword_bits(32, signed=True),
'u4': range_of_bits(4),
'u8': range_of_bits(8),
'u16': range_of_bits(16),
@@ -165,6 +174,7 @@
def operand_combinations(self, methodname, modes, arguments):
mapping = {
'r': (lambda num: REGNAMES[num]),
+ 'eo': (lambda num: REGNAMES[num]),
'r/m': (lambda num: REGNAMES[num]),
'f': (lambda num: FP_REGNAMES[num]),
}
More information about the pypy-commit
mailing list