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 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).