From patchwork Thu Sep 27 23:06:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 187530 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 771E62C00B6 for ; Fri, 28 Sep 2012 09:06:42 +1000 (EST) Received: from localhost ([::1]:52937 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1THNAG-0004kF-Ig for incoming@patchwork.ozlabs.org; Thu, 27 Sep 2012 19:06:40 -0400 Received: from eggs.gnu.org ([208.118.235.92]:46926) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1THNA8-0004jl-Ga for qemu-devel@nongnu.org; Thu, 27 Sep 2012 19:06:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1THNA6-0003rc-K2 for qemu-devel@nongnu.org; Thu, 27 Sep 2012 19:06:32 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:50803) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1THNA6-0003rY-A0 for qemu-devel@nongnu.org; Thu, 27 Sep 2012 19:06:30 -0400 Received: by padfb10 with SMTP id fb10so1751763pad.4 for ; Thu, 27 Sep 2012 16:06:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=kTq9+k7uCJWKs5mqsOg+vS5y9Atc9ypE+buKwiF86Yo=; b=T+pPWA07JWQJ8nzj454UAnHIV3nPNeB0u5bOTl9xCklgjXNDpq0pv4pV0uBQdIju+P 3PE56Q08GYkeTQFMZrXyymx+dcG+NYfwLJKsVuLn5CewDUKtiHoJeo8QRwGoR5Nrsr0G MAYJY73DXvgxzwSrqgf5uyMPp/H9SyZcGKEUhGfgAFNBFrxPbzwFZ0utfo4GMJFreqiI usVS3DHltVvZBLF+Bq7WqaQIQ4fblPkMwg3J6OAM+ZQcys137eb5GluuTCOiqsmi0CUX kFqoUxcxxRGz5kMSdpWm3y5mYVZ5I9M6Df2tW8XuDIip+mhuXzCXOCcr0GtbblnZQlOQ 0WnA== Received: by 10.68.197.104 with SMTP id it8mr15496648pbc.167.1348787189590; Thu, 27 Sep 2012 16:06:29 -0700 (PDT) Received: from anchor.twiddle.home.com ([173.160.232.49]) by mx.google.com with ESMTPS id s10sm4415313paz.11.2012.09.27.16.06.27 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 27 Sep 2012 16:06:28 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 27 Sep 2012 16:06:24 -0700 Message-Id: <1348787184-23750-1-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1348785610-23418-1-git-send-email-rth@twiddle.net> References: <1348785610-23418-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.220.45 Cc: Alexander Graf Subject: [Qemu-devel] [PATCH 030/147] target-s390: Convert AND, OR, XOR, INSERT IMMEDIATE X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Richard Henderson --- target-s390x/insn-data.def | 25 +++++ target-s390x/translate.c | 237 +++++++++++---------------------------------- 2 files changed, 82 insertions(+), 180 deletions(-) diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index 9507262..705b655 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -49,6 +49,13 @@ C(0xb980, NGR, RRE, Z, r1, r2, r1, 0, and, nz64) C(0xb9e4, NGRK, RRF_a, DO, r2, r3, r1, 0, and, nz64) C(0xe380, NG, RXY_a, Z, r1, m2_64, r1, 0, and, nz64) +/* AND IMMEDIATE */ + D(0xc00a, NIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, andi, 0, 0x2020) + D(0xc00b, NILF, RIL_a, EI, r1_o, i2_32u, r1, 0, andi, 0, 0x2000) + D(0xa504, NIHH, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1030) + D(0xa505, NIHL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1020) + D(0xa506, NILH, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1010) + D(0xa507, NILL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1000) /* COMPARE */ C(0x1900, CR, RR_a, Z, r1_o, r2_o, 0, 0, 0, cmps32) @@ -106,6 +113,17 @@ C(0xb982, XGR, RRE, Z, r1, r2, r1, 0, xor, nz64) C(0xb9e7, XGRK, RRF_a, DO, r2, r3, r1, 0, xor, nz64) C(0xe382, XG, RXY_a, Z, r1, m2_64, r1, 0, xor, nz64) +/* EXCLUSIVE OR IMMEDIATE */ + D(0xc006, XIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, xori, 0, 0x2020) + D(0xc007, XILF, RIL_a, EI, r1_o, i2_32u, r1, 0, xori, 0, 0x2000) + +/* INSERT IMMEDIATE */ + D(0xc008, IIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, insi, 0, 0x2020) + D(0xc009, IILF, RIL_a, EI, r1_o, i2_32u, r1, 0, insi, 0, 0x2000) + D(0xa500, IIHH, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1030) + D(0xa501, IIHL, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1020) + D(0xa502, IILH, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1010) + D(0xa503, IILL, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1000) /* LOAD */ C(0x1800, LR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, 0) @@ -223,6 +241,13 @@ C(0xb981, OGR, RRE, Z, r1, r2, r1, 0, or, nz64) C(0xb9e6, OGRK, RRF_a, DO, r2, r3, r1, 0, or, nz64) C(0xe381, OG, RXY_a, Z, r1, m2_64, r1, 0, or, nz64) +/* OR IMMEDIATE */ + D(0xc00c, OIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, ori, 0, 0x2020) + D(0xc00d, OILF, RIL_a, EI, r1_o, i2_32u, r1, 0, ori, 0, 0x2000) + D(0xa508, OIHH, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1030) + D(0xa509, OIHL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1020) + D(0xa50a, OILH, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1010) + D(0xa50b, OILL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1000) /* SUBTRACT */ C(0x1b00, SR, RR_a, Z, r1, r2, new, r1_32, sub, subs32) diff --git a/target-s390x/translate.c b/target-s390x/translate.c index f099fd7..9cf4c57 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -1875,141 +1875,6 @@ static void disas_ed(CPUS390XState *env, DisasContext *s, int op, int r1, tcg_temp_free_i64(addr); } -static void disas_a5(CPUS390XState *env, DisasContext *s, int op, int r1, - int i2) -{ - TCGv_i64 tmp, tmp2; - TCGv_i32 tmp32; - LOG_DISAS("disas_a5: op 0x%x r1 %d i2 0x%x\n", op, r1, i2); - switch (op) { - case 0x0: /* IIHH R1,I2 [RI] */ - tmp = tcg_const_i64(i2); - tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16); - tcg_temp_free_i64(tmp); - break; - case 0x1: /* IIHL R1,I2 [RI] */ - tmp = tcg_const_i64(i2); - tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16); - tcg_temp_free_i64(tmp); - break; - case 0x2: /* IILH R1,I2 [RI] */ - tmp = tcg_const_i64(i2); - tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16); - tcg_temp_free_i64(tmp); - break; - case 0x3: /* IILL R1,I2 [RI] */ - tmp = tcg_const_i64(i2); - tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16); - tcg_temp_free_i64(tmp); - break; - case 0x4: /* NIHH R1,I2 [RI] */ - case 0x8: /* OIHH R1,I2 [RI] */ - tmp = load_reg(r1); - tmp32 = tcg_temp_new_i32(); - switch (op) { - case 0x4: - tmp2 = tcg_const_i64((((uint64_t)i2) << 48) - | 0x0000ffffffffffffULL); - tcg_gen_and_i64(tmp, tmp, tmp2); - break; - case 0x8: - tmp2 = tcg_const_i64(((uint64_t)i2) << 48); - tcg_gen_or_i64(tmp, tmp, tmp2); - break; - default: - tcg_abort(); - } - store_reg(r1, tmp); - tcg_gen_shri_i64(tmp2, tmp, 48); - tcg_gen_trunc_i64_i32(tmp32, tmp2); - set_cc_nz_u32(s, tmp32); - tcg_temp_free_i64(tmp2); - tcg_temp_free_i32(tmp32); - tcg_temp_free_i64(tmp); - break; - case 0x5: /* NIHL R1,I2 [RI] */ - case 0x9: /* OIHL R1,I2 [RI] */ - tmp = load_reg(r1); - tmp32 = tcg_temp_new_i32(); - switch (op) { - case 0x5: - tmp2 = tcg_const_i64((((uint64_t)i2) << 32) - | 0xffff0000ffffffffULL); - tcg_gen_and_i64(tmp, tmp, tmp2); - break; - case 0x9: - tmp2 = tcg_const_i64(((uint64_t)i2) << 32); - tcg_gen_or_i64(tmp, tmp, tmp2); - break; - default: - tcg_abort(); - } - store_reg(r1, tmp); - tcg_gen_shri_i64(tmp2, tmp, 32); - tcg_gen_trunc_i64_i32(tmp32, tmp2); - tcg_gen_andi_i32(tmp32, tmp32, 0xffff); - set_cc_nz_u32(s, tmp32); - tcg_temp_free_i64(tmp2); - tcg_temp_free_i32(tmp32); - tcg_temp_free_i64(tmp); - break; - case 0x6: /* NILH R1,I2 [RI] */ - case 0xa: /* OILH R1,I2 [RI] */ - tmp = load_reg(r1); - tmp32 = tcg_temp_new_i32(); - switch (op) { - case 0x6: - tmp2 = tcg_const_i64((((uint64_t)i2) << 16) - | 0xffffffff0000ffffULL); - tcg_gen_and_i64(tmp, tmp, tmp2); - break; - case 0xa: - tmp2 = tcg_const_i64(((uint64_t)i2) << 16); - tcg_gen_or_i64(tmp, tmp, tmp2); - break; - default: - tcg_abort(); - } - store_reg(r1, tmp); - tcg_gen_shri_i64(tmp, tmp, 16); - tcg_gen_trunc_i64_i32(tmp32, tmp); - tcg_gen_andi_i32(tmp32, tmp32, 0xffff); - set_cc_nz_u32(s, tmp32); - tcg_temp_free_i64(tmp2); - tcg_temp_free_i32(tmp32); - tcg_temp_free_i64(tmp); - break; - case 0x7: /* NILL R1,I2 [RI] */ - case 0xb: /* OILL R1,I2 [RI] */ - tmp = load_reg(r1); - tmp32 = tcg_temp_new_i32(); - switch (op) { - case 0x7: - tmp2 = tcg_const_i64(i2 | 0xffffffffffff0000ULL); - tcg_gen_and_i64(tmp, tmp, tmp2); - break; - case 0xb: - tmp2 = tcg_const_i64(i2); - tcg_gen_or_i64(tmp, tmp, tmp2); - break; - default: - tcg_abort(); - } - store_reg(r1, tmp); - tcg_gen_trunc_i64_i32(tmp32, tmp); - tcg_gen_andi_i32(tmp32, tmp32, 0xffff); - set_cc_nz_u32(s, tmp32); /* signedness should not matter here */ - tcg_temp_free_i64(tmp2); - tcg_temp_free_i32(tmp32); - tcg_temp_free_i64(tmp); - break; - default: - LOG_DISAS("illegal a5 operation 0x%x\n", op); - gen_illegal_opcode(s); - return; - } -} - static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1, int i2) { @@ -2918,44 +2783,6 @@ static void disas_c0(CPUS390XState *env, DisasContext *s, int op, int r1, int i2 gen_goto_tb(s, 0, target); s->is_jmp = DISAS_TB_JUMP; break; - case 0x7: /* XILF R1,I2 [RIL] */ - case 0xb: /* NILF R1,I2 [RIL] */ - case 0xd: /* OILF R1,I2 [RIL] */ - tmp32_1 = load_reg32(r1); - switch (op) { - case 0x7: - tcg_gen_xori_i32(tmp32_1, tmp32_1, (uint32_t)i2); - break; - case 0xb: - tcg_gen_andi_i32(tmp32_1, tmp32_1, (uint32_t)i2); - break; - case 0xd: - tcg_gen_ori_i32(tmp32_1, tmp32_1, (uint32_t)i2); - break; - default: - tcg_abort(); - } - store_reg32(r1, tmp32_1); - set_cc_nz_u32(s, tmp32_1); - tcg_temp_free_i32(tmp32_1); - break; - case 0x9: /* IILF R1,I2 [RIL] */ - tmp32_1 = tcg_const_i32((uint32_t)i2); - store_reg32(r1, tmp32_1); - tcg_temp_free_i32(tmp32_1); - break; - case 0xa: /* NIHF R1,I2 [RIL] */ - tmp = load_reg(r1); - tmp32_1 = tcg_temp_new_i32(); - tcg_gen_andi_i64(tmp, tmp, (((uint64_t)((uint32_t)i2)) << 32) - | 0xffffffffULL); - store_reg(r1, tmp); - tcg_gen_shri_i64(tmp, tmp, 32); - tcg_gen_trunc_i64_i32(tmp32_1, tmp); - set_cc_nz_u32(s, tmp32_1); - tcg_temp_free_i64(tmp); - tcg_temp_free_i32(tmp32_1); - break; default: LOG_DISAS("illegal c0 operation 0x%x\n", op); gen_illegal_opcode(s); @@ -3487,13 +3314,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s) tcg_temp_free_i32(tmp32_1); tcg_temp_free_i32(tmp32_2); break; - case 0xa5: - insn = ld_code4(env, s->pc); - r1 = (insn >> 20) & 0xf; - op = (insn >> 16) & 0xf; - i2 = insn & 0xffff; - disas_a5(env, s, op, r1, i2); - break; case 0xa7: insn = ld_code4(env, s->pc); r1 = (insn >> 20) & 0xf; @@ -4112,6 +3932,31 @@ static ExitStatus op_and(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_andi(DisasContext *s, DisasOps *o) +{ + int shift = s->insn->data & 0xff; + int size = s->insn->data >> 8; + uint64_t mask = ((1ull << size) - 1) << shift; + + assert(!o->g_in2); + tcg_gen_shli_i64(o->in2, o->in2, shift); + tcg_gen_ori_i64(o->in2, o->in2, ~mask); + tcg_gen_and_i64(o->out, o->in1, o->in2); + + /* Produce the CC from only the bits manipulated. */ + tcg_gen_andi_i64(cc_dst, o->out, mask); + set_cc_nz_u64(s, cc_dst); + return NO_EXIT; +} + +static ExitStatus op_insi(DisasContext *s, DisasOps *o) +{ + int shift = s->insn->data & 0xff; + int size = s->insn->data >> 8; + tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size); + return NO_EXIT; +} + static ExitStatus op_ld8s(DisasContext *s, DisasOps *o) { tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s)); @@ -4194,6 +4039,22 @@ static ExitStatus op_or(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_ori(DisasContext *s, DisasOps *o) +{ + int shift = s->insn->data & 0xff; + int size = s->insn->data >> 8; + uint64_t mask = ((1ull << size) - 1) << shift; + + assert(!o->g_in2); + tcg_gen_shli_i64(o->in2, o->in2, shift); + tcg_gen_or_i64(o->out, o->in1, o->in2); + + /* Produce the CC from only the bits manipulated. */ + tcg_gen_andi_i64(cc_dst, o->out, mask); + set_cc_nz_u64(s, cc_dst); + return NO_EXIT; +} + static ExitStatus op_sub(DisasContext *s, DisasOps *o) { tcg_gen_sub_i64(o->out, o->in1, o->in2); @@ -4206,6 +4067,22 @@ static ExitStatus op_xor(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_xori(DisasContext *s, DisasOps *o) +{ + int shift = s->insn->data & 0xff; + int size = s->insn->data >> 8; + uint64_t mask = ((1ull << size) - 1) << shift; + + assert(!o->g_in2); + tcg_gen_shli_i64(o->in2, o->in2, shift); + tcg_gen_xor_i64(o->out, o->in1, o->in2); + + /* Produce the CC from only the bits manipulated. */ + tcg_gen_andi_i64(cc_dst, o->out, mask); + set_cc_nz_u64(s, cc_dst); + return NO_EXIT; +} + /* ====================================================================== */ /* The "Cc OUTput" generators. Given the generated output (and in some cases the original inputs), update the various cc data structures in order to