mirror of https://github.com/xemu-project/xemu.git
target-mips: add new Floating Point Comparison instructions
Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
e7f16abbc5
commit
3f4938833c
44
disas/mips.c
44
disas/mips.c
|
@ -1317,6 +1317,50 @@ const struct mips_opcode mips_builtin_opcodes[] =
|
|||
{"bc1nez", "T,p", 0x45a00000, 0xffe00000, CBD|RD_T|FP_S|FP_D, 0, I32R6},
|
||||
{"bc2eqz", "E,p", 0x49200000, 0xffe00000, CBD|RD_C2, 0, I32R6},
|
||||
{"bc2nez", "E,p", 0x49a00000, 0xffe00000, CBD|RD_C2, 0, I32R6},
|
||||
{"cmp.af.s", "D,S,T", 0x46800000, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.un.s", "D,S,T", 0x46800001, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.eq.s", "D,S,T", 0x46800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ueq.s", "D,S,T", 0x46800003, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.lt.s", "D,S,T", 0x46800004, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ult.s", "D,S,T", 0x46800005, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.le.s", "D,S,T", 0x46800006, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ule.s", "D,S,T", 0x46800007, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.saf.s", "D,S,T", 0x46800008, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sun.s", "D,S,T", 0x46800009, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.seq.s", "D,S,T", 0x4680000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sueq.s", "D,S,T", 0x4680000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.slt.s", "D,S,T", 0x4680000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sult.s", "D,S,T", 0x4680000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sle.s", "D,S,T", 0x4680000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sule.s", "D,S,T", 0x4680000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.or.s", "D,S,T", 0x46800011, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.une.s", "D,S,T", 0x46800012, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ne.s", "D,S,T", 0x46800013, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sor.s", "D,S,T", 0x46800019, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sune.s", "D,S,T", 0x4680001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sne.s", "D,S,T", 0x4680001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.af.d", "D,S,T", 0x46a00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.un.d", "D,S,T", 0x46a00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.eq.d", "D,S,T", 0x46a00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ueq.d", "D,S,T", 0x46a00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.lt.d", "D,S,T", 0x46a00004, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ult.d", "D,S,T", 0x46a00005, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.le.d", "D,S,T", 0x46a00006, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ule.d", "D,S,T", 0x46a00007, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.saf.d", "D,S,T", 0x46a00008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sun.d", "D,S,T", 0x46a00009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.seq.d", "D,S,T", 0x46a0000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sueq.d", "D,S,T", 0x46a0000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.slt.d", "D,S,T", 0x46a0000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sult.d", "D,S,T", 0x46a0000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sle.d", "D,S,T", 0x46a0000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sule.d", "D,S,T", 0x46a0000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.or.d", "D,S,T", 0x46a00011, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.une.d", "D,S,T", 0x46a00012, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ne.d", "D,S,T", 0x46a00013, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sor.d", "D,S,T", 0x46a00019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sune.d", "D,S,T", 0x46a0001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sne.d", "D,S,T", 0x46a0001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4|I32|G3 },
|
||||
{"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t, 0, I4|I33 },
|
||||
{"nop", "", 0x00000000, 0xffffffff, 0, INSN2_ALIAS, I1 }, /* sll */
|
||||
|
|
|
@ -304,6 +304,33 @@ FOP_PROTO(le)
|
|||
FOP_PROTO(ngt)
|
||||
#undef FOP_PROTO
|
||||
|
||||
#define FOP_PROTO(op) \
|
||||
DEF_HELPER_3(r6_cmp_d_ ## op, i64, env, i64, i64) \
|
||||
DEF_HELPER_3(r6_cmp_s_ ## op, i32, env, i32, i32)
|
||||
FOP_PROTO(af)
|
||||
FOP_PROTO(un)
|
||||
FOP_PROTO(eq)
|
||||
FOP_PROTO(ueq)
|
||||
FOP_PROTO(lt)
|
||||
FOP_PROTO(ult)
|
||||
FOP_PROTO(le)
|
||||
FOP_PROTO(ule)
|
||||
FOP_PROTO(saf)
|
||||
FOP_PROTO(sun)
|
||||
FOP_PROTO(seq)
|
||||
FOP_PROTO(sueq)
|
||||
FOP_PROTO(slt)
|
||||
FOP_PROTO(sult)
|
||||
FOP_PROTO(sle)
|
||||
FOP_PROTO(sule)
|
||||
FOP_PROTO(or)
|
||||
FOP_PROTO(une)
|
||||
FOP_PROTO(ne)
|
||||
FOP_PROTO(sor)
|
||||
FOP_PROTO(sune)
|
||||
FOP_PROTO(sne)
|
||||
#undef FOP_PROTO
|
||||
|
||||
/* Special functions */
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
DEF_HELPER_1(tlbwi, void, env)
|
||||
|
|
|
@ -3388,3 +3388,114 @@ FOP_COND_PS(le, float32_le(fst0, fst1, &env->active_fpu.fp_status),
|
|||
float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
|
||||
FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status),
|
||||
float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
|
||||
|
||||
/* R6 compare operations */
|
||||
#define FOP_CONDN_D(op, cond) \
|
||||
uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState * env, uint64_t fdt0, \
|
||||
uint64_t fdt1) \
|
||||
{ \
|
||||
uint64_t c; \
|
||||
c = cond; \
|
||||
update_fcr31(env, GETPC()); \
|
||||
if (c) { \
|
||||
return -1; \
|
||||
} else { \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float64_unordered_quiet() is still called. */
|
||||
FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float64_unordered() is still called. */
|
||||
FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
|
||||
#define FOP_CONDN_S(op, cond) \
|
||||
uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState * env, uint32_t fst0, \
|
||||
uint32_t fst1) \
|
||||
{ \
|
||||
uint64_t c; \
|
||||
c = cond; \
|
||||
update_fcr31(env, GETPC()); \
|
||||
if (c) { \
|
||||
return -1; \
|
||||
} else { \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float32_unordered_quiet() is still called. */
|
||||
FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float32_unordered() is still called. */
|
||||
FOP_CONDN_S(saf, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(seq, (float32_eq(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_eq(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(slt, (float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sle, (float32_le(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sor, (float32_le(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sne, (float32_lt(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
|
|
|
@ -1622,6 +1622,98 @@ FOP_CONDS(abs, 1, s, FMT_S, 32)
|
|||
FOP_CONDS(, 0, ps, FMT_PS, 64)
|
||||
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
|
||||
#undef FOP_CONDS
|
||||
|
||||
#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
|
||||
static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
|
||||
int ft, int fs, int fd) \
|
||||
{ \
|
||||
TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
|
||||
TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
|
||||
switch (ifmt) { \
|
||||
case FMT_D: \
|
||||
check_cp1_registers(ctx, fs | ft | fd); \
|
||||
break; \
|
||||
} \
|
||||
gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
|
||||
gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
|
||||
switch (n) { \
|
||||
case 0: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 1: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 2: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 3: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 4: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 5: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 6: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 7: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 8: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 9: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 10: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 11: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 12: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 13: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 14: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 15: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 17: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 18: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 19: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 25: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 26: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
case 27: \
|
||||
gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
|
||||
break; \
|
||||
default: \
|
||||
abort(); \
|
||||
} \
|
||||
STORE; \
|
||||
tcg_temp_free_i ## bits (fp0); \
|
||||
tcg_temp_free_i ## bits (fp1); \
|
||||
}
|
||||
|
||||
FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
|
||||
FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
|
||||
#undef FOP_CONDNS
|
||||
#undef gen_ldcmp_fpr32
|
||||
#undef gen_ldcmp_fpr64
|
||||
|
||||
|
@ -7792,6 +7884,53 @@ enum fopcode {
|
|||
OPC_CMP_NGT_PS = FOP (63, FMT_PS),
|
||||
};
|
||||
|
||||
enum r6_f_cmp_op {
|
||||
R6_OPC_CMP_AF_S = FOP(0, FMT_W),
|
||||
R6_OPC_CMP_UN_S = FOP(1, FMT_W),
|
||||
R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
|
||||
R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
|
||||
R6_OPC_CMP_LT_S = FOP(4, FMT_W),
|
||||
R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
|
||||
R6_OPC_CMP_LE_S = FOP(6, FMT_W),
|
||||
R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
|
||||
R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
|
||||
R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
|
||||
R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
|
||||
R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
|
||||
R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
|
||||
R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
|
||||
R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
|
||||
R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
|
||||
R6_OPC_CMP_OR_S = FOP(17, FMT_W),
|
||||
R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
|
||||
R6_OPC_CMP_NE_S = FOP(19, FMT_W),
|
||||
R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
|
||||
R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
|
||||
R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
|
||||
|
||||
R6_OPC_CMP_AF_D = FOP(0, FMT_L),
|
||||
R6_OPC_CMP_UN_D = FOP(1, FMT_L),
|
||||
R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
|
||||
R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
|
||||
R6_OPC_CMP_LT_D = FOP(4, FMT_L),
|
||||
R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
|
||||
R6_OPC_CMP_LE_D = FOP(6, FMT_L),
|
||||
R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
|
||||
R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
|
||||
R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
|
||||
R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
|
||||
R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
|
||||
R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
|
||||
R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
|
||||
R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
|
||||
R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
|
||||
R6_OPC_CMP_OR_D = FOP(17, FMT_L),
|
||||
R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
|
||||
R6_OPC_CMP_NE_D = FOP(19, FMT_L),
|
||||
R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
|
||||
R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
|
||||
R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
|
||||
};
|
||||
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
|
||||
{
|
||||
const char *opn = "cp1 move";
|
||||
|
@ -17069,11 +17208,74 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
|
|||
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
||||
case OPC_S_FMT:
|
||||
case OPC_D_FMT:
|
||||
case OPC_W_FMT:
|
||||
case OPC_L_FMT:
|
||||
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
|
||||
(imm >> 8) & 0x7);
|
||||
break;
|
||||
case OPC_W_FMT:
|
||||
case OPC_L_FMT:
|
||||
{
|
||||
int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
|
||||
if (ctx->insn_flags & ISA_MIPS32R6) {
|
||||
switch (r6_op) {
|
||||
case R6_OPC_CMP_AF_S:
|
||||
case R6_OPC_CMP_UN_S:
|
||||
case R6_OPC_CMP_EQ_S:
|
||||
case R6_OPC_CMP_UEQ_S:
|
||||
case R6_OPC_CMP_LT_S:
|
||||
case R6_OPC_CMP_ULT_S:
|
||||
case R6_OPC_CMP_LE_S:
|
||||
case R6_OPC_CMP_ULE_S:
|
||||
case R6_OPC_CMP_SAF_S:
|
||||
case R6_OPC_CMP_SUN_S:
|
||||
case R6_OPC_CMP_SEQ_S:
|
||||
case R6_OPC_CMP_SEUQ_S:
|
||||
case R6_OPC_CMP_SLT_S:
|
||||
case R6_OPC_CMP_SULT_S:
|
||||
case R6_OPC_CMP_SLE_S:
|
||||
case R6_OPC_CMP_SULE_S:
|
||||
case R6_OPC_CMP_OR_S:
|
||||
case R6_OPC_CMP_UNE_S:
|
||||
case R6_OPC_CMP_NE_S:
|
||||
case R6_OPC_CMP_SOR_S:
|
||||
case R6_OPC_CMP_SUNE_S:
|
||||
case R6_OPC_CMP_SNE_S:
|
||||
gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
|
||||
break;
|
||||
case R6_OPC_CMP_AF_D:
|
||||
case R6_OPC_CMP_UN_D:
|
||||
case R6_OPC_CMP_EQ_D:
|
||||
case R6_OPC_CMP_UEQ_D:
|
||||
case R6_OPC_CMP_LT_D:
|
||||
case R6_OPC_CMP_ULT_D:
|
||||
case R6_OPC_CMP_LE_D:
|
||||
case R6_OPC_CMP_ULE_D:
|
||||
case R6_OPC_CMP_SAF_D:
|
||||
case R6_OPC_CMP_SUN_D:
|
||||
case R6_OPC_CMP_SEQ_D:
|
||||
case R6_OPC_CMP_SEUQ_D:
|
||||
case R6_OPC_CMP_SLT_D:
|
||||
case R6_OPC_CMP_SULT_D:
|
||||
case R6_OPC_CMP_SLE_D:
|
||||
case R6_OPC_CMP_SULE_D:
|
||||
case R6_OPC_CMP_OR_D:
|
||||
case R6_OPC_CMP_UNE_D:
|
||||
case R6_OPC_CMP_NE_D:
|
||||
case R6_OPC_CMP_SOR_D:
|
||||
case R6_OPC_CMP_SUNE_D:
|
||||
case R6_OPC_CMP_SNE_D:
|
||||
gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
|
||||
break;
|
||||
default:
|
||||
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
|
||||
(imm >> 8) & 0x7);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
|
||||
(imm >> 8) & 0x7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MIPS_INVAL("cp1");
|
||||
generate_exception (ctx, EXCP_RI);
|
||||
|
|
Loading…
Reference in New Issue