Author: Richard Plangger <planri...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit