Commit 3a5b360dac4ce1900e1cb19b7ad870086936869c

Authored by ths
1 parent 5f30d62c

Catch more MIPS FPU cornercases, fix addr.ps and mulr.ps instructions.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2841 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/op_helper.c
... ... @@ -975,13 +975,25 @@ FLOAT_OP(name, d) \
975 975 { \
976 976 set_float_exception_flags(0, &env->fp_status); \
977 977 FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \
978   - update_fcr31(); \
  978 + update_fcr31(); \
  979 + if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) \
  980 + FDT2 = 0x7ff7ffffffffffffULL; \
  981 + else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
  982 + if ((env->fcr31 & 0x3) == 0) \
  983 + FDT2 &= 0x8000000000000000ULL; \
  984 + } \
979 985 } \
980 986 FLOAT_OP(name, s) \
981 987 { \
982 988 set_float_exception_flags(0, &env->fp_status); \
983 989 FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
984   - update_fcr31(); \
  990 + update_fcr31(); \
  991 + if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) \
  992 + FST2 = 0x7fbfffff; \
  993 + else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
  994 + if ((env->fcr31 & 0x3) == 0) \
  995 + FST2 &= 0x80000000ULL; \
  996 + } \
985 997 } \
986 998 FLOAT_OP(name, ps) \
987 999 { \
... ... @@ -989,6 +1001,15 @@ FLOAT_OP(name, ps) \
989 1001 FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
990 1002 FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
991 1003 update_fcr31(); \
  1004 + if (GET_FP_CAUSE(env->fcr31) & FP_INVALID) { \
  1005 + FST2 = 0x7fbfffff; \
  1006 + FSTH2 = 0x7fbfffff; \
  1007 + } else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
  1008 + if ((env->fcr31 & 0x3) == 0) { \
  1009 + FST2 &= 0x80000000ULL; \
  1010 + FSTH2 &= 0x80000000ULL; \
  1011 + } \
  1012 + } \
992 1013 }
993 1014 FLOAT_BINOP(add)
994 1015 FLOAT_BINOP(sub)
... ...
target-mips/translate.c
... ... @@ -5074,10 +5074,10 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5074 5074 break;
5075 5075 case FOP(24, 22):
5076 5076 gen_op_cp1_64bitmode();
5077   - GEN_LOAD_FREG_FTN(WT0, fs);
5078   - GEN_LOAD_FREG_FTN(WTH0, fs);
5079   - GEN_LOAD_FREG_FTN(WT1, ft);
5080   - GEN_LOAD_FREG_FTN(WTH1, ft);
  5077 + GEN_LOAD_FREG_FTN(WT0, ft);
  5078 + GEN_LOAD_FREG_FTN(WTH0, ft);
  5079 + GEN_LOAD_FREG_FTN(WT1, fs);
  5080 + GEN_LOAD_FREG_FTN(WTH1, fs);
5081 5081 gen_op_float_addr_ps();
5082 5082 GEN_STORE_FTN_FREG(fd, WT2);
5083 5083 GEN_STORE_FTN_FREG(fd, WTH2);
... ... @@ -5085,10 +5085,10 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
5085 5085 break;
5086 5086 case FOP(26, 22):
5087 5087 gen_op_cp1_64bitmode();
5088   - GEN_LOAD_FREG_FTN(WT0, fs);
5089   - GEN_LOAD_FREG_FTN(WTH0, fs);
5090   - GEN_LOAD_FREG_FTN(WT1, ft);
5091   - GEN_LOAD_FREG_FTN(WTH1, ft);
  5088 + GEN_LOAD_FREG_FTN(WT0, ft);
  5089 + GEN_LOAD_FREG_FTN(WTH0, ft);
  5090 + GEN_LOAD_FREG_FTN(WT1, fs);
  5091 + GEN_LOAD_FREG_FTN(WTH1, fs);
5092 5092 gen_op_float_mulr_ps();
5093 5093 GEN_STORE_FTN_FREG(fd, WT2);
5094 5094 GEN_STORE_FTN_FREG(fd, WTH2);
... ...