Commit 5a1e8ffbe746b2ba4fb8dbdebf3f99d2403fb53e

Authored by ths
1 parent 287c4b84

Implemented cabs FP instructions, and improve exception handling for

trunc/floor/ceil/round.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2804 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/op.c
@@ -1965,6 +1965,9 @@ FLOAT_OP(roundl, d) @@ -1965,6 +1965,9 @@ FLOAT_OP(roundl, d)
1965 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); 1965 set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1966 DT2 = float64_round_to_int(FDT0, &env->fp_status); 1966 DT2 = float64_round_to_int(FDT0, &env->fp_status);
1967 RESTORE_ROUNDING_MODE; 1967 RESTORE_ROUNDING_MODE;
  1968 + update_fcr31();
  1969 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  1970 + DT2 = 0x7fffffffffffffffULL;
1968 DEBUG_FPU_STATE(); 1971 DEBUG_FPU_STATE();
1969 RETURN(); 1972 RETURN();
1970 } 1973 }
@@ -1973,6 +1976,9 @@ FLOAT_OP(roundl, s) @@ -1973,6 +1976,9 @@ FLOAT_OP(roundl, s)
1973 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); 1976 set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1974 DT2 = float32_round_to_int(FST0, &env->fp_status); 1977 DT2 = float32_round_to_int(FST0, &env->fp_status);
1975 RESTORE_ROUNDING_MODE; 1978 RESTORE_ROUNDING_MODE;
  1979 + update_fcr31();
  1980 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  1981 + DT2 = 0x7fffffffffffffffULL;
1976 DEBUG_FPU_STATE(); 1982 DEBUG_FPU_STATE();
1977 RETURN(); 1983 RETURN();
1978 } 1984 }
@@ -1981,6 +1987,9 @@ FLOAT_OP(roundw, d) @@ -1981,6 +1987,9 @@ FLOAT_OP(roundw, d)
1981 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); 1987 set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1982 WT2 = float64_round_to_int(FDT0, &env->fp_status); 1988 WT2 = float64_round_to_int(FDT0, &env->fp_status);
1983 RESTORE_ROUNDING_MODE; 1989 RESTORE_ROUNDING_MODE;
  1990 + update_fcr31();
  1991 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  1992 + WT2 = 0x7fffffff;
1984 DEBUG_FPU_STATE(); 1993 DEBUG_FPU_STATE();
1985 RETURN(); 1994 RETURN();
1986 } 1995 }
@@ -1989,6 +1998,9 @@ FLOAT_OP(roundw, s) @@ -1989,6 +1998,9 @@ FLOAT_OP(roundw, s)
1989 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); 1998 set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1990 WT2 = float32_round_to_int(FST0, &env->fp_status); 1999 WT2 = float32_round_to_int(FST0, &env->fp_status);
1991 RESTORE_ROUNDING_MODE; 2000 RESTORE_ROUNDING_MODE;
  2001 + update_fcr31();
  2002 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2003 + WT2 = 0x7fffffff;
