[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Add special MIPS multiply instructions
From: |
Dirk Behme |
Subject: |
[Qemu-devel] [PATCH] Add special MIPS multiply instructions |
Date: |
Sat, 22 Jul 2006 08:04:46 +0200 |
User-agent: |
Mozilla Thunderbird 1.0.7 (X11/20050923) |
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
--- ./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);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH] Add special MIPS multiply instructions,
Dirk Behme <=