qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org
Subject: [Qemu-devel] [PULL 23/26] target-hppa: Implement shifts and deposits
Date: Sun, 22 Jan 2017 18:17:45 -0800	[thread overview]
Message-ID: <20170123021748.13170-24-rth@twiddle.net> (raw)
In-Reply-To: <20170123021748.13170-1-rth@twiddle.net>

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 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:
-- 
2.9.3

  parent reply	other threads:[~2017-01-23  2:18 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-23  2:17 [Qemu-devel] [PULL 00/26] New hppa-linux target support Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 01/26] Revert "Remove remainders of HPPA backend" Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 02/26] linux-user: Support stack-grows-up in elfload.c Richard Henderson
2017-06-27 16:32   ` Peter Maydell
2017-01-23  2:17 ` [Qemu-devel] [PULL 03/26] linux-user: Handle TIOCSTART and TIOCSTOP Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 04/26] linux-user: Add SIOCGPGRP, SIOCGSTAMP, SIOCGSTAMPNS Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 05/26] linux-user: Handle ERFKILL and EHWPOISON Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 06/26] linux-user: Handle more IPV6 sockopts Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 08/26] linux-user: Add HPPA socket.h definitions Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 09/26] linux-user: Add HPPA syscall numbers Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 10/26] linux-user: Add HPPA termbits.h Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 11/26] linux-user: Add HPPA target_syscall.h Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 12/26] linux-user: Add HPPA definitions to syscall_defs.h Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 13/26] linux-user: Add HPPA target_structs.h Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 14/26] linux-user: Add HPPA target_signal.h and target_cpu.h Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 15/26] linux-user: Add HPPA signal handling Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 16/26] linux-user: Add HPPA startup and main loop Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 17/26] target-hppa: Add softfloat specializations Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 18/26] target-hppa: Add framework and enable compilation Richard Henderson
2017-01-30 13:49   ` Peter Maydell
2017-02-07  2:27     ` Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 19/26] target-hppa: Add nullification framework Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 20/26] target-hppa: Implement basic arithmetic Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 21/26] target-hppa: Implement branches Richard Henderson
2017-01-26 12:14   ` Paolo Bonzini
2017-01-26 17:18     ` Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 22/26] target-hppa: Implement linux-user gateway page Richard Henderson
2017-01-23  2:17 ` Richard Henderson [this message]
2017-01-23  2:17 ` [Qemu-devel] [PULL 24/26] target-hppa: Implement loads and stores Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 25/26] target-hppa: Implement system and memory-management insns Richard Henderson
2017-01-23  2:17 ` [Qemu-devel] [PULL 26/26] target-hppa: Implement floating-point insns Richard Henderson
2017-01-23 10:31 ` [Qemu-devel] [PULL 00/26] New hppa-linux target support Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170123021748.13170-24-rth@twiddle.net \
    --to=rth@twiddle.net \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).