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);
next 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.