From patchwork Mon Jan 23 02:17:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 718352 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3v6G5853N4z9s5g for ; Mon, 23 Jan 2017 13:50:20 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="oKHmB0Yp"; dkim-atps=neutral Received: from localhost ([::1]:38844 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cVUi2-0001C6-9Y for incoming@patchwork.ozlabs.org; Sun, 22 Jan 2017 21:50:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46740) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cVUDC-0007vD-0N for qemu-devel@nongnu.org; Sun, 22 Jan 2017 21:18:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cVUDA-0004xe-J8 for qemu-devel@nongnu.org; Sun, 22 Jan 2017 21:18:25 -0500 Received: from mail-qt0-x243.google.com ([2607:f8b0:400d:c0d::243]:32821) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cVUDA-0004xU-Eg for qemu-devel@nongnu.org; Sun, 22 Jan 2017 21:18:24 -0500 Received: by mail-qt0-x243.google.com with SMTP id n13so14087770qtc.0 for ; Sun, 22 Jan 2017 18:18:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=K93nwCrdrzSfFUMiYrmdEmBq5u48pQV8dfMt0kVZlAI=; b=oKHmB0YpVrJqMprR2Er9/XP5HuyedJlGKJwUVyJ+EE8CGUzmRAo27SxUjAw/Ta5HRF /peq+IW5tm/QDM/fyrF4S6JHpd9jQgi6VKtFwOMm0Q28BQYHond+mXBw7ZM+Zx08NqgS DNni/JEzCZbtL4T2BbwyHxk8Rn3cJ9V5QK4M8hIYEjyvXazYhxDtuhoMZOcGsKLKeGvX Lg3r4Paj2bTdfIpDM0t0M+2x9y69cA0tx1G1fmad8iaAiIEtm0hamJP883q3Ryihhspb PgfibArxrywWCsT6YMVpzY/3ngmhm+gf8y+SK3XlYN1jyi4K/bJovf5AdHOgE3nO77o0 fu4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=K93nwCrdrzSfFUMiYrmdEmBq5u48pQV8dfMt0kVZlAI=; b=am4fkzpHvt0mw0q6LGSt/zwNMHcs7T7GKJlswCmgbfQjfBtMqfKGOg4Up+9d4sTCZo 34WKWUT4YJs3ZxHCXdeVfTYQCeaF+TehYyUR17vK+1mUbPBAe4Xr/HIR3guEPufL7oXF GTkJVW5Mq3EdYtLfm3+08txqFS+f3HuySNOgNeMFOd/2dsaqF05ZmdRgO7/wHJxzFc5t leJ3dRNeRFyyWwS2eZEYde4tznX/KuE5WaQ+39GnOig2Tw6QvyW6l41cfrZLhmYt1X4z vIygv0ccT1jCd2KTszU3HZf0PttPLV3o7/0DUQi/Tkpsiof0GuzDUAWZdmeC2mNXWWZQ Gcrw== X-Gm-Message-State: AIkVDXJyCtdKM3emlrn/GIvh332CKfoVuyux/u+qD+agQ9ND4J1iPyxa4eexzomFDV1jZA== X-Received: by 10.237.38.3 with SMTP id z3mr21358218qtc.22.1485137903911; Sun, 22 Jan 2017 18:18:23 -0800 (PST) Received: from bigtime.twiddle.net.com ([2602:47:d954:1500:5e51:4fff:fe40:9c64]) by smtp.gmail.com with ESMTPSA id m85sm12097734qkl.28.2017.01.22.18.18.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 22 Jan 2017 18:18:23 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sun, 22 Jan 2017 18:17:45 -0800 Message-Id: <20170123021748.13170-24-rth@twiddle.net> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170123021748.13170-1-rth@twiddle.net> References: <20170123021748.13170-1-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c0d::243 Subject: [Qemu-devel] [PULL 23/26] target-hppa: Implement shifts and deposits X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- target/hppa/translate.c | 309 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 14fe4bb..093a65e 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -1719,6 +1719,311 @@ static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm) return do_cbranch(ctx, disp, n, &cond); } +static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned rt = extract32(insn, 0, 5); + unsigned c = extract32(insn, 13, 3); + unsigned r1 = extract32(insn, 16, 5); + unsigned r2 = extract32(insn, 21, 5); + TCGv dest; + + if (c) { + nullify_over(ctx); + } + + dest = dest_gpr(ctx, rt); + if (r1 == 0) { + tcg_gen_ext32u_tl(dest, load_gpr(ctx, r2)); + tcg_gen_shr_tl(dest, dest, cpu_sar); + } else if (r1 == r2) { + TCGv_i32 t32 = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t32, load_gpr(ctx, r2)); + tcg_gen_rotr_i32(t32, t32, cpu_sar); + tcg_gen_extu_i32_tl(dest, t32); + tcg_temp_free_i32(t32); + } else { + TCGv_i64 t = tcg_temp_new_i64(); + TCGv_i64 s = tcg_temp_new_i64(); + + tcg_gen_concat_tl_i64(t, load_gpr(ctx, r2), load_gpr(ctx, r1)); + tcg_gen_extu_tl_i64(s, cpu_sar); + tcg_gen_shr_i64(t, t, s); + tcg_gen_trunc_i64_tl(dest, t); + + tcg_temp_free_i64(t); + tcg_temp_free_i64(s); + } + save_gpr(ctx, rt, dest); + + /* Install the new nullification. */ + cond_free(&ctx->null_cond); + if (c) { + ctx->null_cond = do_sed_cond(c, dest); + } + return nullify_end(ctx, NO_EXIT); +} + +static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned rt = extract32(insn, 0, 5); + unsigned cpos = extract32(insn, 5, 5); + unsigned c = extract32(insn, 13, 3); + unsigned r1 = extract32(insn, 16, 5); + unsigned r2 = extract32(insn, 21, 5); + unsigned sa = 31 - cpos; + TCGv dest, t2; + + if (c) { + nullify_over(ctx); + } + + dest = dest_gpr(ctx, rt); + t2 = load_gpr(ctx, r2); + if (r1 == r2) { + TCGv_i32 t32 = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(t32, t2); + tcg_gen_rotri_i32(t32, t32, sa); + tcg_gen_extu_i32_tl(dest, t32); + tcg_temp_free_i32(t32); + } else if (r1 == 0) { + tcg_gen_extract_tl(dest, t2, sa, 32 - sa); + } else { + TCGv t0 = tcg_temp_new(); + tcg_gen_extract_tl(t0, t2, sa, 32 - sa); + tcg_gen_deposit_tl(dest, t0, cpu_gr[r1], 32 - sa, sa); + tcg_temp_free(t0); + } + save_gpr(ctx, rt, dest); + + /* Install the new nullification. */ + cond_free(&ctx->null_cond); + if (c) { + ctx->null_cond = do_sed_cond(c, dest); + } + return nullify_end(ctx, NO_EXIT); +} + +static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned clen = extract32(insn, 0, 5); + unsigned is_se = extract32(insn, 10, 1); + unsigned c = extract32(insn, 13, 3); + unsigned rt = extract32(insn, 16, 5); + unsigned rr = extract32(insn, 21, 5); + unsigned len = 32 - clen; + TCGv dest, src, tmp; + + if (c) { + nullify_over(ctx); + } + + dest = dest_gpr(ctx, rt); + src = load_gpr(ctx, rr); + tmp = tcg_temp_new(); + + /* Recall that SAR is using big-endian bit numbering. */ + tcg_gen_xori_tl(tmp, cpu_sar, TARGET_LONG_BITS - 1); + if (is_se) { + tcg_gen_sar_tl(dest, src, tmp); + tcg_gen_sextract_tl(dest, dest, 0, len); + } else { + tcg_gen_shr_tl(dest, src, tmp); + tcg_gen_extract_tl(dest, dest, 0, len); + } + tcg_temp_free(tmp); + save_gpr(ctx, rt, dest); + + /* Install the new nullification. */ + cond_free(&ctx->null_cond); + if (c) { + ctx->null_cond = do_sed_cond(c, dest); + } + return nullify_end(ctx, NO_EXIT); +} + +static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned clen = extract32(insn, 0, 5); + unsigned pos = extract32(insn, 5, 5); + unsigned is_se = extract32(insn, 10, 1); + unsigned c = extract32(insn, 13, 3); + unsigned rt = extract32(insn, 16, 5); + unsigned rr = extract32(insn, 21, 5); + unsigned len = 32 - clen; + unsigned cpos = 31 - pos; + TCGv dest, src; + + if (c) { + nullify_over(ctx); + } + + dest = dest_gpr(ctx, rt); + src = load_gpr(ctx, rr); + if (is_se) { + tcg_gen_sextract_tl(dest, src, cpos, len); + } else { + tcg_gen_extract_tl(dest, src, cpos, len); + } + save_gpr(ctx, rt, dest); + + /* Install the new nullification. */ + cond_free(&ctx->null_cond); + if (c) { + ctx->null_cond = do_sed_cond(c, dest); + } + return nullify_end(ctx, NO_EXIT); +} + +static const DisasInsn table_sh_ex[] = { + { 0xd0000000u, 0xfc001fe0u, trans_shrpw_sar }, + { 0xd0000800u, 0xfc001c00u, trans_shrpw_imm }, + { 0xd0001000u, 0xfc001be0u, trans_extrw_sar }, + { 0xd0001800u, 0xfc001800u, trans_extrw_imm }, +}; + +static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned clen = extract32(insn, 0, 5); + unsigned cpos = extract32(insn, 5, 5); + unsigned nz = extract32(insn, 10, 1); + unsigned c = extract32(insn, 13, 3); + target_long val = low_sextract(insn, 16, 5); + unsigned rt = extract32(insn, 21, 5); + unsigned len = 32 - clen; + target_long mask0, mask1; + TCGv dest; + + if (c) { + nullify_over(ctx); + } + if (cpos + len > 32) { + len = 32 - cpos; + } + + dest = dest_gpr(ctx, rt); + mask0 = deposit64(0, cpos, len, val); + mask1 = deposit64(-1, cpos, len, val); + + if (nz) { + TCGv src = load_gpr(ctx, rt); + if (mask1 != -1) { + tcg_gen_andi_tl(dest, src, mask1); + src = dest; + } + tcg_gen_ori_tl(dest, src, mask0); + } else { + tcg_gen_movi_tl(dest, mask0); + } + save_gpr(ctx, rt, dest); + + /* Install the new nullification. */ + cond_free(&ctx->null_cond); + if (c) { + ctx->null_cond = do_sed_cond(c, dest); + } + return nullify_end(ctx, NO_EXIT); +} + +static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned clen = extract32(insn, 0, 5); + unsigned cpos = extract32(insn, 5, 5); + unsigned nz = extract32(insn, 10, 1); + unsigned c = extract32(insn, 13, 3); + unsigned rr = extract32(insn, 16, 5); + unsigned rt = extract32(insn, 21, 5); + unsigned rs = nz ? rt : 0; + unsigned len = 32 - clen; + TCGv dest, val; + + if (c) { + nullify_over(ctx); + } + if (cpos + len > 32) { + len = 32 - cpos; + } + + dest = dest_gpr(ctx, rt); + val = load_gpr(ctx, rr); + if (rs == 0) { + tcg_gen_deposit_z_tl(dest, val, cpos, len); + } else { + tcg_gen_deposit_tl(dest, cpu_gr[rs], val, cpos, len); + } + save_gpr(ctx, rt, dest); + + /* Install the new nullification. */ + cond_free(&ctx->null_cond); + if (c) { + ctx->null_cond = do_sed_cond(c, dest); + } + return nullify_end(ctx, NO_EXIT); +} + +static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn, + const DisasInsn *di) +{ + unsigned clen = extract32(insn, 0, 5); + unsigned nz = extract32(insn, 10, 1); + unsigned i = extract32(insn, 12, 1); + unsigned c = extract32(insn, 13, 3); + unsigned rt = extract32(insn, 21, 5); + unsigned rs = nz ? rt : 0; + unsigned len = 32 - clen; + TCGv val, mask, tmp, shift, dest; + unsigned msb = 1U << (len - 1); + + if (c) { + nullify_over(ctx); + } + + if (i) { + val = load_const(ctx, low_sextract(insn, 16, 5)); + } else { + val = load_gpr(ctx, extract32(insn, 16, 5)); + } + dest = dest_gpr(ctx, rt); + shift = tcg_temp_new(); + tmp = tcg_temp_new(); + + /* Convert big-endian bit numbering in SAR to left-shift. */ + tcg_gen_xori_tl(shift, cpu_sar, TARGET_LONG_BITS - 1); + + mask = tcg_const_tl(msb + (msb - 1)); + tcg_gen_and_tl(tmp, val, mask); + if (rs) { + tcg_gen_shl_tl(mask, mask, shift); + tcg_gen_shl_tl(tmp, tmp, shift); + tcg_gen_andc_tl(dest, cpu_gr[rs], mask); + tcg_gen_or_tl(dest, dest, tmp); + } else { + tcg_gen_shl_tl(dest, tmp, shift); + } + tcg_temp_free(shift); + tcg_temp_free(mask); + tcg_temp_free(tmp); + save_gpr(ctx, rt, dest); + + /* Install the new nullification. */ + cond_free(&ctx->null_cond); + if (c) { + ctx->null_cond = do_sed_cond(c, dest); + } + return nullify_end(ctx, NO_EXIT); +} + +static const DisasInsn table_depw[] = { + { 0xd4000000u, 0xfc000be0u, trans_depw_sar }, + { 0xd4000800u, 0xfc001800u, trans_depw_imm }, + { 0xd4001800u, 0xfc001800u, trans_depw_imm_c }, +}; + static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l) { unsigned n = extract32(insn, 1, 1); @@ -1874,6 +2179,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) return trans_movb(ctx, insn, false); case 0x33: return trans_movb(ctx, insn, true); + case 0x34: + return translate_table(ctx, insn, table_sh_ex); + case 0x35: + return translate_table(ctx, insn, table_depw); case 0x38: return trans_be(ctx, insn, false); case 0x39: