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);
_______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel