qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
To: qemu-devel@nongnu.org
Cc: rth@twiddle.net
Subject: [Qemu-devel] [PATCH 3/8] target-tricore: Add instructions of RR opcode format, that have 0xf as the first opcode
Date: Fri, 12 Dec 2014 17:31:39 +0000	[thread overview]
Message-ID: <1418405504-11175-4-git-send-email-kbastian@mail.uni-paderborn.de> (raw)
In-Reply-To: <1418405504-11175-1-git-send-email-kbastian@mail.uni-paderborn.de>

Add instructions of RR opcode format, that have 0xf as the first opcode.
Add helper functions:
    * clo/z/s: Counts leading ones/zeros/signs.
    * clo/z/s_h: Count leading ones/zeros/signs in two haflwords.
    * sh/_h: Shifts one/two word/hwords.
    * sha/_h: Shifts one/two word/hwords arithmeticly.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
 target-tricore/helper.h    |  12 ++++
 target-tricore/op_helper.c | 160 +++++++++++++++++++++++++++++++++++++++++++++
 target-tricore/translate.c |  78 ++++++++++++++++++++++
 3 files changed, 250 insertions(+)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index ce3f6db..8e57e77 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -64,6 +64,18 @@ DEF_HELPER_2(min_b, i32, i32, i32)
 DEF_HELPER_2(min_bu, i32, i32, i32)
 DEF_HELPER_2(min_h, i32, i32, i32)
 DEF_HELPER_2(min_hu, i32, i32, i32)
+/* count leading ... */
+DEF_HELPER_1(clo, i32, i32)
+DEF_HELPER_1(clo_h, i32, i32)
+DEF_HELPER_1(clz, i32, i32)
+DEF_HELPER_1(clz_h, i32, i32)
+DEF_HELPER_1(cls, i32, i32)
+DEF_HELPER_1(cls_h, i32, i32)
+/* sh */
+DEF_HELPER_2(sh, i32, i32, i32)
+DEF_HELPER_2(sh_h, i32, i32, i32)
+DEF_HELPER_3(sha, i32, env, i32, i32)
+DEF_HELPER_2(sha_h, i32, i32, i32)
 /* CSA */
 DEF_HELPER_2(call, void, env, i32)
 DEF_HELPER_1(ret, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 3885897..914d051 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -899,6 +899,166 @@ EXTREMA_H_B(min, <)
 
 #undef EXTREMA_H_B
 
+uint32_t helper_clo(target_ulong r1)
+{
+    return clo32(r1);
+}
+
+uint32_t helper_clo_h(target_ulong r1)
+{
+    uint32_t ret_hw0 = extract32(r1, 0, 16);
+    uint32_t ret_hw1 = extract32(r1, 16, 16);
+
+    ret_hw0 = clo32(ret_hw0 << 16);
+    ret_hw1 = clo32(ret_hw1 << 16);
+
+    if (ret_hw0 > 16) {
+        ret_hw0 = 16;
+    }
+    if (ret_hw1 > 16) {
+        ret_hw1 = 16;
+    }
+
+    return ret_hw0 | (ret_hw1 << 16);
+}
+
+uint32_t helper_clz(target_ulong r1)
+{
+    return clz32(r1);
+}
+
+uint32_t helper_clz_h(target_ulong r1)
+{
+    uint32_t ret_hw0 = extract32(r1, 0, 16);
+    uint32_t ret_hw1 = extract32(r1, 16, 16);
+
+    ret_hw0 = clz32(ret_hw0 << 16);
+    ret_hw1 = clz32(ret_hw1 << 16);
+
+    if (ret_hw0 > 16) {
+        ret_hw0 = 16;
+    }
+    if (ret_hw1 > 16) {
+        ret_hw1 = 16;
+    }
+
+    return ret_hw0 | (ret_hw1 << 16);
+}
+
+uint32_t helper_cls(target_ulong r1)
+{
+    return clrsb32(r1);
+}
+
+uint32_t helper_cls_h(target_ulong r1)
+{
+    uint32_t ret_hw0 = extract32(r1, 0, 16);
+    uint32_t ret_hw1 = extract32(r1, 16, 16);
+
+    ret_hw0 = clrsb32(ret_hw0 << 16);
+    ret_hw1 = clrsb32(ret_hw1 << 16);
+
+    if (ret_hw0 > 15) {
+        ret_hw0 = 15;
+    }
+    if (ret_hw1 > 15) {
+        ret_hw1 = 15;
+    }
+
+    return ret_hw0 | (ret_hw1 << 16);
+}
+
+uint32_t helper_sh(target_ulong r1, target_ulong r2)
+{
+    int32_t shift_count = sextract32(r2, 0, 6);
+
+    if (shift_count == -32) {
+        return 0;
+    } else if (shift_count < 0) {
+        return r1 >> -shift_count;
+    } else {
+        return r1 << shift_count;
+    }
+}
+
+uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
+{
+    int32_t ret_hw0, ret_hw1;
+    int32_t shift_count;
+
+    shift_count = sextract32(r2, 0, 5);
+
+    if (shift_count == -16) {
+        return 0;
+    } else if (shift_count < 0) {
+        ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
+        ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
+        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+    } else {
+        ret_hw0 = extract32(r1, 0, 16) << shift_count;
+        ret_hw1 = extract32(r1, 16, 16) << shift_count;
+        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+    }
+}
+
+uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
+{
+    int32_t shift_count;
+    int64_t result, t1;
+    uint32_t ret;
+
+    shift_count = sextract32(r2, 0, 6);
+    t1 = sextract32(r1, 0, 32);
+
+    if (shift_count == 0) {
+        env->PSW_USB_C = env->PSW_USB_V = 0;
+        ret = r1;
+    } else if (shift_count == -32) {
+        env->PSW_USB_C = r1;
+        env->PSW_USB_V = 0;
+        ret = t1 >> 31;
+    } else if (shift_count > 0) {
+        result = t1 << shift_count;
+        /* calc carry */
+        env->PSW_USB_C = ((result & 0xffffffff00000000) != 0);
+        /* calc v */
+        env->PSW_USB_V = (((result > 0x7fffffffLL) ||
+                           (result < -0x80000000LL)) << 31);
+        /* calc sv */
+        env->PSW_USB_SV |= env->PSW_USB_V;
+        ret = (uint32_t)result;
+    } else {
+        env->PSW_USB_V = 0;
+        env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
+        ret = t1 >> -shift_count;
+    }
+
+    env->PSW_USB_AV = ret ^ ret * 2u;
+    env->PSW_USB_SAV |= env->PSW_USB_AV;
+
+    return ret;
+}
+
+uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
+{
+    int32_t shift_count;
+    int32_t ret_hw0, ret_hw1;
+
+    shift_count = sextract32(r2, 0, 5);
+
+    if (shift_count == 0) {
+        return r1;
+    } else if (shift_count < 0) {
+        ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
+        ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
+        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+    } else {
+        ret_hw0 = sextract32(r1, 0, 16) << shift_count;
+        ret_hw1 = sextract32(r1, 16, 16) << shift_count;
+        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
+    }
+}
+
 /* context save area (CSA) related helpers */
 
 static int cdc_increment(target_ulong *psw)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index a1f29db..323b680 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -4181,6 +4181,81 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
     }
 }
 
+static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r3, r2, r1;
+    TCGv temp;
+
+    r3 = MASK_OP_RR_D(ctx->opcode);
+    r2 = MASK_OP_RR_S2(ctx->opcode);
+    r1 = MASK_OP_RR_S1(ctx->opcode);
+
+    temp = tcg_temp_new();
+    op2 = MASK_OP_RR_OP2(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RR_AND:
+        tcg_gen_and_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ANDN:
+        tcg_gen_andc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_CLO:
+        gen_helper_clo(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLO_H:
+        gen_helper_clo_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLS:
+        gen_helper_cls(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLS_H:
+        gen_helper_cls_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLZ:
+        gen_helper_clz(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLZ_H:
+        gen_helper_clz_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_NAND:
+        tcg_gen_nand_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_NOR:
+        tcg_gen_nor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_OR:
+        tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ORN:
+        tcg_gen_orc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH:
+        gen_helper_sh(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH_H:
+        gen_helper_sh_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SHA:
+        gen_helper_sha(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SHA_H:
+        gen_helper_sha_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SHAS:
+        gen_shas(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_XNOR:
+        tcg_gen_eqv_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_XOR:
+        tcg_gen_xor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    }
+    tcg_temp_free(temp);
+}
+
 static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 {
     int op1;
@@ -4415,6 +4490,9 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     case OPCM_32_RR_ACCUMULATOR:
         decode_rr_accumulator(env, ctx);
         break;
+    case OPCM_32_RR_LOGICAL_SHIFT:
+        decode_rr_logical_shift(env, ctx);
+        break;
     }
 }
 
-- 
2.1.3

  parent reply	other threads:[~2014-12-12 16:31 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-12 17:31 [Qemu-devel] [PATCH 0/8] TriCore add instructions of RR and RR1 opcode format Bastian Koppelmann
2014-12-12 17:31 ` [Qemu-devel] [PATCH 1/8] target-tricore: Change SSOV/SUOV makro name to SSOV32/SUOV32 Bastian Koppelmann
2014-12-12 19:31   ` Richard Henderson
2014-12-12 17:31 ` [Qemu-devel] [PATCH 2/8] target-tricore: Add instructions of RR opcode format, that have 0xb as the first opcode Bastian Koppelmann
2014-12-12 19:49   ` Richard Henderson
2014-12-12 17:31 ` Bastian Koppelmann [this message]
2014-12-12 20:04   ` [Qemu-devel] [PATCH 3/8] target-tricore: Add instructions of RR opcode format, that have 0xf " Richard Henderson
2014-12-12 17:31 ` [Qemu-devel] [PATCH 4/8] target-tricore: Add instructions of RR opcode format, that have 0x1 " Bastian Koppelmann
2014-12-12 20:06   ` Richard Henderson
2014-12-12 17:31 ` [Qemu-devel] [PATCH 5/8] target-tricore: Add instructions of RR opcode format, that have 0x4b " Bastian Koppelmann
2014-12-12 20:45   ` Richard Henderson
2014-12-17 15:43     ` Bastian Koppelmann
2014-12-12 17:31 ` [Qemu-devel] [PATCH 6/8] target-tricore: Add missing 1.6 insn of BOL opcode format Bastian Koppelmann
2014-12-12 20:46   ` Richard Henderson
2014-12-12 17:31 ` [Qemu-devel] [PATCH 7/8] target-tricore: Fix MFCR/MTCR insn and B format offset Bastian Koppelmann
2014-12-12 20:49   ` Richard Henderson
2014-12-12 17:31 ` [Qemu-devel] [PATCH 8/8] target-tricore: Add instructions of RR1 opcode format, that have 0xb3 as first opcode Bastian Koppelmann
2014-12-12 20:53   ` Richard Henderson

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=1418405504-11175-4-git-send-email-kbastian@mail.uni-paderborn.de \
    --to=kbastian@mail.uni-paderborn.de \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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).