qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Dirk Behme <dirk.behme@googlemail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Add special MIPS multiply instructions
Date: Sat, 22 Jul 2006 08:04:46 +0200	[thread overview]
Message-ID: <44C1BFFE.70800@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 349 bytes --]


This is an update of MIPS NEC VR5400 special instruction
patch [1]. It is necessary because of MIPS instruction set
configuration patch. Therefore this patch has to be applied
on top of

http://lists.gnu.org/archive/html/qemu-devel/2006-07/msg00158.html

Best regards

Dirk

[1]
http://lists.gnu.org/archive/html/qemu-devel/2006-04/msg00375.html



[-- Attachment #2: qemu-mips-r5400-patch.txt --]
[-- Type: text/plain, Size: 12033 bytes --]

--- ./target-mips/op_helper.c_orig	2006-07-22 07:32:51.000000000 +0200
+++ ./target-mips/op_helper.c	2006-07-22 08:01:16.000000000 +0200
@@ -128,6 +128,134 @@ void do_msubu (void)
     tmp = ((uint64_t)T0 * (uint64_t)T1);
     set_HILO(get_HILO() - tmp);
 }
+
+#ifdef MIPS_USES_NEC_VR5400
+void do_muls (void)
+{
+    int64_t tmp;
+
+    tmp = 0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+}
+
+void do_mulsu (void)
+{
+    uint64_t tmp;
+
+    tmp = 0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+}
+
+void do_macc (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+}
+
+void do_macchi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+
+void do_maccu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF; 
+}
+
+void do_macchiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+
+void do_msac (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+}
+
+void do_msachi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+
+void do_msacu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+}
+
+void do_msachiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+
+void do_mulhi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+
+void do_mulhiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+
+void do_mulshi (void)
+{
+    int64_t tmp;
+
+    tmp = 0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+
+void do_mulshiu (void)
+{
+    uint64_t tmp;
+
+    tmp = 0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+}
+#endif /* MIPS_USES_NEC_VR5400 */
 #endif
 
 #if defined(CONFIG_USER_ONLY) 
@@ -159,6 +287,149 @@ void do_tlbr (void)
 {
     cpu_abort(env, "tlbr\n");
 }
+
+#ifdef MIPS_USES_NEC_VR5400
+void op_muls (void)
+{
+    int64_t tmp;
+
+    tmp = 0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_mulsu (void)
+{
+    uint64_t tmp;
+
+    tmp = 0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_macc (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_macchi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_maccu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_macchiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_msac (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_msachi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_msacu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_msachiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulhi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulhiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulshi (void)
+{
+    int64_t tmp;
+
+    tmp = 0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulshiu (void)
+{
+    uint64_t tmp;
+
+    tmp = 0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+#endif /* MIPS_USES_NEC_VR5400 */
+
 #else
 
 /* CP0 helpers */
--- ./target-mips/op.c_orig	2006-07-22 07:32:51.000000000 +0200
+++ ./target-mips/op.c	2006-07-22 08:00:37.000000000 +0200
@@ -549,6 +549,148 @@ void op_msubu (void)
     set_HILO(get_HILO() - tmp);
     RETURN();
 }
+
+#ifdef MIPS_USES_NEC_VR5400
+void op_muls (void)
+{
+    int64_t tmp;
+
+    tmp = 0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_mulsu (void)
+{
+    uint64_t tmp;
+
+    tmp = 0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_macc (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_macchi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_maccu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_macchiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_msac (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_msachi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_msacu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp & 0xFFFFFFFF;
+    RETURN();
+}
+
+void op_msachiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulhi (void)
+{
+    int64_t tmp;
+
+    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulhiu (void)
+{
+    uint64_t tmp;
+
+    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulshi (void)
+{
+    int64_t tmp;
+
+    tmp = 0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+
+void op_mulshiu (void)
+{
+    uint64_t tmp;
+
+    tmp = 0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
+    set_HILO(tmp);
+    T0 = tmp >> 32;
+    RETURN();
+}
+#endif /* MIPS_USES_NEC_VR5400 */
 #else
 void op_mult (void)
 {
@@ -585,6 +727,91 @@ void op_msubu (void)
     CALL_FROM_TB0(do_msubu);
     RETURN();
 }
+
+#ifdef MIPS_USES_NEC_VR5400
+void op_muls (void)
+{
+    CALL_FROM_TB0(do_muls);
+    RETURN();
+}
+
+void op_mulsu (void)
+{
+    CALL_FROM_TB0(do_mulsu);
+    RETURN();
+}
+
+void op_macc (void)
+{
+    CALL_FROM_TB0(do_macc);
+    RETURN();
+}
+
+void op_macchi (void)
+{
+    CALL_FROM_TB0(do_macchi); 
+    RETURN();
+}
+
+void op_maccu (void)
+{
+    CALL_FROM_TB0(do_maccu); 
+    RETURN();
+}
+void op_macchiu (void)
+{
+    CALL_FROM_TB0(do_macchiu);
+    RETURN();
+}
+
+void op_msac (void)
+{
+    CALL_FROM_TB0(do_msac);
+    RETURN();
+}
+
+void op_msachi (void)
+{
+    CALL_FROM_TB0(do_msachi);
+    RETURN();
+}
+
+void op_msacu (void)
+{
+    CALL_FROM_TB0(do_msacu);
+    RETURN();
+}
+
+void op_msachiu (void)
+{
+    CALL_FROM_TB0(do_msachiu);
+    RETURN();
+}
+
+void op_mulhi (void)
+{
+    CALL_FROM_TB0(do_mulhi);
+    RETURN();
+}
+
+void op_mulhiu (void)
+{
+    CALL_FROM_TB0(do_mulhiu);
+    RETURN();
+}
+
+void op_mulshi (void)
+{
+    CALL_FROM_TB0(do_mulshi);
+    RETURN();
+}
+
+void op_mulshiu (void)
+{
+    CALL_FROM_TB0(do_mulshiu);
+    RETURN();
+}
+#endif /* MIPS_USES_NEC_VR5400 */
 #endif
 
 /* Conditional moves */
--- ./target-mips/translate.c_orig	2006-07-22 07:32:51.000000000 +0200
+++ ./target-mips/translate.c	2006-07-22 08:01:44.000000000 +0200
@@ -984,6 +984,81 @@ static void gen_muldiv (DisasContext *ct
     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
 }
 
+#ifdef MIPS_USES_NEC_VR5400
+static void gen_muldiv_ext (DisasContext *ctx, uint16_t opc,
+                            int rd, int rs, int rt)
+{
+    const unsigned char *opn = "unk";
+
+    GEN_LOAD_REG_TN(T0, rs);
+    GEN_LOAD_REG_TN(T1, rt);
+    switch (opc) {
+    case 0x0d8:
+        gen_op_muls();
+        opn = "muls";
+	break;
+    case 0x0d9:
+        gen_op_mulsu();
+        opn = "mulsu";
+	break;
+    case 0x158:
+        gen_op_macc();
+        opn = "macc";
+	break;
+    case 0x159:
+        gen_op_maccu();
+        opn = "maccu";
+	break;
+    case 0x1d8:
+        gen_op_msac();
+        opn = "msac";
+	break;
+    case 0x1d9:
+        gen_op_msacu();
+        opn = "msacu";
+	break;
+    case 0x258:
+        gen_op_mulhi();
+        opn = "mulhi";
+	break;
+    case 0x259:
+        gen_op_mulhiu();
+        opn = "mulhiu";
+	break;
+    case 0x2d8:
+        gen_op_mulshi();
+        opn = "mulshi";
+	break;
+    case 0x2d9:
+        gen_op_mulshiu();
+        opn = "mulshiu";
+	break;
+    case 0x358:
+        gen_op_macchi();
+        opn = "macchi";
+	break;
+    case 0x359:
+        gen_op_macchiu();
+        opn = "macchiu";
+	break;
+    case 0x3d8:
+        gen_op_msachi();
+        opn = "msachi";
+	break;
+    case 0x3d9:
+        gen_op_msachiu();
+        opn = "msachiu";
+	break;
+    default:
+        MIPS_INVAL("mul/div ext");
+        generate_exception(ctx, EXCP_RI);
+        return;
+    }
+    GEN_STORE_TN_REG(rd, T0);
+    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
+}
+#endif /* MIPS_USES_NEC_VR5400 */
+
 static void gen_cl (DisasContext *ctx, uint16_t opc,
                     int rd, int rs)
 {
@@ -1932,7 +2007,7 @@ static void decode_opc (CPUState *env, D
 	    } else {
 	        if(mips_uses_nec_vr5400()) {
 	            op1 = ctx->opcode & 0x7FF;
-	            /* tbd: call handler for special NEC instructions */
+	            gen_muldiv_ext(ctx, op1, rd, rs, rt);
                 } else {
 	            MIPS_INVAL("NEC extension");
                     generate_exception(ctx, EXCP_RI);



             reply	other threads:[~2006-07-22  6:04 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-22  6:04 Dirk Behme [this message]
  -- strict thread matches above, loose matches on Subject: below --
2006-04-21 18:30 [Qemu-devel] [PATCH] Add special MIPS multiply instructions Dirk Behme

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=44C1BFFE.70800@gmail.com \
    --to=dirk.behme@googlemail.com \
    --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).