1992 DEBUG_FPU_STATE(); 2004 DEBUG_FPU_STATE();
1993 RETURN(); 2005 RETURN();
1994 } 2006 }
@@ -1996,24 +2008,36 @@ FLOAT_OP(roundw, s) @@ -1996,24 +2008,36 @@ FLOAT_OP(roundw, s)
1996 FLOAT_OP(truncl, d) 2008 FLOAT_OP(truncl, d)
1997 { 2009 {
1998 DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status); 2010 DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
  2011 + update_fcr31();
  2012 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2013 + DT2 = 0x7fffffffffffffffULL;
1999 DEBUG_FPU_STATE(); 2014 DEBUG_FPU_STATE();
2000 RETURN(); 2015 RETURN();
2001 } 2016 }
2002 FLOAT_OP(truncl, s) 2017 FLOAT_OP(truncl, s)
2003 { 2018 {
2004 DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status); 2019 DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
  2020 + update_fcr31();
  2021 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2022 + DT2 = 0x7fffffffffffffffULL;
2005 DEBUG_FPU_STATE(); 2023 DEBUG_FPU_STATE();
2006 RETURN(); 2024 RETURN();
2007 } 2025 }
2008 FLOAT_OP(truncw, d) 2026 FLOAT_OP(truncw, d)
2009 { 2027 {
2010 WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status); 2028 WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
  2029 + update_fcr31();
  2030 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2031 + WT2 = 0x7fffffff;
2011 DEBUG_FPU_STATE(); 2032 DEBUG_FPU_STATE();
2012 RETURN(); 2033 RETURN();
2013 } 2034 }
2014 FLOAT_OP(truncw, s) 2035 FLOAT_OP(truncw, s)
2015 { 2036 {
2016 WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status); 2037 WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
  2038 + update_fcr31();
  2039 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2040 + WT2 = 0x7fffffff;
2017 DEBUG_FPU_STATE(); 2041 DEBUG_FPU_STATE();
2018 RETURN(); 2042 RETURN();
2019 } 2043 }
@@ -2023,6 +2047,9 @@ FLOAT_OP(ceill, d) @@ -2023,6 +2047,9 @@ FLOAT_OP(ceill, d)
2023 set_float_rounding_mode(float_round_up, &env->fp_status); 2047 set_float_rounding_mode(float_round_up, &env->fp_status);
2024 DT2 = float64_round_to_int(FDT0, &env->fp_status); 2048 DT2 = float64_round_to_int(FDT0, &env->fp_status);
2025 RESTORE_ROUNDING_MODE; 2049 RESTORE_ROUNDING_MODE;
  2050 + update_fcr31();
  2051 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2052 + DT2 = 0x7fffffffffffffffULL;
2026 DEBUG_FPU_STATE(); 2053 DEBUG_FPU_STATE();
2027 RETURN(); 2054 RETURN();
2028 } 2055 }
@@ -2031,6 +2058,9 @@ FLOAT_OP(ceill, s) @@ -2031,6 +2058,9 @@ FLOAT_OP(ceill, s)
2031 set_float_rounding_mode(float_round_up, &env->fp_status); 2058 set_float_rounding_mode(float_round_up, &env->fp_status);
2032 DT2 = float32_round_to_int(FST0, &env->fp_status); 2059 DT2 = float32_round_to_int(FST0, &env->fp_status);
2033 RESTORE_ROUNDING_MODE; 2060 RESTORE_ROUNDING_MODE;
  2061 + update_fcr31();
  2062 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2063 + DT2 = 0x7fffffffffffffffULL;
2034 DEBUG_FPU_STATE(); 2064 DEBUG_FPU_STATE();
2035 RETURN(); 2065 RETURN();
2036 } 2066 }
@@ -2039,6 +2069,9 @@ FLOAT_OP(ceilw, d) @@ -2039,6 +2069,9 @@ FLOAT_OP(ceilw, d)
2039 set_float_rounding_mode(float_round_up, &env->fp_status); 2069 set_float_rounding_mode(float_round_up, &env->fp_status);
2040 WT2 = float64_round_to_int(FDT0, &env->fp_status); 2070 WT2 = float64_round_to_int(FDT0, &env->fp_status);
2041 RESTORE_ROUNDING_MODE; 2071 RESTORE_ROUNDING_MODE;
  2072 + update_fcr31();
  2073 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2074 + WT2 = 0x7fffffff;
2042 DEBUG_FPU_STATE(); 2075 DEBUG_FPU_STATE();
2043 RETURN(); 2076 RETURN();
2044 } 2077 }
@@ -2047,6 +2080,9 @@ FLOAT_OP(ceilw, s) @@ -2047,6 +2080,9 @@ FLOAT_OP(ceilw, s)
2047 set_float_rounding_mode(float_round_up, &env->fp_status); 2080 set_float_rounding_mode(float_round_up, &env->fp_status);
2048 WT2 = float32_round_to_int(FST0, &env->fp_status); 2081 WT2 = float32_round_to_int(FST0, &env->fp_status);
2049 RESTORE_ROUNDING_MODE; 2082 RESTORE_ROUNDING_MODE;
  2083 + update_fcr31();
  2084 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2085 + WT2 = 0x7fffffff;
