@@ -1435,6 +1435,7 @@ typedef struct DisasContext {
bool vp;
bool cmgcr;
bool mrp;
+ bool abs2008;
} DisasContext;
enum {
@@ -8890,7 +8891,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(ctx, fp0, fs);
- gen_helper_float_abs_s(fp0, fp0);
+ if (ctx->abs2008) {
+ tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
+ } else {
+ gen_helper_float_abs_s(fp0, fp0);
+ }
gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0);
}
@@ -8909,7 +8914,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(ctx, fp0, fs);
- gen_helper_float_chs_s(fp0, fp0);
+ if (ctx->abs2008) {
+ tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
+ } else {
+ gen_helper_float_chs_s(fp0, fp0);
+ }
gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0);
}
@@ -9380,7 +9389,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i64 fp0 = tcg_temp_new_i64();
gen_load_fpr64(ctx, fp0, fs);
- gen_helper_float_abs_d(fp0, fp0);
+ if (ctx->abs2008) {
+ tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
+ } else {
+ gen_helper_float_abs_d(fp0, fp0);
+ }
gen_store_fpr64(ctx, fp0, fd);
tcg_temp_free_i64(fp0);
}
@@ -9401,7 +9414,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i64 fp0 = tcg_temp_new_i64();
gen_load_fpr64(ctx, fp0, fs);
- gen_helper_float_chs_d(fp0, fp0);
+ if (ctx->abs2008) {
+ tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
+ } else {
+ gen_helper_float_chs_d(fp0, fp0);
+ }
gen_store_fpr64(ctx, fp0, fd);
tcg_temp_free_i64(fp0);
}
@@ -19786,6 +19803,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
+ ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
restore_cpu_state(env, &ctx);
#ifdef CONFIG_USER_ONLY
ctx.mem_idx = MIPS_HFLAG_UM;