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 8/8] target-tricore: Add instructions of RR1 opcode format, that have 0xb3 as first opcode
Date: Fri, 12 Dec 2014 17:31:44 +0000	[thread overview]
Message-ID: <1418405504-11175-9-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 RR1 opcode format, that have 0xb3 as first opcode.
Add helper functions mulh, mulmh and mulrh in four variants, that compute multiplication,
with multiprecision (mulmh) or rounding (mulrh) of 4 halfwords, being either low or high parts
of two 32 bit regs.

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

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 8d7958d..304c023 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -87,6 +87,19 @@ DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_h_13, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_h_131, i64, env, i32, i32)
+/* mulh */
+DEF_HELPER_4(mulh_U_L_L_L, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulh_U_L_L_U, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulh_U_L_U_L, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulh_L_U_U_U, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulmh_U_L_L_L, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulmh_U_L_L_U, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulmh_U_L_U_L, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulmh_L_U_U_U, i64, env, i32, i32, i32)
+DEF_HELPER_4(mulrh_U_L_L_L, i32, env, i32, i32, i32)
+DEF_HELPER_4(mulrh_U_L_L_U, i32, env, i32, i32, i32)
+DEF_HELPER_4(mulrh_U_L_U_L, i32, env, i32, i32, i32)
+DEF_HELPER_4(mulrh_L_U_U_U, i32, env, 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 0fd38b5..1cf9b8a 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -1254,6 +1254,117 @@ uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
     return ret;
 }

