Revision 5a5012ec

b/Changelog
4 4
  - ds1225y nvram support (Herve Poussineau)
5 5
  - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
6 6
  - Several Sparc fixes (Aurelien Jarno, Blue Swirl)
7
  - MIPS 64-bit FPU support (Thiemo Seufer)
7 8

  
8 9
version 0.9.0:
9 10

  
b/gdbstub.c
575 575
      {
576 576
        for (i = 0; i < 32; i++)
577 577
          {
578
            *(uint32_t *)ptr = tswapl(FPR_W (env, i));
578
            *(uint32_t *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
579 579
            ptr += 4;
580 580
          }
581 581

  
......
637 637
      {
638 638
        for (i = 0; i < 32; i++)
639 639
          {
640
            FPR_W (env, i) = tswapl(*(uint32_t *)ptr);
640
            env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(uint32_t *)ptr);
641 641
            ptr += 4;
642 642
          }
643 643

  
b/target-mips/TODO
10 10
  when the Qemu FPU emulation is disabled. Also gdb inside the emulated
11 11
  system does not work. Both problems are caused by insufficient
12 12
  handling of self-modifying code.
13
- Floating point exception emulation is incomplete.
13 14

  
14 15
MIPS64
15 16
------
16 17
- No 64bit TLB support
17
- no 64bit wide registers for FPU
18
- 64bit FPU not fully implemented
18 19
- 64bit mul/div handling broken
19 20

  
20 21
"Generic" 4Kc system emulation
b/target-mips/cpu.h
21 21
union fpr_t {
22 22
    float64  fd;   /* ieee double precision */
23 23
    float32  fs[2];/* ieee single precision */
24
    uint64_t d;    /* binary single fixed-point */
24
    uint64_t d;    /* binary double fixed-point */
25 25
    uint32_t w[2]; /* binary single fixed-point */
26 26
};
27 27
/* define FP_ENDIAN_IDX to access the same location
......
64 64
    target_ulong HI, LO;
65 65
    /* Floating point registers */
66 66
    fpr_t fpr[32];
67
#define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2])
68
#define FPR_FD(cpu, n) (FPR(cpu, n)->fd)
69
#define FPR_FS(cpu, n) (FPR(cpu, n)->fs[((n) & 1) ^ FP_ENDIAN_IDX])
70
#define FPR_D(cpu, n)  (FPR(cpu, n)->d)
71
#define FPR_W(cpu, n)  (FPR(cpu, n)->w[((n) & 1) ^ FP_ENDIAN_IDX])
72

  
73 67
#ifndef USE_HOST_FLOAT_REGS
74 68
    fpr_t ft0;
75 69
    fpr_t ft1;
76 70
    fpr_t ft2;
77 71
#endif
78 72
    float_status fp_status;
79
    /* fpu implementation/revision register */
73
    /* fpu implementation/revision register (fir) */
80 74
    uint32_t fcr0;
75
#define FCR0_F64 22
76
#define FCR0_L 21
77
#define FCR0_W 20
78
#define FCR0_3D 19
79
#define FCR0_PS 18
80
#define FCR0_D 17
81
#define FCR0_S 16
82
#define FCR0_PRID 8
83
#define FCR0_REV 0
81 84
    /* fcsr */
82 85
    uint32_t fcr31;
83
#define SET_FP_COND(reg)     do { (reg) |= (1<<23); } while(0)
84
#define CLEAR_FP_COND(reg)   do { (reg) &= ~(1<<23); } while(0)
85
#define IS_FP_COND_SET(reg)  (((reg) & (1<<23)) != 0)
86
#define GET_FP_CAUSE(reg)    (((reg) >> 12) & 0x3f)
87
#define GET_FP_ENABLE(reg)   (((reg) >>  7) & 0x1f)
88
#define GET_FP_FLAGS(reg)    (((reg) >>  2) & 0x1f)
89
#define SET_FP_CAUSE(reg,v)  do { (reg) = ((reg) & ~(0x3f << 12)) | ((v) << 12); } while(0)
90
#define SET_FP_ENABLE(reg,v) do { (reg) = ((reg) & ~(0x1f <<  7)) | ((v) << 7); } while(0)
91
#define SET_FP_FLAGS(reg,v)  do { (reg) = ((reg) & ~(0x1f <<  2)) | ((v) << 2); } while(0)
86
#define SET_FP_COND(num,env)     do { (env->fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23))); } while(0)
87
#define CLEAR_FP_COND(num,env)   do { (env->fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23))); } while(0)
88
#define IS_FP_COND_SET(num,env)  (((env->fcr31) & ((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23)))) != 0)
89
#define GET_FP_CAUSE(reg)        (((reg) >> 12) & 0x3f)
90
#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
91
#define GET_FP_FLAGS(reg)        (((reg) >>  2) & 0x1f)
92
#define SET_FP_CAUSE(reg,v)      do { (reg) = ((reg) & ~(0x3f << 12)) | ((v & 0x3f) << 12); } while(0)
93
#define SET_FP_ENABLE(reg,v)     do { (reg) = ((reg) & ~(0x1f <<  7)) | ((v & 0x1f) << 7); } while(0)
94
#define SET_FP_FLAGS(reg,v)      do { (reg) = ((reg) & ~(0x1f <<  2)) | ((v & 0x1f) << 2); } while(0)
95
#define UPDATE_FP_FLAGS(reg,v)   do { (reg) |= ((v & 0x1f) << 2); } while(0)
92 96
#define FP_INEXACT        1
93 97
#define FP_UNDERFLOW      2
94 98
#define FP_OVERFLOW       4
......
267 271

  
268 272
    int SYNCI_Step; /* Address step size for SYNCI */
269 273
    int CCRes; /* Cycle count resolution/divisor */
274
    int Status_rw_bitmask; /* Read/write bits in CP0_Status */
270 275

  
271 276
#if defined(CONFIG_USER_ONLY)
272 277
    target_ulong tls_value;
......
330 335
    EXCP_RI,
331 336
    EXCP_OVERFLOW,
332 337
    EXCP_TRAP,
338
    EXCP_FPE,
333 339
    EXCP_DDBS,
334 340
    EXCP_DWATCH,
335
    EXCP_LAE,
336
    EXCP_SAE, /* 24 */
341
    EXCP_LAE, /* 24 */
342
    EXCP_SAE,
337 343
    EXCP_LTLBL,
338 344
    EXCP_TLBL,
339 345
    EXCP_TLBS,
b/target-mips/exec.h
29 29
#define FST0 (env->ft0.fs[FP_ENDIAN_IDX])
30 30
#define FST1 (env->ft1.fs[FP_ENDIAN_IDX])
31 31
#define FST2 (env->ft2.fs[FP_ENDIAN_IDX])
32
#define FSTH0 (env->ft0.fs[!FP_ENDIAN_IDX])
33
#define FSTH1 (env->ft1.fs[!FP_ENDIAN_IDX])
34
#define FSTH2 (env->ft2.fs[!FP_ENDIAN_IDX])
32 35
#define DT0 (env->ft0.d)
33 36
#define DT1 (env->ft1.d)
34 37
#define DT2 (env->ft2.d)
35 38
#define WT0 (env->ft0.w[FP_ENDIAN_IDX])
36 39
#define WT1 (env->ft1.w[FP_ENDIAN_IDX])
37 40
#define WT2 (env->ft2.w[FP_ENDIAN_IDX])
41
#define WTH0 (env->ft0.w[!FP_ENDIAN_IDX])
42
#define WTH1 (env->ft1.w[!FP_ENDIAN_IDX])
43
#define WTH2 (env->ft2.w[!FP_ENDIAN_IDX])
38 44
#endif
39 45

  
40 46
#if defined (DEBUG_OP)
b/target-mips/fop_template.c
19 19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 20
 */
21 21

  
22
#if defined(SFREG)
22
#if defined(FREG)
23 23

  
24
#define OP_WLOAD_FREG(treg, tregname, SFREG)      \
25
    void glue(glue(op_load_fpr_,tregname), SFREG) (void) \
26
    {                                                   \
27
        treg = FPR_W(env, SFREG);     \
28
        RETURN();                                       \
24
#define OP_WLOAD_FREG(treg, tregname, FREG)              \
25
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
26
    {                                                    \
27
        treg = env->fpr[FREG].fs[FP_ENDIAN_IDX];         \
28
        RETURN();                                        \
29 29
    }
30 30

  
31
#define OP_WSTORE_FREG(treg, tregname, SFREG)            \
32
    void glue(glue(op_store_fpr_,tregname), SFREG) (void)\
33
    {                                                   \
34
        FPR_W(env, SFREG) = treg;     \
35
        RETURN();                                       \
31
#define OP_WSTORE_FREG(treg, tregname, FREG)             \
32
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
33
    {                                                    \
34
        env->fpr[FREG].fs[FP_ENDIAN_IDX] = treg;         \
35
        RETURN();                                        \
36 36
    }
37 37

  
38
/* WT0 = SFREG.w: op_load_fpr_WT0_fprSFREG */
39
OP_WLOAD_FREG(WT0, WT0_fpr, SFREG)
40
/* SFREG.w = WT0: op_store_fpr_WT0_fprSFREG */
41
OP_WSTORE_FREG(WT0, WT0_fpr, SFREG)
38
/* WT0 = FREG.w: op_load_fpr_WT0_fprFREG */
39
OP_WLOAD_FREG(WT0, WT0_fpr, FREG)
40
/* FREG.w = WT0: op_store_fpr_WT0_fprFREG */
41
OP_WSTORE_FREG(WT0, WT0_fpr, FREG)
42

  
43
OP_WLOAD_FREG(WT1, WT1_fpr, FREG)
44
OP_WSTORE_FREG(WT1, WT1_fpr, FREG)
45

  
46
OP_WLOAD_FREG(WT2, WT2_fpr, FREG)
47
OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
48

  
49
#define OP_DLOAD_FREG(treg, tregname, FREG)              \
50
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
51
    {                                                    \
52
        if (env->CP0_Status & (1 << CP0St_FR))           \
53
            treg = env->fpr[FREG].fd;                    \
54
        else                                             \
55
            treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
56
                   env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
57
        RETURN();                                        \
58
    }
42 59

  
43
OP_WLOAD_FREG(WT1, WT1_fpr, SFREG)
44
OP_WSTORE_FREG(WT1, WT1_fpr, SFREG)
60
#define OP_DSTORE_FREG(treg, tregname, FREG)             \
61
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
62
    {                                                    \
63
        if (env->CP0_Status & (1 << CP0St_FR))           \
64
            env->fpr[FREG].fd = treg;                    \
65
        else {                                           \
66
            env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
67
            env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg; \
68
        }                                                \
69
        RETURN();                                        \
70
    }
45 71

  
46
OP_WLOAD_FREG(WT2, WT2_fpr, SFREG)
47
OP_WSTORE_FREG(WT2, WT2_fpr, SFREG)
72
OP_DLOAD_FREG(DT0, DT0_fpr, FREG)
73
OP_DSTORE_FREG(DT0, DT0_fpr, FREG)
48 74

  
49
#endif
75
OP_DLOAD_FREG(DT1, DT1_fpr, FREG)
76
OP_DSTORE_FREG(DT1, DT1_fpr, FREG)
50 77

  
51
#if defined(DFREG)
78
OP_DLOAD_FREG(DT2, DT2_fpr, FREG)
79
OP_DSTORE_FREG(DT2, DT2_fpr, FREG)
52 80

  
53
#define OP_DLOAD_FREG(treg, tregname, DFREG)      \
54
    void glue(glue(op_load_fpr_,tregname), DFREG) (void) \
55
    {                                                   \
56
        treg = FPR_D(env, DFREG);                    \
57
        RETURN();                                       \
81
#define OP_PSLOAD_FREG(treg, tregname, FREG)             \
82
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
83
    {                                                    \
84
        treg = env->fpr[FREG].fs[!FP_ENDIAN_IDX];        \
85
        RETURN();                                        \
58 86
    }
59 87

  
60
#define OP_DSTORE_FREG(treg, tregname, DFREG)            \
61
    void glue(glue(op_store_fpr_,tregname), DFREG) (void)\
62
    {                                                   \
63
        FPR_D(env, DFREG) = treg;                    \
64
        RETURN();                                       \
88
#define OP_PSSTORE_FREG(treg, tregname, FREG)            \
89
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
90
    {                                                    \
91
        env->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg;        \
92
        RETURN();                                        \
65 93
    }
66 94

  
67
OP_DLOAD_FREG(DT0, DT0_fpr, DFREG)
68
OP_DSTORE_FREG(DT0, DT0_fpr, DFREG)
95
OP_PSLOAD_FREG(WTH0, WTH0_fpr, FREG)
96
OP_PSSTORE_FREG(WTH0, WTH0_fpr, FREG)
69 97

  
70
OP_DLOAD_FREG(DT1, DT1_fpr, DFREG)
71
OP_DSTORE_FREG(DT1, DT1_fpr, DFREG)
98
OP_PSLOAD_FREG(WTH1, WTH1_fpr, FREG)
99
OP_PSSTORE_FREG(WTH1, WTH1_fpr, FREG)
72 100

  
73
OP_DLOAD_FREG(DT2, DT2_fpr, DFREG)
74
OP_DSTORE_FREG(DT2, DT2_fpr, DFREG)
101
OP_PSLOAD_FREG(WTH2, WTH2_fpr, FREG)
102
OP_PSSTORE_FREG(WTH2, WTH2_fpr, FREG)
75 103

  
76 104
#endif
77 105

  
78 106
#if defined (FTN)
79 107

  
80
#define SET_RESET(treg, tregname)    \
108
#define SET_RESET(treg, tregname)        \
81 109
    void glue(op_set, tregname)(void)    \
82
    {                                \
83
        treg = PARAM1;               \
84
        RETURN();                    \
85
    }                                \
110
    {                                    \
111
        treg = PARAM1;                   \
112
        RETURN();                        \
113
    }                                    \
86 114
    void glue(op_reset, tregname)(void)  \
87
    {                                \
88
        treg = 0;                    \
89
        RETURN();                    \
90
    }                                \
115
    {                                    \
116
        treg = 0;                        \
117
        RETURN();                        \
118
    }
91 119

  
92 120
SET_RESET(WT0, _WT0)
93 121
SET_RESET(WT1, _WT1)
......
95 123
SET_RESET(DT0, _DT0)
96 124
SET_RESET(DT1, _DT1)
97 125
SET_RESET(DT2, _DT2)
126
SET_RESET(WTH0, _WTH0)
127
SET_RESET(WTH1, _WTH1)
128
SET_RESET(WTH2, _WTH2)
98 129

  
99 130
#undef SET_RESET
100 131
#endif
b/target-mips/helper.c
379 379
    case EXCP_TRAP:
380 380
        cause = 13;
381 381
        goto set_EPC;
382
    case EXCP_FPE:
383
        cause = 15;
384
        goto set_EPC;
382 385
    case EXCP_LTLBL:
383 386
        cause = 1;
384 387
        goto set_EPC;
b/target-mips/op.c
23 23
#include "exec.h"
24 24

  
25 25
#ifndef CALL_FROM_TB0
26
#define CALL_FROM_TB0(func) func();
26
#define CALL_FROM_TB0(func) func()
27 27
#endif
28 28
#ifndef CALL_FROM_TB1
29
#define CALL_FROM_TB1(func, arg0) func(arg0);
29
#define CALL_FROM_TB1(func, arg0) func(arg0)
30 30
#endif
31 31
#ifndef CALL_FROM_TB1_CONST16
32
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0);
32
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
33 33
#endif
34 34
#ifndef CALL_FROM_TB2
35
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1);
35
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
36 36
#endif
37 37
#ifndef CALL_FROM_TB2_CONST16
38 38
#define CALL_FROM_TB2_CONST16(func, arg0, arg1)     \
39
CALL_FROM_TB2(func, arg0, arg1);
39
        CALL_FROM_TB2(func, arg0, arg1)
40 40
#endif
41 41
#ifndef CALL_FROM_TB3
42
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2);
42
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
43 43
#endif
44 44
#ifndef CALL_FROM_TB4
45 45
#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
46
        func(arg0, arg1, arg2, arg3);
46
        func(arg0, arg1, arg2, arg3)
47 47
#endif
48 48

  
49 49
#define REG 1
......
144 144
#include "op_template.c"
145 145
#undef TN
146 146

  
147
#define SFREG 0
148
#define DFREG 0
147
#define FREG 0
149 148
#include "fop_template.c"
150
#undef SFREG
151
#undef DFREG
152
#define SFREG 1
149
#undef FREG
150
#define FREG 1
153 151
#include "fop_template.c"
154
#undef SFREG
155
#define SFREG 2
156
#define DFREG 2
152
#undef FREG
153
#define FREG 2
157 154
#include "fop_template.c"
158
#undef SFREG
159
#undef DFREG
160
#define SFREG 3
155
#undef FREG
156
#define FREG 3
161 157
#include "fop_template.c"
162
#undef SFREG
163
#define SFREG 4
164
#define DFREG 4
158
#undef FREG
159
#define FREG 4
165 160
#include "fop_template.c"
166
#undef SFREG
167
#undef DFREG
168
#define SFREG 5
161
#undef FREG
162
#define FREG 5
169 163
#include "fop_template.c"
170
#undef SFREG
171
#define SFREG 6
172
#define DFREG 6
164
#undef FREG
165
#define FREG 6
173 166
#include "fop_template.c"
174
#undef SFREG
175
#undef DFREG
176
#define SFREG 7
167
#undef FREG
168
#define FREG 7
177 169
#include "fop_template.c"
178
#undef SFREG
179
#define SFREG 8
180
#define DFREG 8
170
#undef FREG
171
#define FREG 8
181 172
#include "fop_template.c"
182
#undef SFREG
183
#undef DFREG
184
#define SFREG 9
173
#undef FREG
174
#define FREG 9
185 175
#include "fop_template.c"
186
#undef SFREG
187
#define SFREG 10
188
#define DFREG 10
176
#undef FREG
177
#define FREG 10
189 178
#include "fop_template.c"
190
#undef SFREG
191
#undef DFREG
192
#define SFREG 11
179
#undef FREG
180
#define FREG 11
193 181
#include "fop_template.c"
194
#undef SFREG
195
#define SFREG 12
196
#define DFREG 12
182
#undef FREG
183
#define FREG 12
197 184
#include "fop_template.c"
198
#undef SFREG
199
#undef DFREG
200
#define SFREG 13
185
#undef FREG
186
#define FREG 13
201 187
#include "fop_template.c"
202
#undef SFREG
203
#define SFREG 14
204
#define DFREG 14
188
#undef FREG
189
#define FREG 14
205 190
#include "fop_template.c"
206
#undef SFREG
207
#undef DFREG
208
#define SFREG 15
191
#undef FREG
192
#define FREG 15
209 193
#include "fop_template.c"
210
#undef SFREG
211
#define SFREG 16
212
#define DFREG 16
194
#undef FREG
195
#define FREG 16
213 196
#include "fop_template.c"
214
#undef SFREG
215
#undef DFREG
216
#define SFREG 17
197
#undef FREG
198
#define FREG 17
217 199
#include "fop_template.c"
218
#undef SFREG
219
#define SFREG 18
220
#define DFREG 18
200
#undef FREG
201
#define FREG 18
221 202
#include "fop_template.c"
222
#undef SFREG
223
#undef DFREG
224
#define SFREG 19
203
#undef FREG
204
#define FREG 19
225 205
#include "fop_template.c"
226
#undef SFREG
227
#define SFREG 20
228
#define DFREG 20
206
#undef FREG
207
#define FREG 20
229 208
#include "fop_template.c"
230
#undef SFREG
231
#undef DFREG
232
#define SFREG 21
209
#undef FREG
210
#define FREG 21
233 211
#include "fop_template.c"
234
#undef SFREG
235
#define SFREG 22
236
#define DFREG 22
212
#undef FREG
213
#define FREG 22
237 214
#include "fop_template.c"
238
#undef SFREG
239
#undef DFREG
240
#define SFREG 23
215
#undef FREG
216
#define FREG 23
241 217
#include "fop_template.c"
242
#undef SFREG
243
#define SFREG 24
244
#define DFREG 24
218
#undef FREG
219
#define FREG 24
245 220
#include "fop_template.c"
246
#undef SFREG
247
#undef DFREG
248
#define SFREG 25
221
#undef FREG
222
#define FREG 25
249 223
#include "fop_template.c"
250
#undef SFREG
251
#define SFREG 26
252
#define DFREG 26
224
#undef FREG
225
#define FREG 26
253 226
#include "fop_template.c"
254
#undef SFREG
255
#undef DFREG
256
#define SFREG 27
227
#undef FREG
228
#define FREG 27
257 229
#include "fop_template.c"
258
#undef SFREG
259
#define SFREG 28
260
#define DFREG 28
230
#undef FREG
231
#define FREG 28
261 232
#include "fop_template.c"
262
#undef SFREG
263
#undef DFREG
264
#define SFREG 29
233
#undef FREG
234
#define FREG 29
265 235
#include "fop_template.c"
266
#undef SFREG
267
#define SFREG 30
268
#define DFREG 30
236
#undef FREG
237
#define FREG 30
269 238
#include "fop_template.c"
270
#undef SFREG
271
#undef DFREG
272
#define SFREG 31
239
#undef FREG
240
#define FREG 31
273 241
#include "fop_template.c"
274
#undef SFREG
242
#undef FREG
275 243

  
276 244
#define FTN
277 245
#include "fop_template.c"
......
919 887
void op_movf (void)
920 888
{
921 889
    if (!(env->fcr31 & PARAM1))
922
        env->gpr[PARAM2] = env->gpr[PARAM3];
890
        T0 = T1;
923 891
    RETURN();
924 892
}
925 893

  
926 894
void op_movt (void)
927 895
{
928 896
    if (env->fcr31 & PARAM1)
929
        env->gpr[PARAM2] = env->gpr[PARAM3];
897
        T0 = T1;
930 898
    RETURN();
931 899
}
932 900

  
......
1354 1322
void op_mtc0_status (void)
1355 1323
{
1356 1324
    uint32_t val, old;
1325
    uint32_t mask = env->Status_rw_bitmask;
1357 1326

  
1358
    /* No 64bit FPU, no reverse endianness, no MDMX/DSP, no 64bit ops,
1327
    /* No reverse endianness, no MDMX/DSP, no 64bit ops,
1359 1328
       no 64bit addressing implemented. */
1360
    val = (int32_t)T0 & 0xF878FF17;
1329
    val = (int32_t)T0 & mask;
1361 1330
    old = env->CP0_Status;
1362 1331
    if (!(val & (1 << CP0St_EXL)) &&
1363 1332
        !(val & (1 << CP0St_ERL)) &&
1364 1333
        !(env->hflags & MIPS_HFLAG_DM) &&
1365 1334
        (val & (1 << CP0St_UM)))
1366 1335
        env->hflags |= MIPS_HFLAG_UM;
1367
    env->CP0_Status = (env->CP0_Status & ~0xF878FF17) | val;
1336
    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1368 1337
    if (loglevel & CPU_LOG_EXEC)
1369 1338
        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1370 1339
    CALL_FROM_TB1(cpu_mips_update_irq, env);
......
1643 1612
}
1644 1613
#endif /* TARGET_MIPS64 */
1645 1614

  
1615
/* CP1 functions */
1646 1616
#if 0
1647 1617
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1648 1618
#else
......
1666 1636
    RETURN();
1667 1637
}
1668 1638

  
1669
/* CP1 functions */
1670
void op_cfc1 (void)
1671
{
1672
    if (T1 == 0) {
1673
        T0 = env->fcr0;
1674
    }
1675
    else {
1676
        /* fetch fcr31, masking unused bits */
1677
        T0 = env->fcr31 & 0x0183FFFF;
1678
    }
1679
    DEBUG_FPU_STATE();
1680
    RETURN();
1681
}
1682

  
1683 1639
/* convert MIPS rounding mode in FCR31 to IEEE library */
1684 1640
unsigned int ieee_rm[] = { 
1685 1641
    float_round_nearest_even,
......
1691 1647
#define RESTORE_ROUNDING_MODE \
1692 1648
    set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
1693 1649

  
1694
void op_ctc1 (void)
1650
inline char ieee_ex_to_mips(char ieee)
1695 1651
{
1696
    if (T1 == 0) {
1697
        /* XXX should this throw an exception?
1698
         * don't write to FCR0.
1699
         * env->fcr0 = T0; 
1700
         */
1701
    }
1702
    else {
1703
        /* store new fcr31, masking unused bits */  
1704
        env->fcr31 = T0 & 0x0183FFFF;
1652
    return (ieee & float_flag_inexact) >> 5 |
1653
           (ieee & float_flag_underflow) >> 3 |
1654
           (ieee & float_flag_overflow) >> 1 |
1655
           (ieee & float_flag_divbyzero) << 1 |
1656
           (ieee & float_flag_invalid) << 4;
1657
}
1705 1658

  
1706
        /* set rounding mode */
1707
        RESTORE_ROUNDING_MODE;
1659
inline char mips_ex_to_ieee(char mips)
1660
{
1661
    return (mips & FP_INEXACT) << 5 |
1662
           (mips & FP_UNDERFLOW) << 3 |
1663
           (mips & FP_OVERFLOW) << 1 |
1664
           (mips & FP_DIV0) >> 1 |
1665
           (mips & FP_INVALID) >> 4;
1666
}
1708 1667

  
1709
#ifndef CONFIG_SOFTFLOAT
1710
        /* no floating point exception for native float */
1711
        SET_FP_ENABLE(env->fcr31, 0);
1712
#endif
1668
inline void update_fcr31(void)
1669
{
1670
    int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fp_status));
1671

  
1672
    SET_FP_CAUSE(env->fcr31, tmp);
1673
    if (GET_FP_ENABLE(env->fcr31) & tmp)
1674
        CALL_FROM_TB1(do_raise_exception, EXCP_FPE);
1675
    else
1676
        UPDATE_FP_FLAGS(env->fcr31, tmp);
1677
}
1678

  
1679

  
1680
void op_cfc1 (void)
1681
{
1682
    switch (T1) {
1683
    case 0:
1684
        T0 = (int32_t)env->fcr0;
1685
        break;
1686
    case 25:
1687
        T0 = ((env->fcr31 >> 24) & 0xfe) | ((env->fcr31 >> 23) & 0x1);
1688
        break;
1689
    case 26:
1690
        T0 = env->fcr31 & 0x0003f07c;
1691
        break;
1692
    case 28:
1693
        T0 = (env->fcr31 & 0x00000f83) | ((env->fcr31 >> 22) & 0x4);
1694
        break;
1695
    default:
1696
        T0 = (int32_t)env->fcr31;
1697
        break;
1698
    }
1699
    DEBUG_FPU_STATE();
1700
    RETURN();
1701
}
1702

  
1703
void op_ctc1 (void)
1704
{
1705
    switch(T1) {
1706
    case 25:
1707
        if (T0 & 0xffffff00)
1708
            goto leave;
1709
        env->fcr31 = (env->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |
1710
                     ((T0 & 0x1) << 23);
1711
        break;
1712
    case 26:
1713
        if (T0 & 0x007c0000)
1714
            goto leave;
1715
        env->fcr31 = (env->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);
1716
        break;
1717
    case 28:
1718
        if (T0 & 0x007c0000)
1719
            goto leave;
1720
        env->fcr31 = (env->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |
1721
                     ((T0 & 0x4) << 22);
1722
        break;
1723
    case 31:
1724
        if (T0 & 0x007c0000)
1725
            goto leave;
1726
        env->fcr31 = T0;
1727
        break;
1728
    default:
1729
        goto leave;
1713 1730
    }
1731
    /* set rounding mode */
1732
    RESTORE_ROUNDING_MODE;
1733
    set_float_exception_flags(0, &env->fp_status);
1734
    if ((GET_FP_ENABLE(env->fcr31) | 0x20) & GET_FP_CAUSE(env->fcr31))
1735
        CALL_FROM_TB1(do_raise_exception, EXCP_FPE);
1736
 leave:
1714 1737
    DEBUG_FPU_STATE();
1715 1738
    RETURN();
1716 1739
}
......
1729 1752
    RETURN();
1730 1753
}
1731 1754

  
1755
void op_dmfc1 (void)
1756
{
1757
    T0 = DT0;
1758
    DEBUG_FPU_STATE();
1759
    RETURN();
1760
}
1761

  
1762
void op_dmtc1 (void)
1763
{
1764
    DT0 = T0;
1765
    DEBUG_FPU_STATE();
1766
    RETURN();
1767
}
1768

  
1769
void op_mfhc1 (void)
1770
{
1771
    T0 = WTH0;
1772
    DEBUG_FPU_STATE();
1773
    RETURN();
1774
}
1775

  
1776
void op_mthc1 (void)
1777
{
1778
    WTH0 = T0;
1779
    DEBUG_FPU_STATE();
1780
    RETURN();
1781
}
1782

  
1732 1783
/* Float support.
1733 1784
   Single precition routines have a "s" suffix, double precision a
1734
   "d" suffix.  */
1785
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1786
   paired single lowwer "pl", paired single upper "pu".  */
1735 1787

  
1736 1788
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1737 1789

  
1738 1790
FLOAT_OP(cvtd, s)
1739 1791
{
1792
    set_float_exception_flags(0, &env->fp_status);
1740 1793
    FDT2 = float32_to_float64(FST0, &env->fp_status);
1794
    update_fcr31();
1741 1795
    DEBUG_FPU_STATE();
1742 1796
    RETURN();
1743 1797
}
1744 1798
FLOAT_OP(cvtd, w)
1745 1799
{
1800
    set_float_exception_flags(0, &env->fp_status);
1746 1801
    FDT2 = int32_to_float64(WT0, &env->fp_status);
1802
    update_fcr31();
1803
    DEBUG_FPU_STATE();
1804
    RETURN();
1805
}
1806
FLOAT_OP(cvtd, l)
1807
{
1808
    set_float_exception_flags(0, &env->fp_status);
1809
    FDT2 = int64_to_float64(DT0, &env->fp_status);
1810
    update_fcr31();
1811
    DEBUG_FPU_STATE();
1812
    RETURN();
1813
}
1814
FLOAT_OP(cvtl, d)
1815
{
1816
    set_float_exception_flags(0, &env->fp_status);
1817
    DT2 = float64_to_int64(FDT0, &env->fp_status);
1818
    update_fcr31();
1819
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1820
        DT2 = 0x7fffffffffffffffULL;
1821
    DEBUG_FPU_STATE();
1822
    RETURN();
1823
}
1824
FLOAT_OP(cvtl, s)
1825
{
1826
    set_float_exception_flags(0, &env->fp_status);
1827
    DT2 = float32_to_int64(FST0, &env->fp_status);
1828
    update_fcr31();
1829
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1830
        DT2 = 0x7fffffffffffffffULL;
1831
    DEBUG_FPU_STATE();
1832
    RETURN();
1833
}
1834
FLOAT_OP(cvtps, s)
1835
{
1836
    WT2 = WT0;
1837
    WTH2 = WT1;
1838
    DEBUG_FPU_STATE();
1839
    RETURN();
1840
}
1841
FLOAT_OP(cvtps, pw)
1842
{
1843
    set_float_exception_flags(0, &env->fp_status);
1844
    FST2 = int32_to_float32(WT0, &env->fp_status);
1845
    FSTH2 = int32_to_float32(WTH0, &env->fp_status);
1846
    update_fcr31();
1847
    DEBUG_FPU_STATE();
1848
    RETURN();
1849
}
1850
FLOAT_OP(cvtpw, ps)
1851
{
1852
    set_float_exception_flags(0, &env->fp_status);
1853
    WT2 = float32_to_int32(FST0, &env->fp_status);
1854
    WTH2 = float32_to_int32(FSTH0, &env->fp_status);
1855
    update_fcr31();
1856
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1857
        WT2 = 0x7fffffff;
1747 1858
    DEBUG_FPU_STATE();
1748 1859
    RETURN();
1749 1860
}
1750 1861
FLOAT_OP(cvts, d)
1751 1862
{
1863
    set_float_exception_flags(0, &env->fp_status);
1752 1864
    FST2 = float64_to_float32(FDT0, &env->fp_status);
1865
    update_fcr31();
1753 1866
    DEBUG_FPU_STATE();
1754 1867
    RETURN();
1755 1868
}
1756 1869
FLOAT_OP(cvts, w)
1757 1870
{
1871
    set_float_exception_flags(0, &env->fp_status);
1758 1872
    FST2 = int32_to_float32(WT0, &env->fp_status);
1873
    update_fcr31();
1874
    DEBUG_FPU_STATE();
1875
    RETURN();
1876
}
1877
FLOAT_OP(cvts, l)
1878
{
1879
    set_float_exception_flags(0, &env->fp_status);
1880
    FST2 = int64_to_float32(DT0, &env->fp_status);
1881
    update_fcr31();
1882
    DEBUG_FPU_STATE();
1883
    RETURN();
1884
}
1885
FLOAT_OP(cvts, pl)
1886
{
1887
    set_float_exception_flags(0, &env->fp_status);
1888
    WT2 = WT0;
1889
    update_fcr31();
1890
    DEBUG_FPU_STATE();
1891
    RETURN();
1892
}
1893
FLOAT_OP(cvts, pu)
1894
{
1895
    set_float_exception_flags(0, &env->fp_status);
1896
    WT2 = WTH0;
1897
    update_fcr31();
1759 1898
    DEBUG_FPU_STATE();
1760 1899
    RETURN();
1761 1900
}
1762 1901
FLOAT_OP(cvtw, s)
1763 1902
{
1903
    set_float_exception_flags(0, &env->fp_status);
1764 1904
    WT2 = float32_to_int32(FST0, &env->fp_status);
1905
    update_fcr31();
1906
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1907
        WT2 = 0x7fffffff;
1765 1908
    DEBUG_FPU_STATE();
1766 1909
    RETURN();
1767 1910
}
1768 1911
FLOAT_OP(cvtw, d)
1769 1912
{
1913
    set_float_exception_flags(0, &env->fp_status);
1770 1914
    WT2 = float64_to_int32(FDT0, &env->fp_status);
1915
    update_fcr31();
1916
    if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
1917
        WT2 = 0x7fffffff;
1918
    DEBUG_FPU_STATE();
1919
    RETURN();
1920
}
1921

  
1922
FLOAT_OP(pll, ps)
1923
{
1924
    DT2 = ((uint64_t)WT0 << 32) | WT1;
1925
    DEBUG_FPU_STATE();
1926
    RETURN();
1927
}
1928
FLOAT_OP(plu, ps)
1929
{
1930
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
1931
    DEBUG_FPU_STATE();
1932
    RETURN();
1933
}
1934
FLOAT_OP(pul, ps)
1935
{
1936
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
1937
    DEBUG_FPU_STATE();
1938
    RETURN();
1939
}
1940
FLOAT_OP(puu, ps)
1941
{
1942
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1771 1943
    DEBUG_FPU_STATE();
1772 1944
    RETURN();
1773 1945
}
1774 1946

  
1947
FLOAT_OP(roundl, d)
1948
{
1949
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1950
    DT2 = float64_round_to_int(FDT0, &env->fp_status);
1951
    RESTORE_ROUNDING_MODE;
1952
    DEBUG_FPU_STATE();
1953
    RETURN();
1954
}
1955
FLOAT_OP(roundl, s)
1956
{
1957
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1958
    DT2 = float32_round_to_int(FST0, &env->fp_status);
1959
    RESTORE_ROUNDING_MODE;
1960
    DEBUG_FPU_STATE();
1961
    RETURN();
1962
}
1775 1963
FLOAT_OP(roundw, d)
1776 1964
{
1777 1965
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1778 1966
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
1779 1967
    RESTORE_ROUNDING_MODE;
1780

  
1781 1968
    DEBUG_FPU_STATE();
1782 1969
    RETURN();
1783 1970
}
......
1790 1977
    RETURN();
1791 1978
}
1792 1979

  
1980
FLOAT_OP(truncl, d)
1981
{
1982
    DT2 = float64_to_int64_round_to_zero(FDT0, &env->fp_status);
1983
    DEBUG_FPU_STATE();
1984
    RETURN();
1985
}
1986
FLOAT_OP(truncl, s)
1987
{
1988
    DT2 = float32_to_int64_round_to_zero(FST0, &env->fp_status);
1989
    DEBUG_FPU_STATE();
1990
    RETURN();
1991
}
1793 1992
FLOAT_OP(truncw, d)
1794 1993
{
1795 1994
    WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
......
1803 2002
    RETURN();
1804 2003
}
1805 2004

  
2005
FLOAT_OP(ceill, d)
2006
{
2007
    set_float_rounding_mode(float_round_up, &env->fp_status);
2008
    DT2 = float64_round_to_int(FDT0, &env->fp_status);
2009
    RESTORE_ROUNDING_MODE;
2010
    DEBUG_FPU_STATE();
2011
    RETURN();
2012
}
2013
FLOAT_OP(ceill, s)
2014
{
2015
    set_float_rounding_mode(float_round_up, &env->fp_status);
2016
    DT2 = float32_round_to_int(FST0, &env->fp_status);
2017
    RESTORE_ROUNDING_MODE;
2018
    DEBUG_FPU_STATE();
2019
    RETURN();
2020
}
1806 2021
FLOAT_OP(ceilw, d)
1807 2022
{
1808 2023
    set_float_rounding_mode(float_round_up, &env->fp_status);
1809 2024
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
1810 2025
    RESTORE_ROUNDING_MODE;
1811

  
1812 2026
    DEBUG_FPU_STATE();
1813 2027
    RETURN();
1814 2028
}
......
1821 2035
    RETURN();
1822 2036
}
1823 2037

  
2038
FLOAT_OP(floorl, d)
2039
{
2040
    set_float_rounding_mode(float_round_down, &env->fp_status);
2041
    DT2 = float64_round_to_int(FDT0, &env->fp_status);
2042
    RESTORE_ROUNDING_MODE;
2043
    DEBUG_FPU_STATE();
2044
    RETURN();
2045
}
2046
FLOAT_OP(floorl, s)
2047
{
2048
    set_float_rounding_mode(float_round_down, &env->fp_status);
2049
    DT2 = float32_round_to_int(FST0, &env->fp_status);
2050
    RESTORE_ROUNDING_MODE;
2051
    DEBUG_FPU_STATE();
2052
    RETURN();
2053
}
1824 2054
FLOAT_OP(floorw, d)
1825 2055
{
1826 2056
    set_float_rounding_mode(float_round_down, &env->fp_status);
1827 2057
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
1828 2058
    RESTORE_ROUNDING_MODE;
1829

  
1830 2059
    DEBUG_FPU_STATE();
1831 2060
    RETURN();
1832 2061
}
......
1839 2068
    RETURN();
1840 2069
}
1841 2070

  
2071
FLOAT_OP(movf, d)
2072
{
2073
    if (!(env->fcr31 & PARAM1))
2074
        DT2 = DT0;
2075
    DEBUG_FPU_STATE();
2076
    RETURN();
2077
}
2078
FLOAT_OP(movf, s)
2079
{
2080
    if (!(env->fcr31 & PARAM1))
2081
        WT2 = WT0;
2082
    DEBUG_FPU_STATE();
2083
    RETURN();
2084
}
2085
FLOAT_OP(movf, ps)
2086
{
2087
    if (!(env->fcr31 & PARAM1)) {
2088
        WT2 = WT0;
2089
        WTH2 = WTH0;
2090
    }
2091
    DEBUG_FPU_STATE();
2092
    RETURN();
2093
}
2094
FLOAT_OP(movt, d)
2095
{
2096
    if (env->fcr31 & PARAM1)
2097
        DT2 = DT0;
2098
    DEBUG_FPU_STATE();
2099
    RETURN();
2100
}
2101
FLOAT_OP(movt, s)
2102
{
2103
    if (env->fcr31 & PARAM1)
2104
        WT2 = WT0;
2105
    DEBUG_FPU_STATE();
2106
    RETURN();
2107
}
2108
FLOAT_OP(movt, ps)
2109
{
2110
    if (env->fcr31 & PARAM1) {
2111
        WT2 = WT0;
2112
        WTH2 = WTH0;
2113
    }
2114
    DEBUG_FPU_STATE();
2115
    RETURN();
2116
}
2117
FLOAT_OP(movz, d)
2118
{
2119
    if (!T0)
2120
        DT2 = DT0;
2121
    DEBUG_FPU_STATE();
2122
    RETURN();
2123
}
2124
FLOAT_OP(movz, s)
2125
{
2126
    if (!T0)
2127
        WT2 = WT0;
2128
    DEBUG_FPU_STATE();
2129
    RETURN();
2130
}
2131
FLOAT_OP(movz, ps)
2132
{
2133
    if (!T0) {
2134
        WT2 = WT0;
2135
        WTH2 = WTH0;
2136
    }
2137
    DEBUG_FPU_STATE();
2138
    RETURN();
2139
}
2140
FLOAT_OP(movn, d)
2141
{
2142
    if (T0)
2143
        DT2 = DT0;
2144
    DEBUG_FPU_STATE();
2145
    RETURN();
2146
}
2147
FLOAT_OP(movn, s)
2148
{
2149
    if (T0)
2150
        WT2 = WT0;
2151
    DEBUG_FPU_STATE();
2152
    RETURN();
2153
}
2154
FLOAT_OP(movn, ps)
2155
{
2156
    if (T0) {
2157
        WT2 = WT0;
2158
        WTH2 = WTH0;
2159
    }
2160
    DEBUG_FPU_STATE();
2161
    RETURN();
2162
}
2163

  
1842 2164
/* binary operations */
1843 2165
#define FLOAT_BINOP(name) \
1844 2166
FLOAT_OP(name, d)         \
1845 2167
{                         \
2168
    set_float_exception_flags(0, &env->fp_status);            \
1846 2169
    FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);    \
