Author: Richard Plangger <[email protected]>
Branch: s390x-backend
Changeset: r80655:7e4f29d5c048
Date: 2015-11-13 10:18 +0100
http://bitbucket.org/pypy/pypy/changeset/7e4f29d5c048/
Log: completed implementation for int_is_true, int_is_zero. added
flush_cc method and fixed the LARL problem (test suite provided
wrong number to gnu asm)
diff --git a/rpython/jit/backend/zarch/assembler.py
b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -357,6 +357,26 @@
targettoken._ll_loop_code += rawstart
self.target_tokens_currently_compiling = None
+ def flush_cc(self, condition, result_loc):
+ # After emitting an instruction that leaves a boolean result in
+ # a condition code (cc), call this. In the common case, result_loc
+ # will be set to 'fp' by the regalloc, which in this case means
+ # "propagate it between this operation and the next guard by keeping
+ # it in the cc". In the uncommon case, result_loc is another
+ # register, and we emit a load from the cc into this register.
+ assert self.guard_success_cc == c.cond_none
+ if result_loc is r.SPP:
+ self.guard_success_cc = condition
+ else:
+ # sadly we cannot use LOCGHI
+ # it is included in some extension that seem to be NOT installed
+ # by default.
+ self.mc.LGHI(r.SCRATCH, l.imm(1))
+ self.mc.LOCGR(result_loc, r.SCRATCH, condition)
+ self.mc.LGHI(r.SCRATCH, l.imm(0))
+ self.mc.LOCGR(result_loc, r.SCRATCH, c.negate(condition))
+
+
def _assemble(self, regalloc, inputargs, operations):
self._regalloc = regalloc
self.guard_success_cc = c.cond_none
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
@@ -133,13 +133,13 @@
def build_rre(mnemonic, (opcode1,opcode2), argtypes='r,r'):
@builder.arguments(argtypes)
- def encode_rr(self, reg1, reg2):
+ def encode_rre(self, reg1, reg2):
self.writechar(opcode1)
self.writechar(opcode2)
self.writechar('\x00')
operands = ((reg1 & 0x0f) << 4) | (reg2 & 0xf)
self.writechar(chr(operands))
- return encode_rr
+ return encode_rre
def build_rx(mnemonic, (opcode,)):
@builder.arguments('r/m,bid')
@@ -277,14 +277,24 @@
encode_base_displace(self, base_displace)
return encode_rs
-def build_rsy(mnemonic, (opcode1,opcode2)):
+@always_inline
+def _encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace):
+ self.writechar(opcode1)
+ self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
+ encode_base_displace_long(self, base_displace)
+ self.writechar(opcode2)
+
+def build_rsy_a(mnemonic, (opcode1,opcode2)):
@builder.arguments('r,r,bdl')
- def encode_ssa(self, reg1, reg3, base_displace):
- self.writechar(opcode1)
- self.writechar(chr((reg1 & BIT_MASK_4) << 4 | reg3 & BIT_MASK_4))
- encode_base_displace_long(self, base_displace)
- self.writechar(opcode2)
- return encode_ssa
+ def encode_rsy(self, reg1, reg3, base_displace):
+ _encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace)
+ return encode_rsy
+
+def build_rsy_b(mnemonic, (opcode1,opcode2)):
+ @builder.arguments('r,bdl,r')
+ def encode_rsy(self, reg1, base_displace, reg3):
+ _encode_rsy(self, opcode1, opcode2, reg1, reg3, base_displace)
+ return encode_rsy
def build_rsi(mnemonic, (opcode,)):
br = is_branch_relative(mnemonic)
@@ -298,10 +308,10 @@
self.write_i16(imm16 & BIT_MASK_16)
return encode_ri
-def build_rie(mnemonic, (opcode1,opcode2)):
+def build_rie_e(mnemonic, (opcode1,opcode2)):
br = is_branch_relative(mnemonic)
@builder.arguments('r,r,i16')
- def encode_ri(self, reg1, reg2, imm16):
+ def encode_rie_e(self, reg1, reg2, imm16):
self.writechar(opcode1)
byte = (reg1 & BIT_MASK_4) << 4 | (reg2 & BIT_MASK_4)
self.writechar(chr(byte))
@@ -310,18 +320,45 @@
self.write_i16(imm16 & BIT_MASK_16)
self.writechar(chr(0x0))
self.writechar(opcode2)
- return encode_ri
+ return encode_rie_e
-def build_rrf(mnemonic, (opcode1,opcode2), argtypes):
+def build_rie_a(mnemonic, (opcode1,opcode2)):
+ br = is_branch_relative(mnemonic)
+ @builder.arguments('r,i16,r/m')
+ def encode_rie_a(self, reg1, imm16, mask):
+ self.writechar(opcode1)
+ byte = (reg1 & BIT_MASK_4) << 4 | (mask & BIT_MASK_4)
+ self.writechar(chr(byte))
+ if br:
+ imm16 = imm16 >> 1
+ self.write_i16(imm16 & BIT_MASK_16)
+ self.writechar(chr(0x0))
+ self.writechar(opcode2)
+ return encode_rie_a
+
+build_rie_g = build_rie_a
+
+@always_inline
+def _encode_rrf(self, opcode1, opcode2, r1, r2, rm3, rm4):
+ self.writechar(opcode1)
+ self.writechar(opcode2)
+ byte = (rm3 & BIT_MASK_4) << 4 | (rm4 & BIT_MASK_4)
+ self.writechar(chr(byte))
+ byte = (r1 & BIT_MASK_4) << 4 | (r2 & BIT_MASK_4)
+ self.writechar(chr(byte))
+
+def build_rrf_c(mnemonic, (opcode1,opcode2), argtypes='r,r,r/m,-'):
@builder.arguments(argtypes)
- def encode_rrf(self, r1, rm3, r2, rm4):
- self.writechar(opcode1)
- self.writechar(opcode2)
- byte = (rm3 & BIT_MASK_4) << 4 | (rm4 & BIT_MASK_4)
- self.writechar(chr(byte))
- byte = (r1 & BIT_MASK_4) << 4 | (r2 & BIT_MASK_4)
- self.writechar(chr(byte))
- return encode_rrf
+ def encode_rrf_b(self, r1, r2, rm3, rm4):
+ _encode_rrf(self, opcode1, opcode2, r1, r2, rm3, rm4)
+ return encode_rrf_b
+
+def build_rrf_e(mnemonic, (opcode1,opcode2), argtypes):
+ @builder.arguments(argtypes)
+ def encode_rrf_e(self, r1, rm3, r2, rm4):
+ _encode_rrf(self, opcode1, opcode2, r1, r2, rm3, rm4)
+ return encode_rrf_e
+build_rrf_b = build_rrf_e
def build_rxe(mnemonic, (opcode1,opcode2), argtypes):
@builder.arguments(argtypes)
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
@@ -27,15 +27,15 @@
# div/mod
'DSGR': ('rre', ['\xB9','\x0D'], 'eo,r'),
'DSG': ('rxy', ['\xE3','\x0D'], 'eo,bidl'),
- 'DLGR': ('rre', ['\xB9','\x97'], 'eo,r'),
+ 'DLGR': ('rre', ['\xB9','\x87'], 'eo,r'),
'DLG': ('rxy', ['\xE3','\x87'], 'eo,bidl'),
# there is no immidiate divide
# shifting
- 'SRAG': ('rsy', ['\xEB','\x0A']),
- 'SLAG': ('rsy', ['\xEB','\x0B']),
- 'SRLG': ('rsy', ['\xEB','\x0C']),
- 'SLLG': ('rsy', ['\xEB','\x0D']),
+ 'SRAG': ('rsy_a', ['\xEB','\x0A']),
+ 'SLAG': ('rsy_a', ['\xEB','\x0B']),
+ 'SRLG': ('rsy_a', ['\xEB','\x0C']),
+ 'SLLG': ('rsy_a', ['\xEB','\x0D']),
# invert & negative & absolute
'LPGR': ('rre', ['\xB9','\x00']),
@@ -59,7 +59,7 @@
'CLGR': ('rre', ['\xB9','\x21']),
'CLG': ('rxy', ['\xE3','\x21']),
'CGHI': ('ri', ['\xA7','\x0F']),
- 'CGFI': ('ril', ['\xC2','\x0E']),
+ 'CGFI': ('ril', ['\xC2','\x0C']),
}
logic_mnemonic_codes = {
@@ -111,7 +111,7 @@
# load memory
'LMD': ('sse', ['\xEF']),
- 'LMG': ('rsy', ['\xEB','\x04']),
+ 'LMG': ('rsy_a', ['\xEB','\x04']),
'LHI': ('ri', ['\xA7','\x08']),
'LGHI': ('ri', ['\xA7','\x09']),
'LR': ('rr', ['\x18']),
@@ -119,8 +119,12 @@
'LG': ('rxy', ['\xE3','\x04']),
'LARL': ('ril', ['\xC0','\x00'], 'r/m,h32'),
+ # load on condition
+ 'LOCGR': ('rrf_c', ['\xB9','\xE2']),
+ 'LOCG': ('rsy_b', ['\xEB','\xE2']),
+
# store memory
- 'STMG': ('rsy', ['\xEB','\x24']),
+ 'STMG': ('rsy_a', ['\xEB','\x24']),
'ST': ('rx', ['\x50']),
'STG': ('rxy', ['\xE3','\x24']),
'STY': ('rxy', ['\xE3','\x50']),
@@ -155,12 +159,12 @@
}
floatingpoint_mnemonic_codes = {
- 'FIEBR': ('rrf', ['\xB3','\x57'], 'r,u4,r,-'),
- 'FIDBR': ('rrf', ['\xB3','\x5F'], 'r,u4,r,-'),
+ 'FIEBR': ('rrf_e', ['\xB3','\x57'], 'r,u4,r,-'),
+ 'FIDBR': ('rrf_e', ['\xB3','\x5F'], 'r,u4,r,-'),
# convert to fixed
- 'CGEBR': ('rrf', ['\xB3','\xA8'], 'r,u4,r,-'),
- 'CGDBR': ('rrf', ['\xB3','\xA9'], 'r,u4,r,-'),
+ 'CGEBR': ('rrf_e', ['\xB3','\xA8'], 'r,u4,r,-'),
+ 'CGDBR': ('rrf_e', ['\xB3','\xA9'], 'r,u4,r,-'),
# convert from fixed
'CEGBR': ('rre', ['\xB3','\xA4']),
@@ -190,8 +194,8 @@
'DDB': ('rxe', ['\xED','\x1D'], 'r,bidl,-'),
# DIVIDE (+mod)
- 'DIEBR': ('rrf', ['\xB3','\x53'], 'r,r,r,m'),
- 'DIDBR': ('rrf', ['\xB3','\x5B'], 'r,r,r,m'),
+ 'DIEBR': ('rrf_b', ['\xB3','\x53'], 'r,r,r,m'),
+ 'DIDBR': ('rrf_b', ['\xB3','\x5B'], 'r,r,r,m'),
# COMPARISON
'CEBR': ('rre', ['\xB3','\x09']),
@@ -204,9 +208,9 @@
all_mnemonic_codes = {
#
'BXH': ('rs', ['\x86']),
- 'BXHG': ('rsy', ['\xEB','\x44']),
+ 'BXHG': ('rsy_a', ['\xEB','\x44']),
'BRXH': ('rsi', ['\x84']),
- 'BRXLG': ('rie', ['\xEC','\x45']),
+ 'BRXLG': ('rie_e', ['\xEC','\x45']),
#
'NI': ('si', ['\x94']),
'NIY': ('siy', ['\xEB','\x54']),
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
@@ -6,21 +6,6 @@
import rpython.jit.backend.zarch.locations as l
from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
-def flush_cc(asm, condition, result_loc):
- # After emitting an instruction that leaves a boolean result in
- # a condition code (cc), call this. In the common case, result_loc
- # will be set to 'fp' by the regalloc, which in this case means
- # "propagate it between this operation and the next guard by keeping
- # it in the cc". In the uncommon case, result_loc is another
- # register, and we emit a load from the cc into this register.
- assert asm.guard_success_cc == c.cond_none
- if result_loc is r.SPP:
- asm.guard_success_cc = condition
- else:
- xxx
- #asm.mc.MOV_ri(result_loc.value, 1, condition)
- #asm.mc.MOV_ri(result_loc.value, 0, c.get_opposite_of(condition))
-
class IntOpAssembler(object):
_mixin_ = True
@@ -101,12 +86,12 @@
def emit_int_is_zero(self, op, arglocs, regalloc):
l0 = arglocs[0]
self.mc.CGHI(l0, l.imm(0))
- flush_cc(self, l0, c.EQ)
+ self.flush_cc(c.EQ, l0)
def emit_int_is_true(self, op, arglocs, regalloc):
l0 = arglocs[0]
self.mc.CGHI(l0, l.imm(0))
- flush_cc(self, l0, c.NE)
+ self.flush_cc(c.NE, l0)
emit_int_and = gen_emit_rr_or_rpool("NGR", "NG")
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
@@ -115,7 +115,7 @@
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
+ elems[i] = e >> 1
return elems
def build_fake(clazz, *arg_bits):
@@ -177,6 +177,7 @@
'eo': (lambda num: REGNAMES[num]),
'r/m': (lambda num: REGNAMES[num]),
'f': (lambda num: FP_REGNAMES[num]),
+ 'h32': (lambda num: str(num << 1)),
}
arg_types = self.get_func_arg_types(methodname)
for mode, args in zip(arg_types, arguments):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit