Revision 5a1e8ffb

b/target-mips/op.c
1965 1965
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1966 1966
    DT2 = float64_round_to_int(FDT0, &env->fp_status);
1967 1967
    RESTORE_ROUNDING_MODE;
1968
    update_fcr31();
1969
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1970
        DT2 = 0x7fffffffffffffffULL;
1968 1971
    DEBUG_FPU_STATE();
1969 1972
    RETURN();
1970 1973
}
......
1973 1976
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1974 1977
    DT2 = float32_round_to_int(FST0, &env->fp_status);
1975 1978
    RESTORE_ROUNDING_MODE;
1979
    update_fcr31();
1980
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1981
        DT2 = 0x7fffffffffffffffULL;
1976 1982
    DEBUG_FPU_STATE();
1977 1983
    RETURN();
1978 1984
}
......
1981 1987
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1982 1988
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
1983 1989
    RESTORE_ROUNDING_MODE;
1990
    update_fcr31();
1991
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1992
        WT2 = 0x7fffffff;
1984 1993
    DEBUG_FPU_STATE();
1985 1994
    RETURN();
1986 1995
}
......
1989 1998
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1990 1999
    WT2 = float32_round_to_int(FST0, &env->fp_status);
1991 2000
    RESTORE_ROUNDING_MODE;
2001
    update_fcr31();
2002
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2003
        WT2 = 0x7fffffff;
1992 2004
    DEBUG_FPU_STATE();
1993 2005
    RETURN();
1994 2006
}
......
1996 2008
FLOAT_OP(truncl, d)
1997 2009
{
1998 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 2014
    DEBUG_FPU_STATE();
2000 2015
    RETURN();
2001 2016
}
2002 2017
FLOAT_OP(truncl, s)
2003 2018
{
2004 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 2023
    DEBUG_FPU_STATE();
2006 2024
    RETURN();
2007 2025
}
2008 2026
FLOAT_OP(truncw, d)
2009 2027
{
2010 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 2032
    DEBUG_FPU_STATE();
2012 2033
    RETURN();
2013 2034
}
2014 2035
FLOAT_OP(truncw, s)
2015 2036
{
2016 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 2041
    DEBUG_FPU_STATE();
2018 2042
    RETURN();
2019 2043
}
......
2023 2047
    set_float_rounding_mode(float_round_up, &env->fp_status);
2024 2048
    DT2 = float64_round_to_int(FDT0, &env->fp_status);
2025 2049
    RESTORE_ROUNDING_MODE;
2050
    update_fcr31();
2051
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2052
        DT2 = 0x7fffffffffffffffULL;
2026 2053
    DEBUG_FPU_STATE();
2027 2054
    RETURN();
2028 2055
}
......
2031 2058
    set_float_rounding_mode(float_round_up, &env->fp_status);
2032 2059
    DT2 = float32_round_to_int(FST0, &env->fp_status);
2033 2060
    RESTORE_ROUNDING_MODE;
2061
    update_fcr31();
2062
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2063
        DT2 = 0x7fffffffffffffffULL;
2034 2064
    DEBUG_FPU_STATE();
2035 2065
    RETURN();
2036 2066
}
......
2039 2069
    set_float_rounding_mode(float_round_up, &env->fp_status);
2040 2070
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
2041 2071
    RESTORE_ROUNDING_MODE;
2072
    update_fcr31();
2073
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2074
        WT2 = 0x7fffffff;
2042 2075
    DEBUG_FPU_STATE();
2043 2076
    RETURN();
2044 2077
}
......
2047 2080
    set_float_rounding_mode(float_round_up, &env->fp_status);
2048 2081
    WT2 = float32_round_to_int(FST0, &env->fp_status);
2049 2082
    RESTORE_ROUNDING_MODE;
2083
    update_fcr31();
2084
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2085
        WT2 = 0x7fffffff;
2050 2086
    DEBUG_FPU_STATE();
2051 2087
    RETURN();
2052 2088
}
......
2056 2092
    set_float_rounding_mode(float_round_down, &env->fp_status);
2057 2093
    DT2 = float64_round_to_int(FDT0, &env->fp_status);
2058 2094
    RESTORE_ROUNDING_MODE;
2095
    update_fcr31();
2096
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2097
        DT2 = 0x7fffffffffffffffULL;
2059 2098
    DEBUG_FPU_STATE();
2060 2099
    RETURN();
2061 2100
}
......
2064 2103
    set_float_rounding_mode(float_round_down, &env->fp_status);
2065 2104
    DT2 = float32_round_to_int(FST0, &env->fp_status);
2066 2105
    RESTORE_ROUNDING_MODE;
2106
    update_fcr31();
2107
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2108
        DT2 = 0x7fffffffffffffffULL;
2067 2109
    DEBUG_FPU_STATE();
2068 2110
    RETURN();
2069 2111
}
......
2072 2114
    set_float_rounding_mode(float_round_down, &env->fp_status);
2073 2115
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
2074 2116
    RESTORE_ROUNDING_MODE;
2117
    update_fcr31();
2118
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2119
        WT2 = 0x7fffffff;
2075 2120
    DEBUG_FPU_STATE();
2076 2121
    RETURN();
2077 2122
}
......
2080 2125
    set_float_rounding_mode(float_round_down, &env->fp_status);
2081 2126
    WT2 = float32_round_to_int(FST0, &env->fp_status);
2082 2127
    RESTORE_ROUNDING_MODE;
2128
    update_fcr31();
2129
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
2130
        WT2 = 0x7fffffff;
2083 2131
    DEBUG_FPU_STATE();
2084 2132
    RETURN();
2085 2133
}
......
2396 2444
        CLEAR_FP_COND(PARAM1, env);            \
2397 2445
    DEBUG_FPU_STATE();                         \
2398 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 2463
int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
......
2444 2506
        CLEAR_FP_COND(PARAM1, env);            \
2445 2507
    DEBUG_FPU_STATE();                         \
2446 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 2525
flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
......
2498 2574
        CLEAR_FP_COND(PARAM1 + 1, env);        \
2499 2575
    DEBUG_FPU_STATE();                         \
2500 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 2600
/* NOTE: the comma operator will make "cond" to eval to false,
b/target-mips/translate.c
490 490
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
491 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 524
typedef struct DisasContext {
522 525
    struct TranslationBlock *tb;
......
4453 4456
            "c.le",
4454 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 4478
    uint32_t func = ctx->opcode & 0x3f;
4458 4479

  
4459 4480
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
......
4463 4484
        gen_op_float_add_s();
4464 4485
        GEN_STORE_FTN_FREG(fd, WT2);
4465 4486
        opn = "add.s";
4466
        binary = 1;
4487
        optype = BINOP;
4467 4488
        break;
4468 4489
    case FOP(1, 16):
4469 4490
        GEN_LOAD_FREG_FTN(WT0, fs);
......
4471 4492
        gen_op_float_sub_s();
4472 4493
        GEN_STORE_FTN_FREG(fd, WT2);
4473 4494
        opn = "sub.s";
4474
        binary = 1;
4495
        optype = BINOP;
4475 4496
        break;
4476 4497
    case FOP(2, 16):
4477 4498
        GEN_LOAD_FREG_FTN(WT0, fs);
......
4479 4500
        gen_op_float_mul_s();
4480 4501
        GEN_STORE_FTN_FREG(fd, WT2);
4481 4502
        opn = "mul.s";
4482
        binary = 1;
4503
        optype = BINOP;
4483 4504
        break;
4484 4505
    case FOP(3, 16):
4485 4506
        GEN_LOAD_FREG_FTN(WT0, fs);
......
4487 4508
        gen_op_float_div_s();
4488 4509
        GEN_STORE_FTN_FREG(fd, WT2);
4489 4510
        opn = "div.s";
4490
        binary = 1;
4511
        optype = BINOP;
4491 4512
        break;
4492 4513
    case FOP(4, 16):
4493 4514
        GEN_LOAD_FREG_FTN(WT0, fs);
......
4635 4656
    case FOP(63, 16):
4636 4657
        GEN_LOAD_FREG_FTN(WT0, fs);
4637 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 4666
        break;
4641 4667
    case FOP(0, 17):
4642 4668
        CHECK_FR(ctx, fs | ft | fd);
......
4645 4671
        gen_op_float_add_d();
4646 4672
        GEN_STORE_FTN_FREG(fd, DT2);
4647 4673
        opn = "add.d";
4648
        binary = 1;
4674
        optype = BINOP;
4649 4675
        break;
4650 4676
    case FOP(1, 17):
4651 4677
        CHECK_FR(ctx, fs | ft | fd);
......
4654 4680
        gen_op_float_sub_d();
4655 4681
        GEN_STORE_FTN_FREG(fd, DT2);
4656 4682
        opn = "sub.d";
4657
        binary = 1;
4683
        optype = BINOP;
4658 4684
        break;
4659 4685
    case FOP(2, 17):
4660 4686
        CHECK_FR(ctx, fs | ft | fd);
......
4663 4689
        gen_op_float_mul_d();
4664 4690
        GEN_STORE_FTN_FREG(fd, DT2);
4665 4691
        opn = "mul.d";
4666
        binary = 1;
4692
        optype = BINOP;
4667 4693
        break;
4668 4694
    case FOP(3, 17):
4669 4695
        CHECK_FR(ctx, fs | ft | fd);
......
4672 4698
        gen_op_float_div_d();
4673 4699
        GEN_STORE_FTN_FREG(fd, DT2);
4674 4700
        opn = "div.d";
4675
        binary = 1;
4701
        optype = BINOP;
4676 4702
        break;
4677 4703
    case FOP(4, 17):
4678 4704
        CHECK_FR(ctx, fs | fd);
......
4801 4827
        CHECK_FR(ctx, fs | ft);
4802 4828
        GEN_LOAD_FREG_FTN(DT0, fs);
4803 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 4837
        break;
4807 4838
    case FOP(32, 17):
4808 4839
        CHECK_FR(ctx, fs);
......
5042 5073
        GEN_LOAD_FREG_FTN(WTH0, fs);
5043 5074
        GEN_LOAD_FREG_FTN(WT1, ft);
5044 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 5083
        break;
5048 5084
    default:
5049 5085
        MIPS_INVAL(opn);
5050 5086
        generate_exception (ctx, EXCP_RI);
5051 5087
        return;
5052 5088
    }
5053
    if (binary)
5089
    switch (optype) {
5090
    case BINOP:
5054 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 5097
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5098
        break;
5099
    }
5057 5100
}
5058 5101

  
5059 5102
/* Coprocessor 3 (FPU) */

Also available in: Unified diff