~ubuntu-branches/ubuntu/raring/mame/raring-proposed

« back to all changes in this revision

Viewing changes to mess/src/emu/cpu/i386/x87ops.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Intel x87 FPU opcodes
2
 
 
3
 
#define ST(x)   (cpustate->fpu_reg[(cpustate->fpu_top + (x)) & 7])
4
 
#define FPU_INFINITY_DOUBLE             U64(0x7ff0000000000000)
5
 
#define FPU_INFINITY_SINGLE             (0x7f800000)
6
 
#define FPU_SIGN_BIT_DOUBLE             U64(0x8000000000000000)
7
 
#define FPU_SIGN_BIT_SINGLE             (0x80000000)
8
 
 
9
 
// FPU control word flags
10
 
#define FPU_MASK_INVALID_OP                     0x0001
11
 
#define FPU_MASK_DENORMAL_OP            0x0002
12
 
#define FPU_MASK_ZERO_DIVIDE            0x0004
13
 
#define FPU_MASK_OVERFLOW                       0x0008
14
 
#define FPU_MASK_UNDERFLOW                      0x0010
15
 
#define FPU_MASK_PRECISION                      0x0020
16
 
 
17
 
// FPU status word flags
18
 
#define FPU_BUSY                                        0x8000
19
 
#define FPU_C3                                          0x4000
20
 
#define FPU_STACK_TOP_MASK                      0x3800
21
 
#define FPU_C2                                          0x0400
22
 
#define FPU_C1                                          0x0200
23
 
#define FPU_C0                                          0x0100
24
 
#define FPU_ERROR_SUMMARY                       0x0080
25
 
#define FPU_STACK_FAULT                         0x0040
26
 
#define FPU_EXCEPTION_PRECISION         0x0020
27
 
#define FPU_EXCEPTION_UNDERFLOW         0x0010
28
 
#define FPU_EXCEPTION_OVERFLOW          0x0008
29
 
#define FPU_EXCEPTION_ZERO_DIVIDE       0x0004
30
 
#define FPU_EXCEPTION_DENORMAL_OP       0x0002
31
 
#define FPU_EXCEPTION_INVALID_OP        0x0001
32
 
 
33
 
INLINE void FPU_PUSH(i386_state *cpustate, X87_REG value)
34
 
{
35
 
        cpustate->fpu_top--;
36
 
        if (cpustate->fpu_top < 0)
37
 
        {
38
 
                cpustate->fpu_top = 7;
39
 
        }
40
 
 
41
 
        cpustate->fpu_reg[cpustate->fpu_top] = value;
42
 
}
43
 
 
44
 
INLINE X87_REG FPU_POP(i386_state *cpustate)
45
 
{
46
 
        X87_REG value = cpustate->fpu_reg[cpustate->fpu_top];
47
 
 
48
 
        cpustate->fpu_tag_word |= 3 << (cpustate->fpu_top * 2);         // set FPU register tag to 3 (empty)
49
 
 
50
 
        cpustate->fpu_top++;
51
 
        if (cpustate->fpu_top > 7)
52
 
        {
53
 
                cpustate->fpu_top = 0;
54
 
        }
55
 
 
56
 
        return value;
57
 
}
58
 
 
59
 
static void I386OP(fpu_group_d8)(i386_state *cpustate)          // Opcode 0xd8
60
 
{
61
 
        UINT8 modrm = FETCH(cpustate);
62
 
        if (modrm < 0xc0)
63
 
        {
64
 
                UINT32 ea = GetEA(cpustate,modrm);
65
 
 
66
 
                switch ((modrm >> 3) & 0x7)
67
 
                {
68
 
                case 6:  // FDIV
69
 
                        UINT32 src = READ32(cpustate,ea);
70
 
                        if(src == 0)
71
 
                                fatalerror("FPU: Unimplemented Divide-by-zero exception at %08X.\n", cpustate->pc-2);
72
 
                        ST(0).f = ST(0).f / src;
73
 
                        CYCLES(cpustate,1);             // TODO
74
 
                        break;
75
 
                }
76
 
        }
77
 
        else
78
 
        {
79
 
                fatalerror("I386: FPU Op D8 %02X at %08X", modrm, cpustate->pc-2);
80
 
        }
81
 
}
82
 
 
83
 