2170
    update_fcr31();       \
1847 2171
    DEBUG_FPU_STATE();    \
1848 2172
}                         \
1849 2173
FLOAT_OP(name, s)         \
1850 2174
{                         \
2175
    set_float_exception_flags(0, &env->fp_status);            \
1851 2176
    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);    \
2177
    update_fcr31();       \
2178
    DEBUG_FPU_STATE();    \
2179
}                         \
2180
FLOAT_OP(name, ps)        \
2181
{                         \
2182
    set_float_exception_flags(0, &env->fp_status);            \
2183
    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);    \
2184
    FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
2185
    update_fcr31();       \
1852 2186
    DEBUG_FPU_STATE();    \
1853 2187
}
1854 2188
FLOAT_BINOP(add)
......
1857 2191
FLOAT_BINOP(div)
1858 2192
#undef FLOAT_BINOP
1859 2193

  
2194
/* ternary operations */
2195
#define FLOAT_TERNOP(name1, name2) \
2196
FLOAT_OP(name1 ## name2, d)        \
2197
{                                  \
2198
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status);    \
2199
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status);    \
2200
    DEBUG_FPU_STATE();             \
2201
}                                  \
2202
FLOAT_OP(name1 ## name2, s)        \
2203
{                                  \
2204
    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
2205
    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
2206
    DEBUG_FPU_STATE();             \
2207
}                                  \
2208
FLOAT_OP(name1 ## name2, ps)       \
2209
{                                  \
2210
    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
2211
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
2212
    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
2213
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
2214
    DEBUG_FPU_STATE();             \
2215
}
2216
FLOAT_TERNOP(mul, add)
2217
FLOAT_TERNOP(mul, sub)
2218
#undef FLOAT_TERNOP
2219

  
1860 2220
/* unary operations, modifying fp status  */
1861 2221
#define FLOAT_UNOP(name)  \
1862 2222
FLOAT_OP(name, d)         \
......
1868 2228
{                         \
1869 2229
    FST2 = float32_ ## name(FST0, &env->fp_status);   \
1870 2230
    DEBUG_FPU_STATE();    \
2231
}                         \
2232
FLOAT_OP(name, ps)        \
2233
{                         \
2234
    FST2 = float32_ ## name(FST0, &env->fp_status);   \
2235
    FSTH2 = float32_ ## name(FSTH0, &env->fp_status); \
2236
    DEBUG_FPU_STATE();    \
1871 2237
}
1872 2238
FLOAT_UNOP(sqrt)
1873 2239
#undef FLOAT_UNOP
......
1883 2249
{                         \
1884 2250
    FST2 = float32_ ## name(FST0);   \
1885 2251
    DEBUG_FPU_STATE();    \
2252
}                         \
2253
FLOAT_OP(name, ps)        \
2254
{                         \
2255
    FST2 = float32_ ## name(FST0);   \
2256
    FSTH2 = float32_ ## name(FSTH0); \
2257
    DEBUG_FPU_STATE();    \
1886 2258
}
1887 2259
FLOAT_UNOP(abs)
1888 2260
FLOAT_UNOP(chs)
......
1900 2272
    DEBUG_FPU_STATE();
1901 2273
    RETURN();
1902 2274
}
2275
FLOAT_OP(mov, ps)
2276
{
2277
    FST2 = FST0;
2278
    FSTH2 = FSTH0;
2279
    DEBUG_FPU_STATE();
2280
    RETURN();
2281
}
2282
FLOAT_OP(alnv, ps)
2283
{
2284
    switch (T0 & 0x7) {
2285
    case 0:
2286
        FST2 = FST0;
2287
        FSTH2 = FSTH0;
2288
        break;
2289
    case 4:
2290
#ifdef TARGET_WORDS_BIGENDIAN
2291
        FSTH2 = FST0;
2292
        FST2 = FSTH1;
2293
#else
2294
        FSTH2 = FST1;
2295
        FST2 = FSTH0;
2296
#endif
2297
        break;
2298
    default: /* unpredictable */
2299
        break;
2300
    }
2301
    DEBUG_FPU_STATE();
2302
    RETURN();
2303
}
1903 2304

  
1904 2305
#ifdef CONFIG_SOFTFLOAT
1905 2306
#define clear_invalid() do {                                \
......
1913 2314

  
1914 2315
extern void dump_fpu_s(CPUState *env);
1915 2316

  
1916
#define FOP_COND(fmt, op, sig, cond)           \
1917
void op_cmp_ ## fmt ## _ ## op (void)          \
2317
#define FOP_COND_D(op, cond)                   \
2318
void op_cmp_d_ ## op (void)                    \
1918 2319
{                                              \
1919
    if (cond)                                  \
1920
        SET_FP_COND(env->fcr31);               \
2320
    int c = cond;                              \
2321
    update_fcr31();                            \
2322
    if (c)                                     \
2323
        SET_FP_COND(PARAM1, env);              \
1921 2324
    else                                       \
1922
        CLEAR_FP_COND(env->fcr31);             \
1923
    if (!sig)                                  \
1924
        clear_invalid();                       \
1925
    /*CALL_FROM_TB1(dump_fpu_s, env);*/ \
2325
        CLEAR_FP_COND(PARAM1, env);            \
1926 2326
    DEBUG_FPU_STATE();                         \
1927 2327
    RETURN();                                  \
1928 2328
}
1929 2329

  
1930
int float64_is_unordered(float64 a, float64 b STATUS_PARAM)
2330
int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
1931 2331
{
1932
    if (float64_is_nan(a) || float64_is_nan(b)) {
2332
    if (float64_is_signaling_nan(a) ||
2333
        float64_is_signaling_nan(b) ||
2334
        (sig && (float64_is_nan(a) || float64_is_nan(b)))) {
1933 2335
        float_raise(float_flag_invalid, status);
1934 2336
        return 1;
1935
    }
1936
    else {
2337
    } else if (float64_is_nan(a) || float64_is_nan(b)) {
2338
        return 1;
2339
    } else {
1937 2340
        return 0;
1938 2341
    }
1939 2342
}
1940 2343

  
1941
FOP_COND(d, f,   0,                                                      0) 
1942
FOP_COND(d, un,  0, float64_is_unordered(FDT1, FDT0, &env->fp_status))
1943
FOP_COND(d, eq,  0,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
1944
FOP_COND(d, ueq, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1945
FOP_COND(d, olt, 0,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
1946
FOP_COND(d, ult, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1947
FOP_COND(d, ole, 0,                                                      float64_le(FDT0, FDT1, &env->fp_status))
1948
FOP_COND(d, ule, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
1949 2344
/* NOTE: the comma operator will make "cond" to eval to false,
1950
 * but float*_is_unordered() is still called
1951
 */
1952
FOP_COND(d, sf,  1,                                                      (float64_is_unordered(FDT0, FDT1, &env->fp_status), 0))
1953
FOP_COND(d, ngle,1, float64_is_unordered(FDT1, FDT0, &env->fp_status))
1954
FOP_COND(d, seq, 1,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
1955
FOP_COND(d, ngl, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1956
FOP_COND(d, lt,  1,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
1957
FOP_COND(d, nge, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1958
FOP_COND(d, le,  1,                                                      float64_le(FDT0, FDT1, &env->fp_status))
1959
FOP_COND(d, ngt, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
1960

  
1961
flag float32_is_unordered(float32 a, float32 b STATUS_PARAM)
1962
{
1963
    extern flag float32_is_nan( float32 a );
1964
    if (float32_is_nan(a) || float32_is_nan(b)) {
2345
 * but float*_is_unordered() is still called. */
2346
FOP_COND_D(f,   (float64_is_unordered(0, FDT1, FDT0, &env->fp_status), 0))
2347
FOP_COND_D(un,  float64_is_unordered(0, FDT1, FDT0, &env->fp_status))
2348
FOP_COND_D(eq,  !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
2349
FOP_COND_D(ueq, float64_is_unordered(0, FDT1, FDT0, &env->fp_status)  || float64_eq(FDT0, FDT1, &env->fp_status))
2350
FOP_COND_D(olt, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
2351
FOP_COND_D(ult, float64_is_unordered(0, FDT1, FDT0, &env->fp_status)  || float64_lt(FDT0, FDT1, &env->fp_status))
2352
FOP_COND_D(ole, !float64_is_unordered(0, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
2353
FOP_COND_D(ule, float64_is_unordered(0, FDT1, FDT0, &env->fp_status)  || float64_le(FDT0, FDT1, &env->fp_status))
2354
/* NOTE: the comma operator will make "cond" to eval to false,
2355
 * but float*_is_unordered() is still called. */
2356
FOP_COND_D(sf,  (float64_is_unordered(1, FDT1, FDT0, &env->fp_status), 0))
2357
FOP_COND_D(ngle,float64_is_unordered(1, FDT1, FDT0, &env->fp_status))
2358
FOP_COND_D(seq, !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_eq(FDT0, FDT1, &env->fp_status))
2359
FOP_COND_D(ngl, float64_is_unordered(1, FDT1, FDT0, &env->fp_status)  || float64_eq(FDT0, FDT1, &env->fp_status))
2360
FOP_COND_D(lt,  !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_lt(FDT0, FDT1, &env->fp_status))
2361
FOP_COND_D(nge, float64_is_unordered(1, FDT1, FDT0, &env->fp_status)  || float64_lt(FDT0, FDT1, &env->fp_status))
2362
FOP_COND_D(le,  !float64_is_unordered(1, FDT1, FDT0, &env->fp_status) && float64_le(FDT0, FDT1, &env->fp_status))
2363
FOP_COND_D(ngt, float64_is_unordered(1, FDT1, FDT0, &env->fp_status)  || float64_le(FDT0, FDT1, &env->fp_status))
2364

  
2365
#define FOP_COND_S(op, cond)                   \
2366
void op_cmp_s_ ## op (void)                    \
2367
{                                              \
2368
    int c = cond;                              \
2369
    update_fcr31();                            \
2370
    if (c)                                     \
2371
        SET_FP_COND(PARAM1, env);              \
2372
    else                                       \
2373
        CLEAR_FP_COND(PARAM1, env);            \
2374
    DEBUG_FPU_STATE();                         \
2375
    RETURN();                                  \
2376
}
2377

  
2378
flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
2379
{
2380
    extern flag float32_is_nan(float32 a);
2381
    if (float32_is_signaling_nan(a) ||
2382
        float32_is_signaling_nan(b) ||
2383
        (sig && (float32_is_nan(a) || float32_is_nan(b)))) {
1965 2384
        float_raise(float_flag_invalid, status);
1966 2385
        return 1;
1967
    }
1968
    else {
2386
    } else if (float32_is_nan(a) || float32_is_nan(b)) {
2387
        return 1;
2388
    } else {
1969 2389
        return 0;
1970 2390
    }
1971 2391
}
1972 2392

  
1973 2393
/* NOTE: the comma operator will make "cond" to eval to false,
1974
 * but float*_is_unordered() is still called
1975
 */
1976
FOP_COND(s, f,   0,                                                      0) 
1977
FOP_COND(s, un,  0, float32_is_unordered(FST1, FST0, &env->fp_status))
1978
FOP_COND(s, eq,  0,                                                      float32_eq(FST0, FST1, &env->fp_status))
1979
FOP_COND(s, ueq, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1980
FOP_COND(s, olt, 0,                                                      float32_lt(FST0, FST1, &env->fp_status))
1981
FOP_COND(s, ult, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1982
FOP_COND(s, ole, 0,                                                      float32_le(FST0, FST1, &env->fp_status))
1983
FOP_COND(s, ule, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
2394
 * but float*_is_unordered() is still called. */
2395
FOP_COND_S(f,   (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0))
2396
FOP_COND_S(un,  float32_is_unordered(0, FST1, FST0, &env->fp_status))
2397
FOP_COND_S(eq,  !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
2398
FOP_COND_S(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status)  || float32_eq(FST0, FST1, &env->fp_status))
2399
FOP_COND_S(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
2400
FOP_COND_S(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status)  || float32_lt(FST0, FST1, &env->fp_status))
2401
FOP_COND_S(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
2402
FOP_COND_S(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status)  || float32_le(FST0, FST1, &env->fp_status))
1984 2403
/* NOTE: the comma operator will make "cond" to eval to false,
1985
 * but float*_is_unordered() is still called
1986
 */
1987
FOP_COND(s, sf,  1,                                                      (float32_is_unordered(FST0, FST1, &env->fp_status), 0))
1988
FOP_COND(s, ngle,1, float32_is_unordered(FST1, FST0, &env->fp_status))
1989
FOP_COND(s, seq, 1,                                                      float32_eq(FST0, FST1, &env->fp_status))
1990
FOP_COND(s, ngl, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1991
FOP_COND(s, lt,  1,                                                      float32_lt(FST0, FST1, &env->fp_status))
1992
FOP_COND(s, nge, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1993
FOP_COND(s, le,  1,                                                      float32_le(FST0, FST1, &env->fp_status))
1994
FOP_COND(s, ngt, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
2404
 * but float*_is_unordered() is still called. */
2405
FOP_COND_S(sf,  (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0))
2406
FOP_COND_S(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status))
2407
FOP_COND_S(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_eq(FST0, FST1, &env->fp_status))
2408
FOP_COND_S(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status)  || float32_eq(FST0, FST1, &env->fp_status))
2409
FOP_COND_S(lt,  !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_lt(FST0, FST1, &env->fp_status))
2410
FOP_COND_S(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status)  || float32_lt(FST0, FST1, &env->fp_status))
2411
FOP_COND_S(le,  !float32_is_unordered(1, FST1, FST0, &env->fp_status) && float32_le(FST0, FST1, &env->fp_status))
2412
FOP_COND_S(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status)  || float32_le(FST0, FST1, &env->fp_status))
2413

  
2414
#define FOP_COND_PS(op, condl, condh)          \
2415
void op_cmp_ps_ ## op (void)                   \
2416
{                                              \
2417
    int cl = condl;                            \
2418
    int ch = condh;                            \
2419
    update_fcr31();                            \
2420
    if (cl)                                    \
2421
        SET_FP_COND(PARAM1, env);              \
2422
    else                                       \
2423
        CLEAR_FP_COND(PARAM1, env);            \
2424
    if (ch)                                    \
2425
        SET_FP_COND(PARAM1 + 1, env);          \
2426
    else                                       \
2427
        CLEAR_FP_COND(PARAM1 + 1, env);        \
2428
    DEBUG_FPU_STATE();                         \
2429
    RETURN();                                  \
2430
}
2431

  
2432
/* NOTE: the comma operator will make "cond" to eval to false,
2433
 * but float*_is_unordered() is still called. */
2434
FOP_COND_PS(f,   (float32_is_unordered(0, FST1, FST0, &env->fp_status), 0),
2435
                 (float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status), 0))
2436
FOP_COND_PS(un,  float32_is_unordered(0, FST1, FST0, &env->fp_status),
2437
                 float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status))
2438
FOP_COND_PS(eq,  !float32_is_unordered(0, FST1, FST0, &env->fp_status)   && float32_eq(FST0, FST1, &env->fp_status),
2439
                 !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
2440
FOP_COND_PS(ueq, float32_is_unordered(0, FST1, FST0, &env->fp_status)    || float32_eq(FST0, FST1, &env->fp_status),
2441
                 float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status)  || float32_eq(FSTH0, FSTH1, &env->fp_status))
2442
FOP_COND_PS(olt, !float32_is_unordered(0, FST1, FST0, &env->fp_status)   && float32_lt(FST0, FST1, &env->fp_status),
2443
                 !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
2444
FOP_COND_PS(ult, float32_is_unordered(0, FST1, FST0, &env->fp_status)    || float32_lt(FST0, FST1, &env->fp_status),
2445
                 float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status)  || float32_lt(FSTH0, FSTH1, &env->fp_status))
2446
FOP_COND_PS(ole, !float32_is_unordered(0, FST1, FST0, &env->fp_status)   && float32_le(FST0, FST1, &env->fp_status),
2447
                 !float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
2448
FOP_COND_PS(ule, float32_is_unordered(0, FST1, FST0, &env->fp_status)    || float32_le(FST0, FST1, &env->fp_status),
2449
                 float32_is_unordered(0, FSTH1, FSTH0, &env->fp_status)  || float32_le(FSTH0, FSTH1, &env->fp_status))
2450
/* NOTE: the comma operator will make "cond" to eval to false,
2451
 * but float*_is_unordered() is still called. */
2452
FOP_COND_PS(sf,  (float32_is_unordered(1, FST1, FST0, &env->fp_status), 0),
2453
                 (float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status), 0))
2454
FOP_COND_PS(ngle,float32_is_unordered(1, FST1, FST0, &env->fp_status),
2455
                 float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status))
2456
FOP_COND_PS(seq, !float32_is_unordered(1, FST1, FST0, &env->fp_status)   && float32_eq(FST0, FST1, &env->fp_status),
2457
                 !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_eq(FSTH0, FSTH1, &env->fp_status))
2458
FOP_COND_PS(ngl, float32_is_unordered(1, FST1, FST0, &env->fp_status)    || float32_eq(FST0, FST1, &env->fp_status),
2459
                 float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status)  || float32_eq(FSTH0, FSTH1, &env->fp_status))
2460
FOP_COND_PS(lt,  !float32_is_unordered(1, FST1, FST0, &env->fp_status)   && float32_lt(FST0, FST1, &env->fp_status),
2461
                 !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_lt(FSTH0, FSTH1, &env->fp_status))
2462
FOP_COND_PS(nge, float32_is_unordered(1, FST1, FST0, &env->fp_status)    || float32_lt(FST0, FST1, &env->fp_status),
2463
                 float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status)  || float32_lt(FSTH0, FSTH1, &env->fp_status))
2464
FOP_COND_PS(le,  !float32_is_unordered(1, FST1, FST0, &env->fp_status)   && float32_le(FST0, FST1, &env->fp_status),
2465
                 !float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status) && float32_le(FSTH0, FSTH1, &env->fp_status))
2466
FOP_COND_PS(ngt, float32_is_unordered(1, FST1, FST0, &env->fp_status)    || float32_le(FST0, FST1, &env->fp_status),
2467
                 float32_is_unordered(1, FSTH1, FSTH0, &env->fp_status)  || float32_le(FSTH0, FSTH1, &env->fp_status))
1995 2468

  
1996 2469
void op_bc1f (void)
1997 2470
{
1998
    T0 = ! IS_FP_COND_SET(env->fcr31);
2471
    T0 = !IS_FP_COND_SET(PARAM1, env);
2472
    DEBUG_FPU_STATE();
2473
    RETURN();
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff