[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