2050 DEBUG_FPU_STATE(); 2086 DEBUG_FPU_STATE();
2051 RETURN(); 2087 RETURN();
2052 } 2088 }
@@ -2056,6 +2092,9 @@ FLOAT_OP(floorl, d) @@ -2056,6 +2092,9 @@ FLOAT_OP(floorl, d)
2056 set_float_rounding_mode(float_round_down, &env->fp_status); 2092 set_float_rounding_mode(float_round_down, &env->fp_status);
2057 DT2 = float64_round_to_int(FDT0, &env->fp_status); 2093 DT2 = float64_round_to_int(FDT0, &env->fp_status);
2058 RESTORE_ROUNDING_MODE; 2094 RESTORE_ROUNDING_MODE;
  2095 + update_fcr31();
  2096 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2097 + DT2 = 0x7fffffffffffffffULL;
2059 DEBUG_FPU_STATE(); 2098 DEBUG_FPU_STATE();
2060 RETURN(); 2099 RETURN();
2061 } 2100 }
@@ -2064,6 +2103,9 @@ FLOAT_OP(floorl, s) @@ -2064,6 +2103,9 @@ FLOAT_OP(floorl, s)
2064 set_float_rounding_mode(float_round_down, &env->fp_status); 2103 set_float_rounding_mode(float_round_down, &env->fp_status);
2065 DT2 = float32_round_to_int(FST0, &env->fp_status); 2104 DT2 = float32_round_to_int(FST0, &env->fp_status);
2066 RESTORE_ROUNDING_MODE; 2105 RESTORE_ROUNDING_MODE;
  2106 + update_fcr31();
  2107 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2108 + DT2 = 0x7fffffffffffffffULL;
2067 DEBUG_FPU_STATE(); 2109 DEBUG_FPU_STATE();
2068 RETURN(); 2110 RETURN();
2069 } 2111 }
@@ -2072,6 +2114,9 @@ FLOAT_OP(floorw, d) @@ -2072,6 +2114,9 @@ FLOAT_OP(floorw, d)
2072 set_float_rounding_mode(float_round_down, &env->fp_status); 2114 set_float_rounding_mode(float_round_down, &env->fp_status);
2073 WT2 = float64_round_to_int(FDT0, &env->fp_status); 2115 WT2 = float64_round_to_int(FDT0, &env->fp_status);
2074 RESTORE_ROUNDING_MODE; 2116 RESTORE_ROUNDING_MODE;
  2117 + update_fcr31();
  2118 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2119 + WT2 = 0x7fffffff;
2075 DEBUG_FPU_STATE(); 2120 DEBUG_FPU_STATE();
2076 RETURN(); 2121 RETURN();
2077 } 2122 }
@@ -2080,6 +2125,9 @@ FLOAT_OP(floorw, s) @@ -2080,6 +2125,9 @@ FLOAT_OP(floorw, s)
2080 set_float_rounding_mode(float_round_down, &env->fp_status); 2125 set_float_rounding_mode(float_round_down, &env->fp_status);
2081 WT2 = float32_round_to_int(FST0, &env->fp_status); 2126 WT2 = float32_round_to_int(FST0, &env->fp_status);
2082 RESTORE_ROUNDING_MODE; 2127 RESTORE_ROUNDING_MODE;
  2128 + update_fcr31();
  2129 + if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
  2130 + WT2 = 0x7fffffff;