+#define MUL_H_OP(ARG00, ARG01, ARG10, ARG11)                                \
+uint64_t helper_mulh_##ARG00 ##_##ARG01 ##_##ARG10 ##_##ARG11(              \
+         CPUTriCoreState *env, target_ulong arg1, target_ulong arg2,        \
+         target_ulong n)                                                    \
+{                                                                           \
+    uint64_t ret;                                                           \
+    uint32_t result0, result1;                                              \
+    int32_t arg00 = sextract32(arg1, ARG00, 16);                            \
+    int32_t arg01 = sextract32(arg1, ARG01, 16);                            \
+    int32_t arg10 = sextract32(arg2, ARG10, 16);                            \
+    int32_t arg11 = sextract32(arg2, ARG11, 16);                            \
+                                                                            \
+                                                                            \
+    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&                           \
+                  ((arg10 & 0xffff) == 0x8000) && (n == 1);                 \
+    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&                           \
+                  ((arg11 & 0xffff) == 0x8000) && (n == 1);                 \
+    if (sc1) {                                                              \
+        result1 = 0x7fffffff;                                               \
+    } else {                                                                \
+        result1 = (((uint32_t)(arg00 * arg10)) << n);                       \
+    }                                                                       \
+    if (sc0) {                                                              \
+        result0 = 0x7fffffff;                                               \
+    } else {                                                                \
+        result0 = (((uint32_t)(arg01 * arg11)) << n);                       \
+    }                                                                       \
+    /* advanced overflow */                                                 \
+    env->PSW_USB_AV = (result1 ^ result1 * 2u) | (result0 ^ result0 * 2u);  \
+    env->PSW_USB_SAV |= env->PSW_USB_AV;                                    \
+    /* clean v bit */                                                       \
+    env->PSW_USB_V = 0;                                                     \
+    ret = (((uint64_t)result1 << 32)) | result0;                            \
+    return ret;                                                             \
+}                                                                           \
+uint64_t helper_mulmh_##ARG00 ##_##ARG01 ##_##ARG10 ##_##ARG11(             \
+         CPUTriCoreState *env, target_ulong arg1, target_ulong arg2,        \
+         target_ulong n)                                                    \
+{                                                                           \
+    uint64_t ret;                                                           \
+    int64_t result0, result1;                                               \
+    int32_t arg00 = sextract32(arg1, ARG00, 16);                            \
+    int32_t arg01 = sextract32(arg1, ARG01, 16);                            \
+    int32_t arg10 = sextract32(arg2, ARG10, 16);                            \
+    int32_t arg11 = sextract32(arg2, ARG11, 16);                            \
+                                                                            \
+    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&                           \
+                  ((arg10 & 0xffff) == 0x8000) && (n == 1);                 \
+    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&                           \
+                  ((arg11 & 0xffff) == 0x8000) && (n == 1);                 \
+                                                                            \
+    if (sc1) {                                                              \
+        result1 = 0x7fffffff;                                               \
+    } else {                                                                \
+        result1 = ((arg00 * arg10) << n);                                   \
+    }                                                                       \
+    if (sc0) {                                                              \
+        result0 = 0x7fffffff;                                               \
+    } else {                                                                \
+        result0 = ((arg01 * arg11) << n);                                   \
+    }                                                                       \
+    /* clear advanced overflow */                                           \
+    env->PSW_USB_AV = 0;                                                    \
+    /* clean v bit */                                                       \
+    env->PSW_USB_V = 0;                                                     \
+    ret = (result1 + result0);                                              \
+    ret = ret << 16;                                                        \
+    return ret;                                                             \
+}                                                                           \
+uint32_t helper_mulrh_##ARG00 ##_##ARG01 ##_##ARG10 ##_##ARG11(             \
+         CPUTriCoreState *env, target_ulong arg1, target_ulong arg2,        \
+         target_ulong n)                                                    \
+{                                                                           \
+    uint32_t result0, result1;                                              \
+    int32_t arg00 = sextract32(arg1, ARG00, 16);                            \
+    int32_t arg01 = sextract32(arg1, ARG01, 16);                            \
+    int32_t arg10 = sextract32(arg2, ARG10, 16);                            \
+    int32_t arg11 = sextract32(arg2, ARG11, 16);                            \
+                                                                            \
+    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&                           \
+                  ((arg10 & 0xffff) == 0x8000) && (n == 1);                 \
+    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&                           \
+                  ((arg11 & 0xffff) == 0x8000) && (n == 1);                 \
+                                                                            \
+    if (sc1) {                                                              \
+        result1 = 0x7fffffff;                                               \
+    } else {                                                                \
+        result1 = ((arg00 * arg10) << n) + 0x8000;                          \
+    }                                                                       \
+    if (sc0) {                                                              \
+        result0 = 0x7fffffff;                                               \
+    } else {                                                                \
+        result0 = ((arg01 * arg11) << n) + 0x8000;                          \
+    }                                                                       \
+    /* advanced overflow */                                                 \
+    env->PSW_USB_AV = (result1 ^ result1 * 2u) | (result0 ^ result0 * 2u);  \
+    env->PSW_USB_SAV |= env->PSW_USB_AV;                                    \
+    /* clean v bit */                                                       \
+    env->PSW_USB_V = 0;                                                     \
+    return (result1 & 0xffff0000) | (result0 >> 16);                        \
+}
+
+#define U 16
+#define L 0
+MUL_H_OP(U, L, L, L)
+MUL_H_OP(U, L, L, U)
+MUL_H_OP(U, L, U, L)
+MUL_H_OP(L, U, U, U)
+#undef U
+#undef L
+
 /* 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 aacf097..36a85d6 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -4573,6 +4573,98 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
     }
 }

+/* RR1 Format */
+static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+
+    int r1, r2, r3;
+    TCGv n;
+    TCGv_i64 temp64;
+
+    r1 = MASK_OP_RR1_S1(ctx->opcode);
+    r2 = MASK_OP_RR1_S2(ctx->opcode);
+    r3 = MASK_OP_RR1_D(ctx->opcode);
+    n  = tcg_const_i32(MASK_OP_RR1_N(ctx->opcode));
+    op2 = MASK_OP_RR1_OP2(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RR1_MUL_H_32_LL:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulh_U_L_L_L(temp64, cpu_env, cpu_gpr_d[r1],
+                                cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MUL_H_32_LU:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulh_U_L_L_U(temp64, cpu_env, cpu_gpr_d[r1],
+                                cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MUL_H_32_UL:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulh_U_L_U_L(temp64, cpu_env, cpu_gpr_d[r1],
+                                cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MUL_H_32_UU:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulh_L_U_U_U(temp64, cpu_env, cpu_gpr_d[r1],
+                                cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_LL:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulmh_U_L_L_L(temp64, cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_LU:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulmh_U_L_L_U(temp64, cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_UL:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulmh_U_L_U_L(temp64, cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_UU:
+        temp64 = tcg_temp_new_i64();
+        gen_helper_mulmh_L_U_U_U(temp64, cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULR_H_16_LL:
+        gen_helper_mulrh_U_L_L_L(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                                     cpu_gpr_d[r2], n);
+        break;
+    case OPC2_32_RR1_MULR_H_16_LU:
+        gen_helper_mulrh_U_L_L_U(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2], n);
+        break;
+    case OPC2_32_RR1_MULR_H_16_UL:
+        gen_helper_mulrh_U_L_U_L(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2], n);
+        break;
+    case OPC2_32_RR1_MULR_H_16_UU:
+        gen_helper_mulrh_L_U_U_U(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2], n);
+        break;
+    }
+    tcg_temp_free(n);
+}
+
 static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 {
     int op1;
@@ -4825,6 +4917,10 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     case OPCM_32_RR_DIVIDE:
         decode_rr_divide(env, ctx);
         break;
+/* RR1 Format */
+    case OPCM_32_RR1_MUL:
+        decode_rr1_mul(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 ` [Qemu-devel] [PATCH 3/8] target-tricore: Add instructions of RR opcode format, that have 0xf " Bastian Koppelmann
2014-12-12 20:04   ` 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 ` Bastian Koppelmann [this message]
2014-12-12 20:53   ` [Qemu-devel] [PATCH 8/8] target-tricore: Add instructions of RR1 opcode format, that have 0xb3 as first opcode 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-9-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).