static void I386OP(fpu_group_d9)(i386_state *cpustate)          // Opcode 0xd9
84
 
{
85
 
        UINT8 modrm = FETCH(cpustate);
86
 
 
87
 
        if (modrm < 0xc0)
88
 
        {
89
 
                UINT32 ea = GetEA(cpustate,modrm);
90
 
 
91
 
                switch ((modrm >> 3) & 0x7)
92
 
                {
93
 
                        case 5:                 // FLDCW
94
 
                        {
95
 
                                cpustate->fpu_control_word = READ16(cpustate,ea);
96
 
                                CYCLES(cpustate,1);             // TODO
97
 
                                break;
98
 
                        }
99
 
 
100
 
                        case 6:                 // FSTENV
101
 
                        {  // TODO: 32-bit operand size
102
 
                                WRITE16(cpustate,ea, cpustate->fpu_control_word);
103
 
                                WRITE16(cpustate,ea+2, cpustate->fpu_status_word);
104
 
                                WRITE16(cpustate,ea+4, cpustate->fpu_tag_word);
105
 
                                WRITE16(cpustate,ea+6, cpustate->fpu_inst_ptr & 0xffff);
106
 
                                WRITE16(cpustate,ea+8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
107
 
                                WRITE16(cpustate,ea+10, cpustate->fpu_data_ptr & 0xffff);
108
 
                                WRITE16(cpustate,ea+12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
109
 
                                CYCLES(cpustate,1);             // TODO
110
 
                                break;
111
 
                        }
112
 
 
113
 
                        case 7:                 // FSTCW
114
 
                        {
115
 
                                WRITE16(cpustate,ea, cpustate->fpu_control_word);
116
 
                                CYCLES(cpustate,1);             // TODO
117
 
                                break;
118
 
                        }
119
 
 
120
 
                        default:
121
 
                                fatalerror("I386: FPU Op D9 %02X at %08X", modrm, cpustate->pc-2);
122
 
                }
123
 
        }
124
 
        else
125
 
        {
126
 
                switch (modrm & 0x3f)
127
 
                {
128
 
                        // FLD
129
 
                        case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
130
 
                        {
131
 
                                X87_REG t = ST(modrm & 7);
132
 
                                FPU_PUSH(cpustate,t);
133
 
                                CYCLES(cpustate,1);             // TODO
134
 
                                break;
135
 
                        }
136
 
 
137
 
                        case 0x20:              // FCHS
138
 
                        {
139
 
                                ST(0).i ^= FPU_SIGN_BIT_DOUBLE;
140
 
                                CYCLES(cpustate,1);             // TODO
141
 
                                break;
142
 
                        }
143
 
 
144
 
                        case 0x28:              // FLD1
145
 
                        {
146
 
                                X87_REG t;
147
 
                                t.f = 1.0;
148
 
                                FPU_PUSH(cpustate,t);
149
 
                                CYCLES(cpustate,1);             // TODO
150
 
                                break;
151
 
                        }
152
 
 
153
 
                        case 0x2e:              // FLDZ
154
 
                        {
155
 
                                X87_REG t;
156
 
                                t.f = 0.0;
157
 
                                FPU_PUSH(cpustate,t);
158
 
                                CYCLES(cpustate,1);             // TODO
159
 
                                break;
160
 
                        }
161
 
                        default:
162
 
                                fatalerror("I386: FPU Op D9 %02X at %08X", modrm, cpustate->pc-2);
163
 
                }
164
 
        }
165
 
}
166
 
 
167
 
static void I386OP(fpu_group_da)(i386_state *cpustate)          // Opcode 0xda
168
 
{
169
 
        UINT8 modrm = FETCH(cpustate);
170
 
        fatalerror("I386: FPU Op DA %02X at %08X", modrm, cpustate->pc-2);
171
 
}
172
 
 
173
 
static void I386OP(fpu_group_db)(i386_state *cpustate)          // Opcode 0xdb
174
 
{
175
 
        UINT8 modrm = FETCH(cpustate);
176
 
 
177
 
        if (modrm < 0xc0)
178
 
        {
179
 
                fatalerror("I386: FPU Op DB %02X at %08X", modrm, cpustate->pc-2);
180
 
        }
181
 
        else
182
 
        {
183
 
                switch (modrm & 0x3f)
184
 
                {
185
 
                        case 0x23:              // FINIT
186
 
                        {
187
 
                                cpustate->fpu_control_word = 0x37f;
188
 
                                cpustate->fpu_status_word = 0;
189
 
                                cpustate->fpu_tag_word = 0xffff;
190
 
                                cpustate->fpu_data_ptr = 0;
191
 
                                cpustate->fpu_inst_ptr = 0;
192
 
                                cpustate->fpu_opcode = 0;
193
 
 
194
 
                                CYCLES(cpustate,1);             // TODO
195
 
                                break;
196
 
                        }
197
 
 
198
 
                        case 0x24:              // FSETPM (treated as nop on 387+)
199
 
                        {
200
 
                                CYCLES(cpustate,1);
201
 
                                break;
202
 
                        }
203
 
 
204
 
                        default:
205
 
                                fatalerror("I386: FPU Op DB %02X at %08X", modrm, cpustate->pc-2);
206
 
                }
207
 
        }
208
 
}
209
 
 
210
 
static void I386OP(fpu_group_dc)(i386_state *cpustate)          // Opcode 0xdc
211
 
{
212
 
        UINT8 modrm = FETCH(cpustate);
213
 
 
214
 
        if (modrm < 0xc0)
215
 
        {
216
 
                //UINT32 ea = GetEA(cpustate,modrm);
217
 
 
218
 
                switch ((modrm >> 3) & 0x7)
219
 
                {
220
 
                        default:
221
 
                                fatalerror("I386: FPU Op DC %02X at %08X", modrm, cpustate->pc-2);
222
 
                }
223
 
        }
224
 
        else
225
 
        {
226
 
                switch (modrm & 0x3f)
227
 
                {
228
 
                        case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
229
 
                        {
230
 
                                // FDIVR
231
 
                                if ((ST(modrm & 7).i & U64(0x7fffffffffffffff)) == 0)
232
 
                                {
233
 
                                        // set result as infinity if zero divide is masked
234
 
                                        if (cpustate->fpu_control_word & FPU_MASK_ZERO_DIVIDE)
235
 
                                        {
236
 
                                                ST(modrm & 7).i |= FPU_INFINITY_DOUBLE;
237
 
                                        }
238
 
                                }
239
 
                                else
240
 
                                {
241
 
                                        ST(modrm & 7).f = ST(0).f / ST(modrm & 7).f;
242
 
                                }
243
 
                                CYCLES(cpustate,1);             // TODO
244
 
                                break;
245
 
                        }
246
 
 
247
 
                        default:
248
 
                                fatalerror("I386: FPU Op DC %02X at %08X", modrm, cpustate->pc-2);
249
 
                }
250
 
        }
251
 
}
252
 
 
253
 
static void I386OP(fpu_group_dd)(i386_state *cpustate)          // Opcode 0xdd
254
 
{
255
 
        UINT8 modrm = FETCH(cpustate);
256
 
 
257
 
        if (modrm < 0xc0)
258
 
        {
259
 
                UINT32 ea = GetEA(cpustate,modrm);
260
 
 
261
 
                switch ((modrm >> 3) & 0x7)
262
 
                {
263
 
                        case 7:                 // FSTSW
264
 
                        {
265
 
                                WRITE16(cpustate,ea, (cpustate->fpu_status_word & ~FPU_STACK_TOP_MASK) | (cpustate->fpu_top << 10));
266
 
                                CYCLES(cpustate,1);             // TODO
267
 
                                break;
268
 
                        }
269
 
 
270
 
                        default:
271
 
                                fatalerror("I386: FPU Op DD %02X at %08X", modrm, cpustate->pc-2);
272
 
                }
273
 
        }
274
 
        else
275
 
        {
276
 
                switch (modrm & 0x3f)
277
 
                {
278
 
                        default:
279
 
                                fatalerror("I386: FPU Op DD %02X at %08X", modrm, cpustate->pc-2);
280
 
                }
281
 
        }
282
 
}
283
 
 
284
 
static void I386OP(fpu_group_de)(i386_state *cpustate)          // Opcode 0xde
285
 
{
286
 
        UINT8 modrm = FETCH(cpustate);
287
 
 
288
 
        if (modrm < 0xc0)
289
 
        {
290
 
        //  UINT32 ea = GetEA(cpustate,modrm);
291
 
 
292
 
                switch ((modrm >> 3) & 0x7)
293
 
                {
294
 
                        default:
295
 
                                fatalerror("I386: FPU Op DE %02X at %08X", modrm, cpustate->pc-2);
296
 
                }
297
 
        }
298
 
        else
299
 
        {
300
 
                switch (modrm & 0x3f)
301
 
                {
302
 
                        case 0x19:                      // FCOMPP
303
 
                        {
304
 
                                cpustate->fpu_status_word &= ~(FPU_C3 | FPU_C2 | FPU_C0);
305
 
                                if (ST(0).f > ST(1).f)
306
 
                                {
307
 
                                        // C3 = 0, C2 = 0, C0 = 0
308
 
                                }
309
 
                                else if (ST(0).f < ST(1).f)
310
 
                                {
311
 
                                        cpustate->fpu_status_word |= FPU_C0;
312
 
                                }
313
 
                                else if (ST(0).f == ST(1).f)
314
 
                                {
315
 
                                        cpustate->fpu_status_word |= FPU_C3;
316
 
                                }
317
 
                                else
318
 
                                {
319
 
                                        // unordered
320
 
                                        cpustate->fpu_status_word |= (FPU_C3 | FPU_C2 | FPU_C0);
321
 
                                }
322
 
                                FPU_POP(cpustate);
323
 
                                FPU_POP(cpustate);
324
 
                                CYCLES(cpustate,1);             // TODO
325
 
                                break;
326
 
                        }
327
 
 
328
 
                        // FDIVP
329
 
                        case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
330
 
                        {
331
 
                                if ((ST(0).i & U64(0x7fffffffffffffff)) == 0)
332
 
                                {
333
 
                                        // set result as infinity if zero divide is masked
334
 
                                        if (cpustate->fpu_control_word & FPU_MASK_ZERO_DIVIDE)
335
 
                                        {
336
 
                                                ST(modrm & 7).i |= FPU_INFINITY_DOUBLE;
337
 
                                        }
338
 
                                }
339
 
                                else
340
 
                                {
341
 
                                        ST(modrm & 7).f = ST(modrm & 7).f / ST(0).f;
342
 
                                }
343
 
                                FPU_POP(cpustate);
344
 
                                CYCLES(cpustate,1);             // TODO
345
 
                                break;
346
 
                        }
347
 
 
348
 
                        default:
349
 
                                fatalerror("I386: FPU Op DE %02X at %08X", modrm, cpustate->pc-2);
350
 
                }
351
 
        }
352
 
}
353
 
 
354
 
static void I386OP(fpu_group_df)(i386_state *cpustate)          // Opcode 0xdf
355
 
{
356
 
        UINT8 modrm = FETCH(cpustate);
357
 
 
358
 
        if (modrm < 0xc0)
359
 
        {
360
 
        //  UINT32 ea = GetEA(cpustate,modrm);
361
 
 
362
 
                switch ((modrm >> 3) & 0x7)
363
 
                {
364
 
                        default:
365
 
                                fatalerror("I386: FPU Op DF %02X at %08X", modrm, cpustate->pc-2);
366
 
                }
367
 
        }
368
 
        else
369
 
        {
370
 
                switch (modrm & 0x3f)
371
 
                {
372
 
                        case 0x20:                      // FSTSW AX
373
 
                        {
374
 
                                REG16(AX) = (cpustate->fpu_status_word & ~FPU_STACK_TOP_MASK) | (cpustate->fpu_top << 10);
375
 
                                CYCLES(cpustate,1);             // TODO
376
 
                                break;
377
 
                        }
378
 
 
379
 
                        default:
380
 
                                fatalerror("I386: FPU Op DF %02X at %08X", modrm, cpustate->pc-2);
381
 
                }
382
 
        }
383
 
}