2083 DEBUG_FPU_STATE(); 2131 DEBUG_FPU_STATE();
2084 RETURN(); 2132 RETURN();
2085 } 2133 }
@@ -2396,6 +2444,20 @@ void op_cmp_d_ ## op (void) \ @@ -2396,6 +2444,20 @@ void op_cmp_d_ ## op (void) \
2396 CLEAR_FP_COND(PARAM1, env); \ 2444 CLEAR_FP_COND(PARAM1, env); \
2397 DEBUG_FPU_STATE(); \ 2445 DEBUG_FPU_STATE(); \
2398 RETURN(); \ 2446 RETURN(); \
  2447 +} \
  2448 +void op_cmpabs_d_ ## op (void) \
  2449 +{ \
  2450 + int c; \
  2451 + FDT0 &= ~(1ULL << 63); \
  2452 + FDT1 &= ~(1ULL << 63); \
  2453 + c = cond; \
  2454 + update_fcr31(); \
  2455 + if (c) \
  2456 + SET_FP_COND(PARAM1, env); \
  2457 + else \
  2458 + CLEAR_FP_COND(PARAM1, env); \
  2459 + DEBUG_FPU_STATE(); \
  2460 + RETURN(); \
2399 } 2461 }
2400 2462
2401 int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM) 2463 int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
@@ -2444,6 +2506,20 @@ void op_cmp_s_ ## op (void) \ @@ -2444,6 +2506,20 @@ void op_cmp_s_ ## op (void) \
2444 CLEAR_FP_COND(PARAM1, env); \ 2506 CLEAR_FP_COND(PARAM1, env); \
2445 DEBUG_FPU_STATE(); \ 2507 DEBUG_FPU_STATE(); \
2446 RETURN(); \ 2508 RETURN(); \
  2509 +} \
  2510 +void op_cmpabs_s_ ## op (void) \
  2511 +{ \
  2512 + int c; \
  2513 + FST0 &= ~(1 << 31); \
  2514 + FST1 &= ~(1 << 31); \
  2515 + c = cond; \
  2516 + update_fcr31(); \
  2517 + if (c) \
  2518 + SET_FP_COND(PARAM1, env); \
  2519 + else \
  2520 + CLEAR_FP_COND(PARAM1, env); \
  2521 + DEBUG_FPU_STATE(); \
  2522 + RETURN(); \
2447 } 2523 }
2448 2524
2449 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM) 2525 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
@@ -2498,6 +2574,27 @@ void op_cmp_ps_ ## op (void) \ @@ -2498,6 +2574,27 @@ void op_cmp_ps_ ## op (void) \
2498 CLEAR_FP_COND(PARAM1 + 1, env); \ 2574 CLEAR_FP_COND(PARAM1 + 1, env); \
2499 DEBUG_FPU_STATE(); \ 2575 DEBUG_FPU_STATE(); \
2500 RETURN(); \ 2576 RETURN(); \
  2577 +} \
  2578 +void op_cmpabs_ps_ ## op (void) \
  2579 +{ \
  2580 + int cl, ch; \
  2581 + FST0 &= ~(1 << 31); \
  2582 + FSTH0 &= ~(1 << 31); \
  2583 + FST1 &= ~(1 << 31); \
  2584 + FSTH1 &= ~(1 << 31); \
  2585 + cl = condl; \
  2586 + ch = condh; \
  2587 + update_fcr31(); \
  2588 + if (cl) \
  2589 + SET_FP_COND(PARAM1, env); \
  2590 + else \
  2591 + CLEAR_FP_COND(PARAM1, env); \
  2592 + if (ch) \
  2593 + SET_FP_COND(PARAM1 + 1, env); \
  2594 + else \
  2595 + CLEAR_FP_COND(PARAM1 + 1, env); \
  2596 + DEBUG_FPU_STATE(); \
  2597 + RETURN(); \
2501 } 2598 }
2502 2599
2503 /* NOTE: the comma operator will make "cond" to eval to false, 2600 /* NOTE: the comma operator will make "cond" to eval to false,
target-mips/translate.c
@@ -490,33 +490,36 @@ FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr); @@ -490,33 +490,36 @@ FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
490 FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr); 490 FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr);
491 FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr); 491 FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
492 492
493 -#define FOP_CONDS(fmt) \  
494 -static GenOpFunc1 * cond_ ## fmt ## _table[16] = { \  
495 - gen_op_cmp_ ## fmt ## _f, \  
496 - gen_op_cmp_ ## fmt ## _un, \  
497 - gen_op_cmp_ ## fmt ## _eq, \  
498 - gen_op_cmp_ ## fmt ## _ueq, \  
499 - gen_op_cmp_ ## fmt ## _olt, \  
500 - gen_op_cmp_ ## fmt ## _ult, \  
501 - gen_op_cmp_ ## fmt ## _ole, \  
502 - gen_op_cmp_ ## fmt ## _ule, \  
503 - gen_op_cmp_ ## fmt ## _sf, \  
504 - gen_op_cmp_ ## fmt ## _ngle, \  
505 - gen_op_cmp_ ## fmt ## _seq, \  
506 - gen_op_cmp_ ## fmt ## _ngl, \  
507 - gen_op_cmp_ ## fmt ## _lt, \  
508 - gen_op_cmp_ ## fmt ## _nge, \  
509 - gen_op_cmp_ ## fmt ## _le, \  
510 - gen_op_cmp_ ## fmt ## _ngt, \ 493 +#define FOP_CONDS(type, fmt) \
  494 +static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = { \
  495 + gen_op_cmp ## type ## _ ## fmt ## _f, \
  496 + gen_op_cmp ## type ## _ ## fmt ## _un, \
  497 + gen_op_cmp ## type ## _ ## fmt ## _eq, \
  498 + gen_op_cmp ## type ## _ ## fmt ## _ueq, \
  499 + gen_op_cmp ## type ## _ ## fmt ## _olt, \
  500 + gen_op_cmp ## type ## _ ## fmt ## _ult, \
  501 + gen_op_cmp ## type ## _ ## fmt ## _ole, \
  502 + gen_op_cmp ## type ## _ ## fmt ## _ule, \
  503 + gen_op_cmp ## type ## _ ## fmt ## _sf, \
  504 + gen_op_cmp ## type ## _ ## fmt ## _ngle, \
  505 + gen_op_cmp ## type ## _ ## fmt ## _seq, \
  506 + gen_op_cmp ## type ## _ ## fmt ## _ngl, \
  507 + gen_op_cmp ## type ## _ ## fmt ## _lt, \
  508 + gen_op_cmp ## type ## _ ## fmt ## _nge, \
  509 + gen_op_cmp ## type ## _ ## fmt ## _le, \
  510 + gen_op_cmp ## type ## _ ## fmt ## _ngt, \
511 }; \ 511 }; \
512 -static inline void gen_cmp_ ## fmt(int n, long cc) \ 512 +static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \
513 { \ 513 { \
514 - cond_ ## fmt ## _table[n](cc); \ 514 + cond ## type ## _ ## fmt ## _table[n](cc); \
515 } 515 }
516 516
517 -FOP_CONDS(d)  
518 -FOP_CONDS(s)  
519 -FOP_CONDS(ps) 517 +FOP_CONDS(, d)
  518 +FOP_CONDS(abs, d)
  519 +FOP_CONDS(, s)
  520 +FOP_CONDS(abs, s)
  521 +FOP_CONDS(, ps)
  522 +FOP_CONDS(abs, ps)
520 523
521 typedef struct DisasContext { 524 typedef struct DisasContext {
522 struct TranslationBlock *tb; 525 struct TranslationBlock *tb;
@@ -4453,7 +4456,25 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4453,7 +4456,25 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4453 "c.le", 4456 "c.le",
4454 "c.ngt", 4457 "c.ngt",
4455 }; 4458 };
4456 - int binary = 0; 4459 + const char *condnames_abs[] = {
  4460 + "cabs.f",
  4461 + "cabs.un",
  4462 + "cabs.eq",
  4463 + "cabs.ueq",
  4464 + "cabs.olt",
  4465 + "cabs.ult",
  4466 + "cabs.ole",
  4467 + "cabs.ule",
  4468 + "cabs.sf",
  4469 + "cabs.ngle",
  4470 + "cabs.seq",
  4471 + "cabs.ngl",
  4472 + "cabs.lt",
  4473 + "cabs.nge",
  4474 + "cabs.le",
  4475 + "cabs.ngt",
  4476 + };
  4477 + enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4457 uint32_t func = ctx->opcode & 0x3f; 4478 uint32_t func = ctx->opcode & 0x3f;
4458 4479
4459 switch (ctx->opcode & FOP(0x3f, 0x1f)) { 4480 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
@@ -4463,7 +4484,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4463,7 +4484,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4463 gen_op_float_add_s(); 4484 gen_op_float_add_s();
4464 GEN_STORE_FTN_FREG(fd, WT2); 4485 GEN_STORE_FTN_FREG(fd, WT2);
4465 opn = "add.s"; 4486 opn = "add.s";
4466 - binary = 1; 4487 + optype = BINOP;
4467 break; 4488 break;
4468 case FOP(1, 16): 4489 case FOP(1, 16):
4469 GEN_LOAD_FREG_FTN(WT0, fs); 4490 GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4471,7 +4492,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4471,7 +4492,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4471 gen_op_float_sub_s(); 4492 gen_op_float_sub_s();
4472 GEN_STORE_FTN_FREG(fd, WT2); 4493 GEN_STORE_FTN_FREG(fd, WT2);
4473 opn = "sub.s"; 4494 opn = "sub.s";
4474 - binary = 1; 4495 + optype = BINOP;
4475 break; 4496 break;
4476 case FOP(2, 16): 4497 case FOP(2, 16):
4477 GEN_LOAD_FREG_FTN(WT0, fs); 4498 GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4479,7 +4500,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4479,7 +4500,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4479 gen_op_float_mul_s(); 4500 gen_op_float_mul_s();
4480 GEN_STORE_FTN_FREG(fd, WT2); 4501 GEN_STORE_FTN_FREG(fd, WT2);
4481 opn = "mul.s"; 4502 opn = "mul.s";
4482 - binary = 1; 4503 + optype = BINOP;
4483 break; 4504 break;
4484 case FOP(3, 16): 4505 case FOP(3, 16):
4485 GEN_LOAD_FREG_FTN(WT0, fs); 4506 GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4487,7 +4508,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4487,7 +4508,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4487 gen_op_float_div_s(); 4508 gen_op_float_div_s();
4488 GEN_STORE_FTN_FREG(fd, WT2); 4509 GEN_STORE_FTN_FREG(fd, WT2);
4489 opn = "div.s"; 4510 opn = "div.s";
4490 - binary = 1; 4511 + optype = BINOP;
4491 break; 4512 break;
4492 case FOP(4, 16): 4513 case FOP(4, 16):
4493 GEN_LOAD_FREG_FTN(WT0, fs); 4514 GEN_LOAD_FREG_FTN(WT0, fs);
@@ -4635,8 +4656,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4635,8 +4656,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4635 case FOP(63, 16): 4656 case FOP(63, 16):
4636 GEN_LOAD_FREG_FTN(WT0, fs); 4657 GEN_LOAD_FREG_FTN(WT0, fs);
4637 GEN_LOAD_FREG_FTN(WT1, ft); 4658 GEN_LOAD_FREG_FTN(WT1, ft);
4638 - gen_cmp_s(func-48, cc);  
4639 - opn = condnames[func-48]; 4659 + if (ctx->opcode & (1 << 6)) {
  4660 + gen_cmpabs_s(func-48, cc);
  4661 + opn = condnames_abs[func-48];
  4662 + } else {
  4663 + gen_cmp_s(func-48, cc);
  4664 + opn = condnames[func-48];
  4665 + }
4640 break; 4666 break;
4641 case FOP(0, 17): 4667 case FOP(0, 17):
4642 CHECK_FR(ctx, fs | ft | fd); 4668 CHECK_FR(ctx, fs | ft | fd);
@@ -4645,7 +4671,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4645,7 +4671,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4645 gen_op_float_add_d(); 4671 gen_op_float_add_d();
4646 GEN_STORE_FTN_FREG(fd, DT2); 4672 GEN_STORE_FTN_FREG(fd, DT2);
4647 opn = "add.d"; 4673 opn = "add.d";
4648 - binary = 1; 4674 + optype = BINOP;
4649 break; 4675 break;
4650 case FOP(1, 17): 4676 case FOP(1, 17):
4651 CHECK_FR(ctx, fs | ft | fd); 4677 CHECK_FR(ctx, fs | ft | fd);
@@ -4654,7 +4680,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4654,7 +4680,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4654 gen_op_float_sub_d(); 4680 gen_op_float_sub_d();
4655 GEN_STORE_FTN_FREG(fd, DT2); 4681 GEN_STORE_FTN_FREG(fd, DT2);
4656 opn = "sub.d"; 4682 opn = "sub.d";
4657 - binary = 1; 4683 + optype = BINOP;
4658 break; 4684 break;
4659 case FOP(2, 17): 4685 case FOP(2, 17):
4660 CHECK_FR(ctx, fs | ft | fd); 4686 CHECK_FR(ctx, fs | ft | fd);
@@ -4663,7 +4689,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4663,7 +4689,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4663 gen_op_float_mul_d(); 4689 gen_op_float_mul_d();
4664 GEN_STORE_FTN_FREG(fd, DT2); 4690 GEN_STORE_FTN_FREG(fd, DT2);
4665 opn = "mul.d"; 4691 opn = "mul.d";
4666 - binary = 1; 4692 + optype = BINOP;
4667 break; 4693 break;
4668 case FOP(3, 17): 4694 case FOP(3, 17):
4669 CHECK_FR(ctx, fs | ft | fd); 4695 CHECK_FR(ctx, fs | ft | fd);
@@ -4672,7 +4698,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4672,7 +4698,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4672 gen_op_float_div_d(); 4698 gen_op_float_div_d();
4673 GEN_STORE_FTN_FREG(fd, DT2); 4699 GEN_STORE_FTN_FREG(fd, DT2);
4674 opn = "div.d"; 4700 opn = "div.d";
4675 - binary = 1; 4701 + optype = BINOP;
4676 break; 4702 break;
4677 case FOP(4, 17): 4703 case FOP(4, 17):
4678 CHECK_FR(ctx, fs | fd); 4704 CHECK_FR(ctx, fs | fd);
@@ -4801,8 +4827,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -4801,8 +4827,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4801 CHECK_FR(ctx, fs | ft); 4827 CHECK_FR(ctx, fs | ft);
4802 GEN_LOAD_FREG_FTN(DT0, fs); 4828 GEN_LOAD_FREG_FTN(DT0, fs);
4803 GEN_LOAD_FREG_FTN(DT1, ft); 4829 GEN_LOAD_FREG_FTN(DT1, ft);
4804 - gen_cmp_d(func-48, cc);  
4805 - opn = condnames[func-48]; 4830 + if (ctx->opcode & (1 << 6)) {
  4831 + gen_cmpabs_d(func-48, cc);
  4832 + opn = condnames_abs[func-48];
  4833 + } else {
  4834 + gen_cmp_d(func-48, cc);
  4835 + opn = condnames[func-48];
  4836 + }
4806 break; 4837 break;
4807 case FOP(32, 17): 4838 case FOP(32, 17):
4808 CHECK_FR(ctx, fs); 4839 CHECK_FR(ctx, fs);
@@ -5042,18 +5073,30 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, @@ -5042,18 +5073,30 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5042 GEN_LOAD_FREG_FTN(WTH0, fs); 5073 GEN_LOAD_FREG_FTN(WTH0, fs);
5043 GEN_LOAD_FREG_FTN(WT1, ft); 5074 GEN_LOAD_FREG_FTN(WT1, ft);
5044 GEN_LOAD_FREG_FTN(WTH1, ft); 5075 GEN_LOAD_FREG_FTN(WTH1, ft);
5045 - gen_cmp_ps(func-48, cc);  
5046 - opn = condnames[func-48]; 5076 + if (ctx->opcode & (1 << 6)) {
  5077 + gen_cmpabs_ps(func-48, cc);
  5078 + opn = condnames_abs[func-48];
  5079 + } else {
  5080 + gen_cmp_ps(func-48, cc);
  5081 + opn = condnames[func-48];
  5082 + }
5047 break; 5083 break;
5048 default: 5084 default:
5049 MIPS_INVAL(opn); 5085 MIPS_INVAL(opn);
5050 generate_exception (ctx, EXCP_RI); 5086 generate_exception (ctx, EXCP_RI);
5051 return; 5087 return;
5052 } 5088 }
5053 - if (binary) 5089 + switch (optype) {
  5090 + case BINOP:
5054 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]); 5091 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5055 - else 5092 + break;
  5093 + case CMPOP:
  5094 + MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
  5095 + break;
  5096 + default:
5056 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]); 5097 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
  5098 + break;
  5099 + }
5057 } 5100 }
5058 5101
5059 /* Coprocessor 3 (FPU) */ 5102 /* Coprocessor 3 (FPU) */