~mirabilos/aranym/trunk

« back to all changes in this revision

Viewing changes to src/uae_cpu/fpu_x86.cpp

  • Committer: atarist
  • Date: 2001-03-19 22:54:37 UTC
  • Revision ID: atarist-20010319225437-6qz4u4srm32pibqb
Initial revision

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  fpu_x86.cpp - 68881/68040 fpu code for x86/Windows an Linux/x86.
 
3
 *
 
4
 *  Basilisk II (C) 1997-1999 Christian Bauer
 
5
 *
 
6
 *  MC68881/68040 fpu emulation
 
7
 *
 
8
 *  Based on UAE FPU, original copyright 1996 Herman ten Brugge,
 
9
 *  rewritten for x86 by Lauri Pesonen 1999-2000,
 
10
 *  accomodated to GCC's Extended Asm syntax by Gwenole Beauchesne 2000.
 
11
 *
 
12
 *  This program is free software; you can redistribute it and/or modify
 
13
 *  it under the terms of the GNU General Public License as published by
 
14
 *  the Free Software Foundation; either version 2 of the License, or
 
15
 *  (at your option) any later version.
 
16
 *
 
17
 *  This program is distributed in the hope that it will be useful,
 
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 *  GNU General Public License for more details.
 
21
 *
 
22
 *  You should have received a copy of the GNU General Public License
 
23
 *  along with this program; if not, write to the Free Software
 
24
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
25
 *
 
26
 *
 
27
 *      Interface
 
28
 *              Almost the same as original. Please see the comments in "fpu.h".
 
29
 *              Call fpu_init() and fpu_set_integral_fpu() before cpu thread starts up.
 
30
 *
 
31
 *
 
32
 *      Why assembly?
 
33
 *              The reason is not really speed, but to get infinities,
 
34
 *              NANs and flags finally working.
 
35
 *
 
36
 *
 
37
 *      How to maintain Mac and x86 FPU flags -- plan B
 
38
 *
 
39
 *      regs.piar is not updated.
 
40
 *
 
41
 *      regs.fpcr always contains the real 68881/68040 control word.
 
42
 *
 
43
 *      regs.fpsr is not kept up-to-date, for efficiency reasons.
 
44
 *      Most of the FPU commands update this in a way or another,
 
45
 *      but it is not read nearly that often. Therefore, three host-specific
 
46
 *      words hold the status byte and exception byte ("sw"), accrued exception
 
47
 *      byte ("sw_accrued") and the quotient byte ("sw_quotient"), as explained below.
 
48
 *
 
49
 *      CONDITION CODE - QUOTIENT - EXCEPTION STATUS - ACCRUED EXCEPTION
 
50
 *              CONDITION CODE (N,Z,I,NAN)
 
51
 *                      updated after each opcode, if needed.
 
52
 *                      x86 assembly opcodes call FXAM and store the status word to "sw".
 
53
 *                      When regs.fpsr is actually used, the value of "sw" is translated.
 
54
 *              QUOTIENT BYTE
 
55
 *                      Updated by frem, fmod, frestore(null frame)
 
56
 *                      Stored in "sw_quotient" in correct bit position, combined when
 
57
 *                      regs.fpsr is actually used.
 
58
 *              EXCEPTION STATUS (BSUN,SNAN,OPERR,OVFL,UNFL,DZ,INEX2,INEX1)
 
59
 *                      updated after each opcode, if needed.
 
60
 *                      Saved in x86 form in "sw".
 
61
 *                      When regs.fpsr is actually used, the value of "sw" is translated.
 
62
 *                      Only fcc_op can set BSUN
 
63
 *              ACCRUED EXCEPTION (ACCR_IOP,ACCR_OVFL,ACCR_UNFL,ACCR_DZ,ACCR_INEX)
 
64
 *                      updated after each opcode, if needed.
 
65
 *                      Logically OR'ed in x86 form to "sw_accrued".
 
66
 *                      When regs.fpsr is actually used, the value of "sw_accrued" is translated.
 
67
 *              
 
68
 *              When "sw" and "sw_accrued" are stored, all pending x86 FPU
 
69
 *              exceptions are cleared, if there are any.
 
70
 *
 
71
 *              Writing to "regs.fpsr" reverse-maps to x86 status/exception values
 
72
 *              and stores the values in "sw", "sw_accrued" and "sw_quotient".
 
73
 *
 
74
 *              So, "sw" and "sw_accrued" are not in correct bit positions
 
75
 *              and have x86 values, but "sw_quotient" is at correct position.
 
76
 *
 
77
 *              Note that it does not matter that the reverse-mapping is not exact
 
78
 *              (both SW_IE and SW_DE are mapped to ACCR_IOP, but ACCR_IOP maps to SW_IE
 
79
 *              only), the MacOS always sees the correct exception bits.
 
80
 *
 
81
 *              Also note the usage of the fake BSUN flag SW_FAKE_BSUN. If you change the
 
82
 *              x86 FPU code, you must make sure that you don't generate any FPU stack faults.
 
83
 *
 
84
 *
 
85
 *      x86 co-processor initialization:
 
86
 *
 
87
 *      Bit  Code   Use
 
88
 *       0   IM     Invalid operation exception mask     1    Disabled
 
89
 *       1   DM     Denormalized operand exception mask  1    Disabled
 
90
 *       2   ZM     Zerodivide exception mask            1    Disabled
 
91
 *       3   OM     Overflow exception mask              1    Disabled
 
92
 *       4   UM     Underflow exception mask             1    Disabled
 
93
 *       5   PM     Precision exception mask             1    Disabled
 
94
 *       6   -      -                                    -    -
 
95
 *       7   IEM    Interrupt enable mask                0    Enabled
 
96
 *       8   PC     Precision control\                   1  - 64 bits
 
97
 *       9   PC     Precision control/                   1  /
 
98
 *      10   RC     Rounding control\                    0  - Nearest even
 
99
 *      11   RC     Rounding control/                    0  /
 
100
 *      12   IC     Infinity control                     1    Affine
 
101
 *      13   -      -                                    -    -
 
102
 *      14   -      -                                    -    -
 
103
 *      15   -      -                                    -    -
 
104
 *
 
105
 *
 
106
 *  TODO:
 
107
 *    - Exceptions are not implemented.
 
108
 *    - All tbyte variables should be aligned to 16-byte boundaries.
 
109
 *                (for best efficiency).
 
110
 *              - FTRAPcc code looks like broken.
 
111
 *              - If USE_3_BIT_QUOTIENT is 0, exceptions should be checked after
 
112
 *                      float -> int rounding (frem,fmod).
 
113
 *              - The speed can be greatly improved. Do this only after you are sure
 
114
 *                      that there are no major bugs.
 
115
 *              - Support for big-endian byte order (but all assembly code needs to
 
116
 *                      be rewritten anyway)
 
117
 *                      I have some non-portable code like *((uae_u16 *)&m68k_dreg(regs, reg)) = newv;
 
118
 *                      Sorry about that, you need to change these. I could do it myself, but better
 
119
 *                      not, I would have no way to test them out.
 
120
 *                      I tried to mark all spots with a comment TODO_BIGENDIAN.
 
121
 *              - to_double() may need renormalization code. Or then again, maybe not.
 
122
 *              - Signaling NANs should be handled better. The current mapping of
 
123
 *                      signaling nan exception to denormalized operand exception is only
 
124
 *                      based on the idea that the (possible) handler sees that "something
 
125
 *                      seriously wrong" and takes the same action. Should not really get (m)any
 
126
 *                      of those since normalization is handled on to_exten()
 
127
 *                      
 
128
 */
 
129
 
 
130
#include <math.h>
 
131
#include <stdio.h>
 
132
 
 
133
#include "sysdeps.h"
 
134
#include "memory.h"
 
135
#include "readcpu.h"
 
136
#include "newcpu.h"
 
137
#include "fpu_x86.h"
 
138
#include "fpu_x86_asm.h"
 
139
 
 
140
/* ---------------------------- Compatibility ---------------------------- */
 
141
 
 
142
#define BYTE            uint8
 
143
#define WORD            uint16
 
144
#define DWORD           uint32
 
145
#define _ASM            __asm__ __volatile__
 
146
#define min(a, b)       (((a) < (b)) ? (a) : (b))
 
147
 
 
148
/* ---------------------------- Configuration ---------------------------- */
 
149
 
 
150
/*
 
151
If USE_3_BIT_QUOTIENT is set to 1, FREM and FMOD use a faster version
 
152
with only 3 quotient bits (those provided by the x86 FPU). If set to 0,
 
153
they calculate the same 7 bits that m68k does. It seems (as for now) that
 
154
3 bits suffice for all Mac programs I have tried.
 
155
 
 
156
If you decide that you need all 7 bits (USE_3_BIT_QUOTIENT is 0),
 
157
consider checking the host exception flags after FISTP (search for
 
158
"TODO:Quotient". The result may be too large to fit into a dword.
 
159
*/
 
160
/*
 
161
gb-- I only tested the following configurations:
 
162
                USE_3_BIT_QUOTIENT                      1 -- still changes to apply if no 3-bit quotient
 
163
                DEBUG                                           1 or 0
 
164
                USE_CONSISTENCY_CHECKING        0
 
165
                I3_ON_ILLEGAL_FPU_OP            0 -- and this won't change
 
166
                I3_ON_FTRAPCC                           0 -- and this won't change
 
167
*/
 
168
#define USE_3_BIT_QUOTIENT                      1
 
169
 
 
170
#define DEBUG                                           0
 
171
#define USE_CONSISTENCY_CHECKING        0
 
172
 
 
173
#define I3_ON_ILLEGAL_FPU_OP            0
 
174
#define I3_ON_FTRAPCC                           0
 
175
 
 
176
 
 
177
/* ---------------------------- Registers ---------------------------- */
 
178
 
 
179
// "regs.fp" is not used. regs.fpcr, regs.fpsr and regs.fpiar are used.
 
180
 
 
181
typedef BYTE *float80;
 
182
typedef BYTE float80_s[10];
 
183
typedef BYTE float80_s_aligned[16];
 
184
 
 
185
static float80_s_aligned fp_reg[8];
 
186
 
 
187
 
 
188
/* ---------------------------- Debugging ---------------------------- */
 
189
 
 
190
#if DEBUG
 
191
//#pragma optimize("",off)
 
192
#endif
 
193
 
 
194
// extern "C" {int debugging_fpp = 0;}
 
195
 
 
196
#include "debug.h"
 
197
 
 
198
#if DEBUG
 
199
#undef __inline__
 
200
#define __inline__
 
201
//#undef D
 
202
//#define D(x) { if(debugging_fpp) { (x); } }
 
203
 
 
204
static void dump_first_bytes_buf( char *b, BYTE *buf, int32 actual )
 
205
{
 
206
        char bb[10];
 
207
        int32 i, bytes = min(actual,100);
 
208
 
 
209
        *b = 0;
 
210
        for (i=0; i<bytes; i++) {
 
211
                sprintf( bb, "%02x ", (uint32)buf[i] );
 
212
                strcat( b, bb );
 
213
        }
 
214
        strcat((char*)b,"\r\n");
 
215
}
 
216
 
 
217
static void dump_first_bytes( BYTE *buf, int32 actual )
 
218
{
 
219
        char msg[256];
 
220
        dump_first_bytes_buf( msg, buf, actual );
 
221
        D(bug("%s\n", msg));
 
222
}
 
223
 
 
224
#define CONDRET(s,x) D(bug("fpp_cond %s = %d\r\n",s,(uint32)(x))); return (x)
 
225
static char * etos( float80 e ) REGPARAM;
 
226
static char * etos( float80 e )
 
227
{
 
228
        static char _s[10][30];
 
229
        static int _ix = 0;
 
230
        float f;
 
231
 
 
232
/*      _asm {
 
233
                MOV                     EDI, [e]
 
234
                FLD     TBYTE PTR [EDI]
 
235
    FSTP    DWORD PTR f
 
236
        } */
 
237
        
 
238
        _ASM(   "fldt   %1\n"
 
239
                        "fstp   %0\n"
 
240
                :       "=m" (f)
 
241
                :       "m" (*e)
 
242
                );
 
243
        
 
244
        if(++_ix >= 10) _ix = 0;
 
245
 
 
246
        sprintf( _s[_ix], "%.04f", (float)f );
 
247
        return( _s[_ix] );
 
248
}
 
249
static void dump_fp_regs( char *s )
 
250
{
 
251
        char b[512];
 
252
 
 
253
        sprintf(
 
254
                b,
 
255
                "%s: %s, %s, %s, %s, %s, %s, %s, %s\r\n",
 
256
                s,
 
257
                etos(fp_reg[0]),
 
258
                etos(fp_reg[1]),
 
259
                etos(fp_reg[2]),
 
260
                etos(fp_reg[3]),
 
261
                etos(fp_reg[4]),
 
262
                etos(fp_reg[5]),
 
263
                etos(fp_reg[6]),
 
264
                etos(fp_reg[7])
 
265
        );
 
266
        D(bug((char*)b));
 
267
}
 
268
 
 
269
#else
 
270
#define CONDRET(s,x) return (x)
 
271
#define dump_fp_regs(s) {}
 
272
#endif
 
273
 
 
274
 
 
275
/* ---------------------------- FPU consistency ---------------------------- */
 
276
 
 
277
#if USE_CONSISTENCY_CHECKING
 
278
static uae_u16 checked_sw_atstart;
 
279
 
 
280
static void FPU_CONSISTENCY_CHECK_START()
 
281
{
 
282
/*      _asm {
 
283
          FNSTSW checked_sw_atstart
 
284
        } */
 
285
        _ASM("fnstsw %0" : "=m" (checked_sw_atstart));
 
286
}
 
287
 
 
288
static void FPU_CONSISTENCY_CHECK_STOP(char *name)
 
289
{
 
290
        uae_u16 checked_sw_atend;
 
291
//      _asm FNSTSW checked_sw_atend
 
292
        _ASM("fnstsw %0" : "=m" (checked_sw_attend));
 
293
        char msg[256];
 
294
 
 
295
        // Check for FPU stack overflows/underflows.
 
296
        if( (checked_sw_atend & 0x3800) != (checked_sw_atstart & 0x3800) ) {
 
297
                wsprintf(
 
298
                        msg, 
 
299
                        "FPU stack leak at %s, %X, %X\r\n", 
 
300
                        name,
 
301
                        (int)(checked_sw_atstart & 0x3800) >> 11,
 
302
                        (int)(checked_sw_atend & 0x3800) >> 11
 
303
                );
 
304
                OutputDebugString(msg);
 
305
        }
 
306
 
 
307
        // Observe status mapping.
 
308
        /*
 
309
        if(checked_sw_atstart != 0x400 || checked_sw_atend != 0x400) {
 
310
                wsprintf(
 
311
                        msg, "Op %s, sw before=%X, sw after=%X\r\n", 
 
312
                        name, (int)checked_sw_atstart, (int)checked_sw_atend
 
313
                );
 
314
                OutputDebugString(msg);
 
315
        }
 
316
        */
 
317
}
 
318
#else
 
319
#define FPU_CONSISTENCY_CHECK_START()
 
320
#define FPU_CONSISTENCY_CHECK_STOP(name)
 
321
#endif
 
322
 
 
323
 
 
324
/* ---------------------------- FPU type ---------------------------- */
 
325
 
 
326
static uae_u32 is_integral_68040_fpu = 0;
 
327
 
 
328
 
 
329
/* ---------------------------- Status byte ---------------------------- */
 
330
 
 
331
// Extend the SW_* codes
 
332
#define SW_FAKE_BSUN                    SW_SF
 
333
 
 
334
// Shorthand
 
335
#define SW_EXCEPTION_MASK (SW_ES|SW_SF|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE)
 
336
// #define SW_EXCEPTION_MASK (SW_SF|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE)
 
337
 
 
338
// Map x86 FXAM codes -> m68k fpu status byte
 
339
#define SW_Z_I_NAN_MASK                 (SW_C0|SW_C2|SW_C3)
 
340
#define SW_Z                                    (SW_C3)
 
341
#define SW_I                                    (SW_C0|SW_C2)
 
342
#define SW_NAN                                  (SW_C0)
 
343
#define SW_FINITE                               (SW_C2)
 
344
#define SW_EMPTY_REGISTER               (SW_C0|SW_C3)
 
345
#define SW_DENORMAL                             (SW_C2|SW_C3)
 
346
#define SW_UNSUPPORTED                  (0)
 
347
#define SW_N                                    (SW_C1)
 
348
 
 
349
// Initial state after boot, reset and frestore(null frame)
 
350
#define SW_INITIAL                              SW_FINITE
 
351
 
 
352
// These hold the contents of the fpsr, in Intel values.
 
353
static DWORD sw = SW_INITIAL;
 
354
static DWORD sw_accrued = 0;
 
355
static DWORD sw_quotient = 0;
 
356
 
 
357
 
 
358
/* ---------------------------- Control word ---------------------------- */
 
359
 
 
360
// Initial state after boot, reset and frestore(null frame)
 
361
#define CW_INITIAL      (CW_RESET|CW_X|CW_PC_EXTENDED|CW_RC_NEAR|CW_PM|CW_UM|CW_OM|CW_ZM|CW_DM|CW_IM)
 
362
 
 
363
static WORD cw = CW_INITIAL; 
 
364
 
 
365
 
 
366
/* ---------------------------- FMOVECR constants ---------------------------- */
 
367
 
 
368
static float80_s
 
369
        // Suported by x86 FPU
 
370
        const_pi,
 
371
        const_lg2,
 
372
        const_l2e,
 
373
        const_z,
 
374
        const_ln2,
 
375
        const_1,
 
376
 
 
377
        // Not suported by x86 FPU
 
378
        const_e,
 
379
        const_log_10_e,
 
380
        const_ln_10,
 
381
        const_1e1,
 
382
        const_1e2,
 
383
        const_1e4,
 
384
        const_1e8,
 
385
        const_1e16,
 
386
        const_1e32,
 
387
        const_1e64,
 
388
        const_1e128,
 
389
        const_1e256,
 
390
        const_1e512,
 
391
        const_1e1024,
 
392
        const_1e2048,
 
393
        const_1e4096;
 
394
 
 
395
 
 
396
/* ---------------------------- Saved host FPU state ---------------------------- */
 
397
 
 
398
static BYTE m_fpu_state_original[108]; // 90/94/108
 
399
 
 
400
 
 
401
/* ---------------------------- Map tables ---------------------------- */
 
402
 
 
403
typedef void REGPARAM2 fpuop_func( uae_u32, uae_u16 );
 
404
extern "C" { fpuop_func *fpufunctbl[65536]; }
 
405
 
 
406
// Control word -- need only one-way mapping
 
407
static const uae_u16 cw_rc_mac2host[] = {
 
408
        CW_RC_NEAR,
 
409
        CW_RC_ZERO,
 
410
        CW_RC_DOWN,
 
411
        CW_RC_UP
 
412
};
 
413
static const uae_u16 cw_pc_mac2host[] = {
 
414
        CW_PC_EXTENDED,
 
415
        CW_PC_SINGLE,
 
416
        CW_PC_DOUBLE,
 
417
        CW_PC_RESERVED
 
418
};
 
419
 
 
420
// Status word -- need two-way mapping
 
421
static uae_u32 sw_cond_host2mac[ 0x48 ];
 
422
static uae_u16 sw_cond_mac2host[ 16 ];
 
423
 
 
424
static uae_u32 exception_host2mac[ 0x80 ];
 
425
static uae_u32 exception_mac2host[ 0x100 ];
 
426
 
 
427
static uae_u32 accrued_exception_host2mac[ 0x40 ];
 
428
static uae_u32 accrued_exception_mac2host[ 0x20 ];
 
429
 
 
430
 
 
431
/* ---------------------------- Control functions ---------------------------- */
 
432
 
 
433
/*
 
434
        Exception enable byte is ignored, but the same value is returned
 
435
        that was previously set.
 
436
*/
 
437
static void __inline__ set_host_fpu_control_word()
 
438
{
 
439
        cw = (cw & ~(X86_ROUND_CONTROL_MASK|X86_PRECISION_CONTROL_MASK)) | 
 
440
                                cw_rc_mac2host[ (regs.fpcr & ROUND_CONTROL_MASK) >> 4 ] |
 
441
                                cw_pc_mac2host[ (regs.fpcr & PRECISION_CONTROL_MASK) >> 6 ];
 
442
        
 
443
        // Writing to control register is very slow (no register renaming on
 
444
        // ppro++, and most of all, it's one of those serializing commands).
 
445
/*      _asm {
 
446
    FLDCW   cw
 
447
        } */
 
448
        _ASM("fldcw %0" : : "m" (cw));
 
449
}
 
450
 
 
451
 
 
452
/* ---------------------------- Status functions ---------------------------- */
 
453
 
 
454
static void __inline__ SET_BSUN_ON_NAN()
 
455
{
 
456
        if( (sw & (SW_Z_I_NAN_MASK)) == SW_NAN ) {
 
457
                sw |= SW_FAKE_BSUN;
 
458
                sw_accrued |= SW_IE;
 
459
        }
 
460
}
 
461
 
 
462
static void __inline__ build_ex_status()
 
463
{
 
464
        if(sw & SW_EXCEPTION_MASK) {
 
465
//              _asm FNCLEX
 
466
                _ASM("fnclex");
 
467
                sw_accrued |= sw;
 
468
        }
 
469
}
 
470
 
 
471
static void __inline__ to_fpsr()
 
472
{
 
473
        regs.fpsr = 
 
474
                        sw_cond_host2mac[ (sw & 0x4700) >> 8 ] |
 
475
                        sw_quotient |
 
476
                        exception_host2mac[ sw & (SW_FAKE_BSUN|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE) ] |
 
477
                        accrued_exception_host2mac[ sw_accrued & (SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE) ]
 
478
                        ;
 
479
}
 
480
 
 
481
static void __inline__ from_fpsr()
 
482
{
 
483
        sw = 
 
484
                        sw_cond_mac2host[ (regs.fpsr & 0x0F000000) >> 24 ] |
 
485
                        exception_mac2host[ (regs.fpsr & 0x0000FF00) >> 8 ];
 
486
        sw_quotient = regs.fpsr & 0x00FF0000;
 
487
        sw_accrued =  accrued_exception_mac2host[ (regs.fpsr & 0xF8) >> 3 ];
 
488
}
 
489
 
 
490
 
 
491
// TODO_BIGENDIAN; all of these.
 
492
/* ---------------------------- Type functions ---------------------------- */
 
493
 
 
494
/*
 
495
When the FPU creates a NAN, the NAN always contains the same bit pattern
 
496
in the mantissa. All bits of the mantissa are ones for any precision.
 
497
When the user creates a NAN, any nonzero bit pattern can be stored in the mantissa.
 
498
*/
 
499
static __inline__ void MAKE_NAN(float80 p)
 
500
{
 
501
        // Make it non-signaling.
 
502
        memset( p, 0xFF, sizeof(float80_s)-1 );
 
503
        p[9] = 0x7F;
 
504
}
 
505
 
 
506
/*
 
507
For single- and double-precision infinities the fraction is a zero.
 
508
For extended-precision infinities, the mantissa�s MSB, the explicit
 
509
integer bit, can be either one or zero.
 
510
*/
 
511
static __inline__ uae_u32 IS_INFINITY(float80 p)
 
512
{
 
513
        if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) {
 
514
                if( *((uae_u32 *)p) == 0 &&
 
515
                                ( *((uae_u32 *)&p[4]) & 0x7FFFFFFF ) == 0 )
 
516
                {
 
517
                        return(1);
 
518
                }
 
519
        }
 
520
        return(0);
 
521
}
 
522
 
 
523
static __inline__ uae_u32 IS_NAN(float80 p)
 
524
{
 
525
        if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) {
 
526
                if( *((uae_u32 *)p) != 0 ||
 
527
                                ( *((uae_u32 *)&p[4]) & 0x7FFFFFFF ) != 0 )
 
528
                {
 
529
                        return(1);
 
530
                }
 
531
        }
 
532
        return(0);
 
533
}
 
534
 
 
535
static __inline__ uae_u32 IS_ZERO(float80 p)
 
536
{
 
537
        return *((uae_u32 *)p) == 0 &&
 
538
                                 *((uae_u32 *)&p[4]) == 0 &&
 
539
                                 ( *((uae_u16 *)&p[8]) & 0x7FFF ) == 0;
 
540
}
 
541
 
 
542
static __inline__ void MAKE_INF_POSITIVE(float80 p)
 
543
{
 
544
        memset( p, 0, sizeof(float80_s)-2 );
 
545
        *((uae_u16 *)&p[8]) = 0x7FFF;
 
546
}
 
547
 
 
548
static __inline__ void MAKE_INF_NEGATIVE(float80 p)
 
549
{
 
550
        memset( p, 0, sizeof(float80_s)-2 );
 
551
        *((uae_u16 *)&p[8]) = 0xFFFF;
 
552
}
 
553
 
 
554
static __inline__ void MAKE_ZERO_POSITIVE(float80 p)
 
555
{
 
556
        memset( p, 0, sizeof(float80_s) );
 
557
}
 
558
 
 
559
static __inline__ void MAKE_ZERO_NEGATIVE(float80 *p)
 
560
{
 
561
        memset( p, 0, sizeof(float80_s) );
 
562
        *((uae_u32 *)&p[4]) = 0x80000000;
 
563
}
 
564
 
 
565
static __inline__ uae_u32 IS_NEGATIVE(float80 p)
 
566
{
 
567
        return( (p[9] & 0x80) != 0 );
 
568
}
 
569
 
 
570
 
 
571
/* ---------------------------- Conversions ---------------------------- */
 
572
 
 
573
static void signed_to_extended( uae_s32 x, float80 f ) REGPARAM;
 
574
static void signed_to_extended( uae_s32 x, float80 f )
 
575
{
 
576
        FPU_CONSISTENCY_CHECK_START();
 
577
        
 
578
/*      _asm {
 
579
                MOV                     ESI, [f]
 
580
    FILD    DWORD PTR [x]
 
581
                FSTP    TBYTE PTR [ESI]
 
582
        } */
 
583
        
 
584
        _ASM(   "fildl  %1\n"
 
585
                        "fstpt  %0\n"
 
586
                :       "=m" (*f)
 
587
                :       "m" (x)
 
588
                );
 
589
        
 
590
        D(bug("signed_to_extended (%X) = %s\r\n",(int)x,etos(f)));
 
591
        FPU_CONSISTENCY_CHECK_STOP("signed_to_extended");
 
592
}
 
593
 
 
594
static uae_s32 extended_to_signed_32( float80 f ) REGPARAM;
 
595
static uae_s32 extended_to_signed_32( float80 f )
 
596
{
 
597
        FPU_CONSISTENCY_CHECK_START();
 
598
        uae_s32 tmp;
 
599
        WORD sw_temp;
 
600
        
 
601
/*      _asm {
 
602
                MOV                     EDI, [f]
 
603
                FLD     TBYTE PTR [EDI]
 
604
    FISTP   DWORD PTR tmp
 
605
    FNSTSW  sw_temp
 
606
        } */
 
607
 
 
608
        _ASM(   "fldt   %2\n"
 
609
                        "fistpl %0\n"
 
610
                        "fnstsw %1\n"
 
611
                :       "=m" (tmp), "=m" (sw_temp)
 
612
                :       "m" (*f)
 
613
                );
 
614
        
 
615
        if(sw_temp & SW_EXCEPTION_MASK) {
 
616
//              _asm FNCLEX
 
617
                _ASM("fnclex");
 
618
                if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR.
 
619
                        sw |= SW_IE;
 
620
                        sw_accrued |= SW_IE;
 
621
                        // Setting the value to zero might not be the right way to go,
 
622
                        // but I'll leave it like this for now.
 
623
                        tmp = 0;
 
624
                }
 
625
                if(sw_temp & SW_PE) {
 
626
                        sw |= SW_PE;
 
627
                        sw_accrued |= SW_PE;
 
628
                }
 
629
        }
 
630
 
 
631
        D(bug("extended_to_signed_32 (%s) = %X\r\n",etos(f),(int)tmp));
 
632
        FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_32");
 
633
        return tmp;
 
634
}
 
635
 
 
636
static uae_s16 extended_to_signed_16( float80 f ) REGPARAM;
 
637
static uae_s16 extended_to_signed_16( float80 f )
 
638
{
 
639
        FPU_CONSISTENCY_CHECK_START();
 
640
        uae_s16 tmp;
 
641
        WORD sw_temp;
 
642
 
 
643
/*      _asm {
 
644
                MOV                     EDI, [f]
 
645
                FLD     TBYTE PTR [EDI]
 
646
    FISTP   WORD PTR tmp
 
647
    FNSTSW  sw_temp
 
648
        } */
 
649
        
 
650
        _ASM(   "fldt   %2\n"
 
651
                        "fistp  %0\n"
 
652
                        "fnstsw %1\n"
 
653
                :       "=m" (tmp), "=m" (sw_temp)
 
654
                :       "m" (*f)
 
655
                );
 
656
 
 
657
        if(sw_temp & SW_EXCEPTION_MASK) {
 
658
//              _asm FNCLEX
 
659
                _ASM("fnclex");
 
660
                if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR.
 
661
                        sw |= SW_IE;
 
662
                        sw_accrued |= SW_IE;
 
663
                        tmp = 0;
 
664
                }
 
665
                if(sw_temp & SW_PE) {
 
666
                        sw |= SW_PE;
 
667
                        sw_accrued |= SW_PE;
 
668
                }
 
669
        }
 
670
 
 
671
        D(bug("extended_to_signed_16 (%s) = %X\r\n",etos(f),(int)tmp));
 
672
        FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_16");
 
673
        return tmp;
 
674
}
 
675
 
 
676
static uae_s8 extended_to_signed_8( float80 f ) REGPARAM;
 
677
static uae_s8 extended_to_signed_8( float80 f )
 
678
{
 
679
        FPU_CONSISTENCY_CHECK_START();
 
680
        uae_s16 tmp;
 
681
        WORD sw_temp;
 
682
        
 
683
/*      _asm {
 
684
                MOV                     EDI, [f]
 
685
                FLD     TBYTE PTR [EDI]
 
686
    FISTP   WORD PTR tmp
 
687
    FNSTSW  sw_temp
 
688
        } */
 
689
        
 
690
        _ASM(   "fldt   %2\n"
 
691
                        "fistp  %0\n"
 
692
                        "fnstsw %1\n"
 
693
                :       "=m" (tmp), "=m" (sw_temp)
 
694
                :       "m" (*f)
 
695
                );
 
696
 
 
697
        if(sw_temp & SW_EXCEPTION_MASK) {
 
698
//              _asm FNCLEX
 
699
                _ASM("fnclex");
 
700
                if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR.
 
701
                        sw |= SW_IE;
 
702
                        sw_accrued |= SW_IE;
 
703
                        tmp = 0;
 
704
                }
 
705
                if(sw_temp & SW_PE) {
 
706
                        sw |= SW_PE;
 
707
                        sw_accrued |= SW_PE;
 
708
                }
 
709
        }
 
710
 
 
711
        if(tmp > 127 || tmp < -128) { // OPERR
 
712
                sw |= SW_IE;
 
713
                sw_accrued |= SW_IE;
 
714
        }
 
715
 
 
716
        D(bug("extended_to_signed_8 (%s) = %X\r\n",etos(f),(int)tmp));
 
717
        FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_8");
 
718
        return (uae_s8)tmp;
 
719
}
 
720
 
 
721
static void double_to_extended( double x, float80 f ) REGPARAM;
 
722
static void double_to_extended( double x, float80 f )
 
723
{
 
724
        FPU_CONSISTENCY_CHECK_START();
 
725
 
 
726
/*      _asm {
 
727
                MOV                     EDI, [f]
 
728
    FLD     QWORD PTR [x]
 
729
                FSTP    TBYTE PTR [EDI]
 
730
        } */
 
731
        
 
732
        _ASM(   "fldl   %1\n"
 
733
                        "fstpt  %0\n"
 
734
                :       "=m" (*f)
 
735
                :       "m" (x)
 
736
                );
 
737
        
 
738
        FPU_CONSISTENCY_CHECK_STOP("double_to_extended");
 
739
}
 
740
 
 
741
static double extended_to_double( float80 f ) REGPARAM;
 
742
static double extended_to_double( float80 f )
 
743
{
 
744
        FPU_CONSISTENCY_CHECK_START();
 
745
        double result;
 
746
 
 
747
/*      _asm {
 
748
                MOV                     ESI, [f]
 
749
                FLD     TBYTE PTR [ESI]
 
750
    FSTP    QWORD PTR result
 
751
        } */
 
752
        
 
753
        _ASM(   "fldt   %1\n"
 
754
                        "fstpl  %0\n"
 
755
                :       "=m" (result)
 
756
                :       "m" (*f)
 
757
                );
 
758
        
 
759
        FPU_CONSISTENCY_CHECK_STOP("extended_to_double");
 
760
        return result;
 
761
}
 
762
 
 
763
static void to_single( uae_u32 src, float80 f ) REGPARAM;
 
764
static void to_single( uae_u32 src, float80 f )
 
765
{
 
766
        FPU_CONSISTENCY_CHECK_START();
 
767
/*      _asm {
 
768
                MOV                     ESI, [f]
 
769
    FLD     DWORD PTR src
 
770
                FSTP    TBYTE PTR [ESI]
 
771
        } */
 
772
        
 
773
        _ASM(   "flds   %1\n"
 
774
                        "fstpt  %0\n"
 
775
                :       "=m" (*f)
 
776
                :       "m" (src)
 
777
                );
 
778
 
 
779
        D(bug("to_single (%X) = %s\r\n",src,etos(f)));
 
780
        FPU_CONSISTENCY_CHECK_STOP("to_single");
 
781
}
 
782
 
 
783
// TODO_BIGENDIAN
 
784
static void to_exten_no_normalize( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, float80 f ) REGPARAM;
 
785
static void to_exten_no_normalize( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, float80 f )
 
786
{
 
787
        FPU_CONSISTENCY_CHECK_START();
 
788
        uae_u32 *p = (uae_u32 *)f;
 
789
 
 
790
        uae_u32 sign =  (wrd1 & 0x80000000) >> 16;
 
791
        uae_u32 exp  = (wrd1 >> 16) & 0x7fff;
 
792
        p[0] = wrd3;
 
793
        p[1] = wrd2;
 
794
        *((uae_u16 *)&p[2]) = (uae_u16)(sign | exp);
 
795
 
 
796
        D(bug("to_exten_no_normalize (%X,%X,%X) = %s\r\n",wrd1,wrd2,wrd3,etos(f)));
 
797
        FPU_CONSISTENCY_CHECK_STOP("to_exten_no_normalize");
 
798
}
 
799
 
 
800
static void to_exten( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, float80 f ) REGPARAM;
 
801
static void to_exten( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, float80 f )
 
802
{
 
803
        FPU_CONSISTENCY_CHECK_START();
 
804
        uae_u32 *p = (uae_u32 *)f;
 
805
 
 
806
        uae_u32 sign =  (wrd1 & 0x80000000) >> 16;
 
807
        uae_u32 exp  = (wrd1 >> 16) & 0x7fff;
 
808
 
 
809
        // The explicit integer bit is not set, must normalize.
 
810
        // Don't do it for zeroes, infinities or nans.
 
811
        if( (wrd2 & 0x80000000) == 0 && exp != 0 && exp != 0x7FFF ) {
 
812
                D(bug("to_exten denormalized mantissa (%X,%X,%X)\r\n",wrd1,wrd2,wrd3));
 
813
                if( wrd2 | wrd3 ) {
 
814
                        // mantissa, not fraction.
 
815
                        uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3;
 
816
                        while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) {
 
817
                                man <<= 1;
 
818
                                exp--;
 
819
                        }
 
820
                        wrd2 = (uae_u32)( man >> 32 );
 
821
                        wrd3 = (uae_u32)( man & 0xFFFFFFFF );
 
822
                        if( exp == 0 || (wrd2 & 0x80000000) == 0 ) {
 
823
                                // underflow
 
824
                                wrd2 = wrd3 = exp = 0;
 
825
                                sign = 0;
 
826
                        }
 
827
                } else {
 
828
                        if(exp != 0x7FFF && exp != 0) {
 
829
                                // Make a non-signaling nan.
 
830
                                exp = 0x7FFF;
 
831
                                sign = 0;
 
832
                                wrd2 = 0x80000000;
 
833
                        }
 
834
                }
 
835
        }
 
836
 
 
837
        p[0] = wrd3;
 
838
        p[1] = wrd2;
 
839
        *((uae_u16 *)&p[2]) = (uae_u16)(sign | exp);
 
840
 
 
841
        D(bug("to_exten (%X,%X,%X) = %s\r\n",wrd1,wrd2,wrd3,etos(f)));
 
842
        FPU_CONSISTENCY_CHECK_STOP("to_exten");
 
843
}
 
844
 
 
845
static void to_double( uae_u32 wrd1, uae_u32 wrd2, float80 f ) REGPARAM;
 
846
static void to_double( uae_u32 wrd1, uae_u32 wrd2, float80 f )
 
847
{
 
848
        FPU_CONSISTENCY_CHECK_START();
 
849
        
 
850
        // gb-- make GCC happy
 
851
        union {
 
852
                uae_u64 q;
 
853
                uae_u32 l[2];
 
854
        } src;
 
855
        
 
856
        // Should renormalize if needed. I'm not sure that x86 and m68k FPU's
 
857
        // do it the sama way. This should be extremely rare however.
 
858
        // to_exten() is often called with denormalized values.
 
859
 
 
860
        src.l[0] = wrd2;
 
861
        src.l[1] = wrd1;
 
862
 
 
863
/*      _asm {
 
864
    FLD     QWORD PTR src
 
865
                MOV                     EDI, [f]
 
866
                FSTP    TBYTE PTR [EDI]
 
867
        } */
 
868
        
 
869
        _ASM(   "fldl   %1\n"
 
870
                        "fstpt  %0\n"
 
871
                :       "=m" (*f)
 
872
                :       "m" (src.q)
 
873
                );
 
874
 
 
875
        D(bug("to_double (%X,%X) = %s\r\n",wrd1,wrd2,etos(f)));
 
876
        FPU_CONSISTENCY_CHECK_STOP("to_double");
 
877
}
 
878
 
 
879
static uae_u32 from_single( float80 f ) REGPARAM;
 
880
static uae_u32 from_single( float80 f )
 
881
{
 
882
        FPU_CONSISTENCY_CHECK_START();
 
883
        uae_u32 dest;
 
884
        WORD sw_temp;
 
885
 
 
886
/*      _asm {
 
887
                MOV                     EDI, [f]
 
888
    FLD     TBYTE PTR [EDI]
 
889
                FSTP    DWORD PTR dest
 
890
    FNSTSW  sw_temp
 
891
        } */
 
892
        
 
893
        _ASM(   "fldt   %2\n"
 
894
                        "fstps  %0\n"
 
895
                        "fnstsw %1\n"
 
896
                :       "=m" (dest), "=m" (sw_temp)
 
897
                :       "m" (*f)
 
898
                );
 
899
 
 
900
        sw_temp &= SW_EXCEPTION_MASK;
 
901
        if(sw_temp) {
 
902
//              _asm FNCLEX
 
903
                asm("fnclex");
 
904
                sw = (sw & ~SW_EXCEPTION_MASK) | sw_temp;
 
905
                sw_accrued |= sw_temp;
 
906
        }
 
907
 
 
908
        D(bug("from_single (%s) = %X\r\n",etos(f),dest));
 
909
        FPU_CONSISTENCY_CHECK_STOP("from_single");
 
910
        return dest;
 
911
}
 
912
 
 
913
// TODO_BIGENDIAN
 
914
static void from_exten( float80 f, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3 ) REGPARAM;
 
915
static void from_exten( float80 f, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3 )
 
916
{
 
917
        FPU_CONSISTENCY_CHECK_START();
 
918
        uae_u32 *p = (uae_u32 *)f;
 
919
        *wrd3 = p[0];
 
920
        *wrd2 = p[1];
 
921
        *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16;
 
922
 
 
923
        D(bug("from_exten (%s) = %X,%X,%X\r\n",etos(f),*wrd1,*wrd2,*wrd3));
 
924
        FPU_CONSISTENCY_CHECK_STOP("from_exten");
 
925
}
 
926
 
 
927
static void from_double( float80 f, uae_u32 *wrd1, uae_u32 *wrd2 ) REGPARAM;
 
928
static void from_double( float80 f, uae_u32 *wrd1, uae_u32 *wrd2 )
 
929
{
 
930
        FPU_CONSISTENCY_CHECK_START();
 
931
        uae_u32 dest[2];
 
932
        WORD sw_temp;
 
933
 
 
934
/*      _asm {
 
935
                MOV                     EDI, [f]
 
936
    FLD     TBYTE PTR [EDI]
 
937
                FSTP    QWORD PTR dest
 
938
    FNSTSW  sw_temp
 
939
        } */
 
940
        
 
941
        _ASM(   "fldt   %2\n"
 
942
                        "fstpl  %0\n"
 
943
                        "fnstsw %1\n"
 
944
                :       "=m" (dest), "=m" (sw_temp)
 
945
                :       "m" (*f)
 
946
                );
 
947
 
 
948
        sw_temp &= SW_EXCEPTION_MASK;
 
949
        if(sw_temp) {
 
950
//              _asm FNCLEX
 
951
                asm("fnclex");
 
952
                sw = (sw & ~SW_EXCEPTION_MASK) | sw_temp;
 
953
                sw_accrued |= sw_temp;
 
954
        }
 
955
 
 
956
        // TODO: There is a partial memory stall, nothing happens until FSTP retires.
 
957
        // On PIII, could use MMX move w/o any penalty.
 
958
        *wrd2 = dest[0];
 
959
        *wrd1 = dest[1];
 
960
 
 
961
        D(bug("from_double (%s) = %X,%X\r\n",etos(f),dest[1],dest[0]));
 
962
        FPU_CONSISTENCY_CHECK_STOP("from_double");
 
963
}
 
964
 
 
965
static void do_fmove( float80 dest, float80 src ) REGPARAM;
 
966
static void do_fmove( float80 dest, float80 src )
 
967
{
 
968
        FPU_CONSISTENCY_CHECK_START();
 
969
/*      _asm {
 
970
                MOV                     ESI, [src]
 
971
                MOV                     EDI, [dest]
 
972
    FLD     TBYTE PTR [ESI]
 
973
                FXAM
 
974
    FNSTSW  sw
 
975
                FSTP    TBYTE PTR [EDI]
 
976
        } */
 
977
        
 
978
        _ASM(   "fldt   %2\n"
 
979
                        "fxam   \n"
 
980
                        "fnstsw %0\n"
 
981
                        "fstpt  %1\n"
 
982
                :       "=m" (sw), "=m" (*dest)
 
983
                :       "m" (*src)
 
984
                );
 
985
        FPU_CONSISTENCY_CHECK_STOP("do_fmove");
 
986
}
 
987
 
 
988
/*
 
989
static void do_fmove_no_status( float80 dest, float80 src ) REGPARAM;
 
990
static void do_fmove_no_status( float80 dest, float80 src )
 
991
{
 
992
        FPU_CONSISTENCY_CHECK_START();
 
993
        _asm {
 
994
                MOV                     ESI, [src]
 
995
                MOV                     EDI, [dest]
 
996
    FLD     TBYTE PTR [ESI]
 
997
                FSTP    TBYTE PTR [EDI]
 
998
        }
 
999
        FPU_CONSISTENCY_CHECK_STOP("do_fmove_no_status");
 
1000
}
 
1001
*/
 
1002
 
 
1003
 
 
1004
/* ---------------------------- Operations ---------------------------- */
 
1005
 
 
1006
static void do_fint( float80 dest, float80 src ) REGPARAM;
 
1007
static void do_fint( float80 dest, float80 src )
 
1008
{
 
1009
        FPU_CONSISTENCY_CHECK_START();
 
1010
/*      _asm {
 
1011
                MOV                     ESI, [src]
 
1012
                MOV                     EDI, [dest]
 
1013
    FLD     TBYTE PTR [ESI]
 
1014
                FRNDINT
 
1015
                FXAM
 
1016
    FNSTSW  sw
 
1017
                FSTP    TBYTE PTR [EDI]
 
1018
        } */
 
1019
        _ASM(   "fldt   %2\n"
 
1020
                        "frndint\n"
 
1021
                        "fxam   \n"
 
1022
                        "fnstsw %0\n"
 
1023
                        "fstpt  %1\n"
 
1024
                :       "=m" (sw), "=m" (*dest)
 
1025
                :       "m" (*src)
 
1026
                );
 
1027
        if(sw & SW_EXCEPTION_MASK) {
 
1028
//              _asm FNCLEX
 
1029
                _ASM("fnclex");
 
1030
                sw &= ~(SW_EXCEPTION_MASK - SW_PE);
 
1031
                sw_accrued |= sw;
 
1032
        }
 
1033
        FPU_CONSISTENCY_CHECK_STOP("do_fint");
 
1034
}
 
1035
 
 
1036
static void do_fintrz( float80 dest, float80 src ) REGPARAM;
 
1037
static void do_fintrz( float80 dest, float80 src )
 
1038
{
 
1039
        FPU_CONSISTENCY_CHECK_START();
 
1040
        WORD cw_temp;
 
1041
 
 
1042
/*      _asm {
 
1043
                MOV                     ESI, [src]
 
1044
                MOV                     EDI, [dest]
 
1045
                FSTCW   cw_temp
 
1046
                and                     cw_temp, ~X86_ROUND_CONTROL_MASK
 
1047
                or                      cw_temp, CW_RC_ZERO
 
1048
    FLDCW   cw_temp
 
1049
    FLD     TBYTE PTR [ESI]
 
1050
                FRNDINT
 
1051
                FXAM
 
1052
    FNSTSW  sw
 
1053
    FLDCW   cw
 
1054
                FSTP    TBYTE PTR [EDI]
 
1055
        } */
 
1056
        
 
1057
        _ASM(   "fstcw  %0\n"
 
1058
                        "andl   $(~X86_ROUND_CONTROL_MASK), %0\n"
 
1059
                        "orl    $CW_RC_ZERO, %0\n"
 
1060
                        "fldcw  %0\n"
 
1061
                        "fldt   %3\n"
 
1062
                        "frndint\n"
 
1063
                        "fxam   \n"
 
1064
                        "fnstsw %1\n"
 
1065
                        "fldcw  %4\n"
 
1066
                        "fstpt  %2\n"
 
1067
                :       "+m" (cw_temp), "=m" (sw), "=m" (*dest)
 
1068
                :       "m" (*src), "m" (cw)
 
1069
                );
 
1070
        
 
1071
        if(sw & SW_EXCEPTION_MASK) {
 
1072
//              _asm FNCLEX
 
1073
                _ASM("fnclex");
 
1074
                sw &= ~(SW_EXCEPTION_MASK - SW_PE);
 
1075
                sw_accrued |= sw;
 
1076
        }
 
1077
        FPU_CONSISTENCY_CHECK_STOP("do_fintrz");
 
1078
}
 
1079
 
 
1080
static void do_fsqrt( float80 dest, float80 src ) REGPARAM;
 
1081
static void do_fsqrt( float80 dest, float80 src )
 
1082
{
 
1083
        FPU_CONSISTENCY_CHECK_START();
 
1084
/*      _asm {
 
1085
                MOV                     ESI, [src]
 
1086
                MOV                     EDI, [dest]
 
1087
    FLD     TBYTE PTR [ESI]
 
1088
                FSQRT
 
1089
                FXAM
 
1090
    FNSTSW  sw
 
1091
                FSTP    TBYTE PTR [EDI]
 
1092
        } */
 
1093
        
 
1094
        _ASM(   "fldt   %2\n"
 
1095
                        "fsqrt  \n"
 
1096
                        "fxam   \n"
 
1097
                        "fnstsw %0\n"
 
1098
                        "fstpt  %1\n"
 
1099
                :       "=m" (sw), "=m" (*dest)
 
1100
                :       "m" (*src)
 
1101
                );
 
1102
        
 
1103
        if(sw & SW_EXCEPTION_MASK) {
 
1104
//              _asm FNCLEX
 
1105
                _ASM("fnclex");
 
1106
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE);
 
1107
                sw_accrued |= sw;
 
1108
        }
 
1109
        FPU_CONSISTENCY_CHECK_STOP("do_fsqrt");
 
1110
}
 
1111
 
 
1112
static void do_ftst( float80 src ) REGPARAM;
 
1113
static void do_ftst( float80 src )
 
1114
{
 
1115
        FPU_CONSISTENCY_CHECK_START();
 
1116
/*      _asm {
 
1117
                MOV                     ESI, [src]
 
1118
    FLD     TBYTE PTR [ESI]
 
1119
                FXAM
 
1120
    FNSTSW  sw
 
1121
                FSTP    ST(0)
 
1122
        } */
 
1123
        
 
1124
        _ASM(   "fldt   %1\n"
 
1125
                        "fxam   \n"
 
1126
                        "fnstsw %0\n"
 
1127
                        "fstp   %%st(0)\n"
 
1128
                :       "=m" (sw)
 
1129
                :       "m" (*src)
 
1130
                );
 
1131
        
 
1132
        if(sw & SW_EXCEPTION_MASK) {
 
1133
//              _asm FNCLEX
 
1134
                _ASM("fnclex");
 
1135
                sw &= ~SW_EXCEPTION_MASK;
 
1136
        }
 
1137
        FPU_CONSISTENCY_CHECK_STOP("do_ftst");
 
1138
}
 
1139
 
 
1140
// These functions are calculated in 53 bits accuracy only.
 
1141
// Exception checking is not complete.
 
1142
static void do_fsinh( float80 dest, float80 src ) REGPARAM;
 
1143
static void do_fsinh( float80 dest, float80 src )
 
1144
{
 
1145
        FPU_CONSISTENCY_CHECK_START();
 
1146
        double x, y;
 
1147
        x = extended_to_double( src );
 
1148
        y = sinh(x);
 
1149
        double_to_extended( y, dest );
 
1150
        do_ftst( dest );
 
1151
        FPU_CONSISTENCY_CHECK_STOP("do_fsinh");
 
1152
}
 
1153
 
 
1154
static void do_flognp1( float80 dest, float80 src ) REGPARAM;
 
1155
static void do_flognp1( float80 dest, float80 src )
 
1156
{
 
1157
        FPU_CONSISTENCY_CHECK_START();
 
1158
        double x, y;
 
1159
        x = extended_to_double( src );
 
1160
        y = log (x + 1.0);
 
1161
        double_to_extended( y, dest );
 
1162
        do_ftst( dest );
 
1163
        FPU_CONSISTENCY_CHECK_STOP("do_flognp1");
 
1164
}
 
1165
 
 
1166
static void do_fetoxm1( float80 dest, float80 src ) REGPARAM;
 
1167
static void do_fetoxm1( float80 dest, float80 src )
 
1168
{
 
1169
        FPU_CONSISTENCY_CHECK_START();
 
1170
        double x, y;
 
1171
        x = extended_to_double( src );
 
1172
        y = exp (x) - 1.0;
 
1173
        double_to_extended( y, dest );
 
1174
        do_ftst( dest );
 
1175
        FPU_CONSISTENCY_CHECK_STOP("do_fetoxm1");
 
1176
}
 
1177
 
 
1178
static void do_ftanh( float80 dest, float80 src ) REGPARAM;
 
1179
static void do_ftanh( float80 dest, float80 src )
 
1180
{
 
1181
        FPU_CONSISTENCY_CHECK_START();
 
1182
        double x, y;
 
1183
        x = extended_to_double( src );
 
1184
        y = tanh (x);
 
1185
        double_to_extended( y, dest );
 
1186
        do_ftst( dest );
 
1187
        FPU_CONSISTENCY_CHECK_STOP("do_ftanh");
 
1188
}
 
1189
 
 
1190
static void do_fatan( float80 dest, float80 src ) REGPARAM;
 
1191
static void do_fatan( float80 dest, float80 src )
 
1192
{
 
1193
        FPU_CONSISTENCY_CHECK_START();
 
1194
        double x, y;
 
1195
        x = extended_to_double( src );
 
1196
        y = atan (x);
 
1197
        double_to_extended( y, dest );
 
1198
        do_ftst( dest );
 
1199
        FPU_CONSISTENCY_CHECK_STOP("do_fatan");
 
1200
}
 
1201
 
 
1202
static void do_fasin( float80 dest, float80 src ) REGPARAM;
 
1203
static void do_fasin( float80 dest, float80 src )
 
1204
{
 
1205
        FPU_CONSISTENCY_CHECK_START();
 
1206
        double x, y;
 
1207
        x = extended_to_double( src );
 
1208
        y = asin (x);
 
1209
        double_to_extended( y, dest );
 
1210
        do_ftst( dest );
 
1211
        FPU_CONSISTENCY_CHECK_STOP("do_fasin");
 
1212
}
 
1213
 
 
1214
static void do_fatanh( float80 dest, float80 src ) REGPARAM;
 
1215
static void do_fatanh( float80 dest, float80 src )
 
1216
{
 
1217
        FPU_CONSISTENCY_CHECK_START();
 
1218
        double x, y;
 
1219
        x = extended_to_double( src );
 
1220
        y = log ((1 + x) / (1 - x)) / 2;
 
1221
        double_to_extended( y, dest );
 
1222
        do_ftst( dest );
 
1223
        FPU_CONSISTENCY_CHECK_STOP("do_fatanh");
 
1224
}
 
1225
 
 
1226
static void do_fetox( float80 dest, float80 src ) REGPARAM;
 
1227
static void do_fetox( float80 dest, float80 src )
 
1228
{
 
1229
        FPU_CONSISTENCY_CHECK_START();
 
1230
        double x, y;
 
1231
        x = extended_to_double( src );
 
1232
        y = exp (x);
 
1233
        double_to_extended( y, dest );
 
1234
        do_ftst( dest );
 
1235
        FPU_CONSISTENCY_CHECK_STOP("do_fetox");
 
1236
}
 
1237
 
 
1238
static void do_ftwotox( float80 dest, float80 src ) REGPARAM;
 
1239
static void do_ftwotox( float80 dest, float80 src )
 
1240
{
 
1241
        FPU_CONSISTENCY_CHECK_START();
 
1242
        double x, y;
 
1243
        x = extended_to_double( src );
 
1244
        y = pow(2.0, x);
 
1245
        double_to_extended( y, dest );
 
1246
        do_ftst( dest );
 
1247
        FPU_CONSISTENCY_CHECK_STOP("do_ftwotox");
 
1248
}
 
1249
 
 
1250
static void do_ftentox( float80 dest, float80 src ) REGPARAM;
 
1251
static void do_ftentox( float80 dest, float80 src )
 
1252
{
 
1253
        FPU_CONSISTENCY_CHECK_START();
 
1254
        double x, y;
 
1255
        x = extended_to_double( src );
 
1256
        y = pow(10.0, x);
 
1257
        double_to_extended( y, dest );
 
1258
        do_ftst( dest );
 
1259
        FPU_CONSISTENCY_CHECK_STOP("do_ftentox");
 
1260
}
 
1261
 
 
1262
static void do_flogn( float80 dest, float80 src ) REGPARAM;
 
1263
static void do_flogn( float80 dest, float80 src )
 
1264
{
 
1265
        FPU_CONSISTENCY_CHECK_START();
 
1266
        double x, y;
 
1267
        x = extended_to_double( src );
 
1268
        y = log (x);
 
1269
        double_to_extended( y, dest );
 
1270
        do_ftst( dest );
 
1271
        FPU_CONSISTENCY_CHECK_STOP("do_flogn");
 
1272
}
 
1273
 
 
1274
static void do_flog10( float80 dest, float80 src ) REGPARAM;
 
1275
static void do_flog10( float80 dest, float80 src )
 
1276
{
 
1277
        FPU_CONSISTENCY_CHECK_START();
 
1278
        double x, y;
 
1279
        x = extended_to_double( src );
 
1280
        y = log10 (x);
 
1281
        double_to_extended( y, dest );
 
1282
        do_ftst( dest );
 
1283
        FPU_CONSISTENCY_CHECK_STOP("do_flog10");
 
1284
}
 
1285
 
 
1286
static void do_flog2( float80 dest, float80 src ) REGPARAM;
 
1287
static void do_flog2( float80 dest, float80 src )
 
1288
{
 
1289
        FPU_CONSISTENCY_CHECK_START();
 
1290
        double x, y;
 
1291
        x = extended_to_double( src );
 
1292
        y = log (x) / log (2.0);
 
1293
        double_to_extended( y, dest );
 
1294
        do_ftst( dest );
 
1295
        FPU_CONSISTENCY_CHECK_STOP("do_flog2");
 
1296
}
 
1297
 
 
1298
static void do_facos( float80 dest, float80 src ) REGPARAM;
 
1299
static void do_facos( float80 dest, float80 src )
 
1300
{
 
1301
        FPU_CONSISTENCY_CHECK_START();
 
1302
        double x, y;
 
1303
        x = extended_to_double( src );
 
1304
        y = acos(x);
 
1305
        double_to_extended( y, dest );
 
1306
        do_ftst( dest );
 
1307
        FPU_CONSISTENCY_CHECK_STOP("do_facos");
 
1308
}
 
1309
 
 
1310
static void do_fcosh( float80 dest, float80 src ) REGPARAM;
 
1311
static void do_fcosh( float80 dest, float80 src )
 
1312
{
 
1313
        FPU_CONSISTENCY_CHECK_START();
 
1314
        double x, y;
 
1315
        x = extended_to_double( src );
 
1316
        y = cosh(x);
 
1317
        double_to_extended( y, dest );
 
1318
        do_ftst( dest );
 
1319
        FPU_CONSISTENCY_CHECK_STOP("do_fcosh");
 
1320
}
 
1321
 
 
1322
static void do_fsin( float80 dest, float80 src ) REGPARAM;
 
1323
static void do_fsin( float80 dest, float80 src )
 
1324
{
 
1325
        FPU_CONSISTENCY_CHECK_START();
 
1326
/*      _asm {
 
1327
                MOV                     ESI, [src]
 
1328
                MOV                     EDI, [dest]
 
1329
    FLD     TBYTE PTR [ESI]
 
1330
                FSIN
 
1331
                FXAM
 
1332
    FNSTSW  sw
 
1333
                FSTP    TBYTE PTR [EDI]
 
1334
        } */
 
1335
        _ASM(   "fldt   %2\n"
 
1336
                        "fsin   \n"
 
1337
                        "fxam   \n"
 
1338
                        "fnstsw %0\n"
 
1339
                        "fstpt  %1\n"
 
1340
                :       "=m" (sw), "=m" (*dest)
 
1341
                :       "m" (*src)
 
1342
                );
 
1343
        if(sw & SW_EXCEPTION_MASK) {
 
1344
//              _asm FNCLEX
 
1345
                _ASM("fnclex");
 
1346
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE);
 
1347
                sw_accrued |= sw;
 
1348
        }
 
1349
        FPU_CONSISTENCY_CHECK_STOP("do_fsin");
 
1350
}
 
1351
 
 
1352
// TODO: Should check for out-of-range condition (partial tangent)
 
1353
static void do_ftan( float80 dest, float80 src ) REGPARAM;
 
1354
static void do_ftan( float80 dest, float80 src )
 
1355
{
 
1356
        FPU_CONSISTENCY_CHECK_START();
 
1357
/*      _asm {
 
1358
                MOV                     ESI, [src]
 
1359
                MOV                     EDI, [dest]
 
1360
    FLD     TBYTE PTR [ESI]
 
1361
                FPTAN
 
1362
                FSTP    ST(0)   ; pop 1.0 (the 8087/287 compatibility thing)
 
1363
                FXAM
 
1364
    FNSTSW  sw
 
1365
                FSTP    TBYTE PTR [EDI]
 
1366
        } */
 
1367
        _ASM(   "fldt   %2\n"
 
1368
                        "fptan  \n"
 
1369
                        "fstp   %%st(0)\n"
 
1370
                        "fxam   \n"
 
1371
                        "fnstsw %0\n"
 
1372
                        "fstpt  %1\n"
 
1373
                :       "=m" (sw), "=m" (*dest)
 
1374
                :       "m" (*src)
 
1375
                );
 
1376
        if(sw & SW_EXCEPTION_MASK) {
 
1377
//              _asm FNCLEX
 
1378
                _ASM("fnclex");
 
1379
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE - SW_UE);
 
1380
                sw_accrued |= sw;
 
1381
        }
 
1382
        FPU_CONSISTENCY_CHECK_STOP("do_ftan");
 
1383
}
 
1384
 
 
1385
static void do_fabs( float80 dest, float80 src ) REGPARAM;
 
1386
static void do_fabs( float80 dest, float80 src )
 
1387
{
 
1388
        FPU_CONSISTENCY_CHECK_START();
 
1389
/*      _asm {
 
1390
                MOV                     ESI, [src]
 
1391
                MOV                     EDI, [dest]
 
1392
    FLD     TBYTE PTR [ESI]
 
1393
                FABS
 
1394
                FXAM
 
1395
    FNSTSW  sw
 
1396
                FSTP    TBYTE PTR [EDI]
 
1397
        } */
 
1398
        _ASM(   "fldt   %2\n"
 
1399
                        "fabs   \n"
 
1400
                        "fxam   \n"
 
1401
                        "fnstsw %0\n"
 
1402
                        "fstpt  %1\n"
 
1403
                :       "=m" (sw), "=m" (*dest)
 
1404
                :       "m" (*src)
 
1405
                );
 
1406
        // x86 fabs should not rise any exceptions (except stack underflow)
 
1407
        if(sw & SW_EXCEPTION_MASK) {
 
1408
//              _asm FNCLEX
 
1409
                _ASM("fnclex");
 
1410
                sw &= ~SW_EXCEPTION_MASK;
 
1411
        }
 
1412
        FPU_CONSISTENCY_CHECK_STOP("do_fabs");
 
1413
}
 
1414
 
 
1415
static void do_fneg( float80 dest, float80 src ) REGPARAM;
 
1416
static void do_fneg( float80 dest, float80 src )
 
1417
{
 
1418
        FPU_CONSISTENCY_CHECK_START();
 
1419
/*      _asm {
 
1420
                MOV                     ESI, [src]
 
1421
                MOV                     EDI, [dest]
 
1422
    FLD     TBYTE PTR [ESI]
 
1423
                FCHS
 
1424
                FXAM
 
1425
    FNSTSW  sw
 
1426
                FSTP    TBYTE PTR [EDI]
 
1427
        } */
 
1428
        _ASM(   "fldt   %2\n"
 
1429
                        "fchs   \n"
 
1430
                        "fxam   \n"
 
1431
                        "fnstsw %0\n"
 
1432
                        "fstpt  %1\n"
 
1433
                :       "=m" (sw), "=m" (*dest)
 
1434
                :       "m" (*src)
 
1435
                );
 
1436
        // x86 fchs should not rise any exceptions (except stack underflow)
 
1437
        if(sw & SW_EXCEPTION_MASK) {
 
1438
//              _asm FNCLEX
 
1439
                _ASM("fnclex");
 
1440
                sw &= ~SW_EXCEPTION_MASK;
 
1441
        }
 
1442
        FPU_CONSISTENCY_CHECK_STOP("do_fneg");
 
1443
}
 
1444
 
 
1445
static void do_fcos( float80 dest, float80 src ) REGPARAM;
 
1446
static void do_fcos( float80 dest, float80 src )
 
1447
{
 
1448
        FPU_CONSISTENCY_CHECK_START();
 
1449
/*      _asm {
 
1450
                MOV                     ESI, [src]
 
1451
                MOV                     EDI, [dest]
 
1452
    FLD     TBYTE PTR [ESI]
 
1453
                FCOS
 
1454
                FXAM
 
1455
    FNSTSW  sw
 
1456
                FSTP    TBYTE PTR [EDI]
 
1457
        } */
 
1458
        _ASM(   "fldt   %2\n"
 
1459
                        "fcos   \n"
 
1460
                        "fxam   \n"
 
1461
                        "fnstsw %0\n"
 
1462
                        "fstpt  %1\n"
 
1463
                :       "=m" (sw), "=m" (*dest)
 
1464
                :       "m" (*src)
 
1465
                );
 
1466
        if(sw & SW_EXCEPTION_MASK) {
 
1467
//              _asm FNCLEX
 
1468
                _ASM("fnclex");
 
1469
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE);
 
1470
                sw_accrued |= sw;
 
1471
        }
 
1472
        FPU_CONSISTENCY_CHECK_STOP("do_fcos");
 
1473
}
 
1474
 
 
1475
static void do_fgetexp( float80 dest, float80 src ) REGPARAM;
 
1476
static void do_fgetexp( float80 dest, float80 src )
 
1477
{
 
1478
        FPU_CONSISTENCY_CHECK_START();
 
1479
/*      _asm {
 
1480
                MOV                     ESI, [src]
 
1481
                MOV                     EDI, [dest]
 
1482
    FLD     TBYTE PTR [ESI]
 
1483
                FXTRACT
 
1484
                FSTP    ST(0)                                           ; pop mantissa
 
1485
                FXAM
 
1486
    FNSTSW  sw
 
1487
                FSTP    TBYTE PTR [EDI]
 
1488
        } */
 
1489
        _ASM(   "fldt   %2\n"
 
1490
                        "fxtract\n"
 
1491
                        "fstp   %%st(0)\n"
 
1492
                        "fxam   \n"
 
1493
                        "fnstsw %0\n"
 
1494
                        "fstpt  %1\n"
 
1495
                :       "=m" (sw), "=m" (*dest)
 
1496
                :       "m" (*src)
 
1497
                );
 
1498
        if(sw & SW_EXCEPTION_MASK) {
 
1499
//              _asm FNCLEX
 
1500
                _ASM("fnclex");
 
1501
                sw &= ~SW_EXCEPTION_MASK;
 
1502
        }
 
1503
        FPU_CONSISTENCY_CHECK_STOP("do_fgetexp");
 
1504
}
 
1505
 
 
1506
static void do_fgetman( float80 dest, float80 src ) REGPARAM;
 
1507
static void do_fgetman( float80 dest, float80 src )
 
1508
{
 
1509
        FPU_CONSISTENCY_CHECK_START();
 
1510
/*      _asm {
 
1511
                MOV                     ESI, [src]
 
1512
                MOV                     EDI, [dest]
 
1513
    FLD     TBYTE PTR [ESI]
 
1514
                FXTRACT
 
1515
                FXAM
 
1516
    FNSTSW  sw
 
1517
                FSTP    TBYTE PTR [EDI]
 
1518
                FSTP    ST(0)                                           ; pop exponent
 
1519
        } */
 
1520
        _ASM(   "fldt   %2\n"
 
1521
                        "fxtract\n"
 
1522
                        "fxam   \n"
 
1523
                        "fnstsw %0\n"
 
1524
                        "fstpt  %1\n"
 
1525
                        "fstp   %%st(0)\n"
 
1526
                :       "=m" (sw), "=m" (*dest)
 
1527
                :       "m" (*src)
 
1528
                );
 
1529
        if(sw & SW_EXCEPTION_MASK) {
 
1530
//              _asm FNCLEX
 
1531
                _ASM("fnclex");
 
1532
                sw &= ~SW_EXCEPTION_MASK;
 
1533
        }
 
1534
        FPU_CONSISTENCY_CHECK_STOP("do_fgetman");
 
1535
}
 
1536
 
 
1537
static void do_fdiv( float80 dest, float80 src ) REGPARAM;
 
1538
static void do_fdiv( float80 dest, float80 src )
 
1539
{
 
1540
        FPU_CONSISTENCY_CHECK_START();
 
1541
/*      _asm {
 
1542
                MOV                     ESI, [src]
 
1543
                MOV                     EDI, [dest]
 
1544
    FLD     TBYTE PTR [ESI]
 
1545
    FLD     TBYTE PTR [EDI]
 
1546
                FDIV            ST(0),ST(1)
 
1547
                FXAM
 
1548
    FNSTSW  sw
 
1549
                FSTP    TBYTE PTR [EDI]
 
1550
                FSTP    ST(0)
 
1551
        } */
 
1552
        _ASM(   "fldt   %2\n"
 
1553
                        "fldt   %1\n"
 
1554
                        "fdiv   %%st(1), %%st(0)\n"
 
1555
                        "fxam   \n"
 
1556
                        "fnstsw %0\n"
 
1557
                        "fstpt  %1\n"
 
1558
                        "fstp   %%st(0)\n"
 
1559
                :       "=m" (sw), "+m" (*dest)
 
1560
                :       "m" (*src)
 
1561
                );
 
1562
        if(sw & SW_EXCEPTION_MASK) {
 
1563
//              _asm FNCLEX
 
1564
                _ASM("fnclex");
 
1565
                sw_accrued |= sw;
 
1566
        }
 
1567
        FPU_CONSISTENCY_CHECK_STOP("do_fdiv");
 
1568
}
 
1569
 
 
1570
// The sign of the quotient is the exclusive-OR of the sign bits
 
1571
// of the source and destination operands.
 
1572
// Quotient Byte is loaded with the sign and least significant
 
1573
// seven bits of the quotient.
 
1574
 
 
1575
static void do_fmod( float80 dest, float80 src ) REGPARAM;
 
1576
static void do_fmod( float80 dest, float80 src )
 
1577
{
 
1578
        FPU_CONSISTENCY_CHECK_START();
 
1579
 
 
1580
        volatile uint16 status;
 
1581
        uae_u32 quot;
 
1582
#if !USE_3_BIT_QUOTIENT
 
1583
        WORD cw_temp;
 
1584
#endif
 
1585
 
 
1586
        uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
 
1587
 
 
1588
/*      _asm {
 
1589
                MOV                     ESI, [src]
 
1590
                MOV                     EDI, [dest]
 
1591
 
 
1592
#if !USE_3_BIT_QUOTIENT
 
1593
                MOV                     CX, cw
 
1594
                AND                     CX, ~X86_ROUND_CONTROL_MASK
 
1595
                OR                      CX, CW_RC_ZERO
 
1596
                MOV                     cw_temp, CX
 
1597
    FLDCW   cw_temp
 
1598
 
 
1599
                FLD     TBYTE PTR [ESI]
 
1600
                FLD     TBYTE PTR [EDI]
 
1601
                FDIV            ST(0),ST(1)
 
1602
                FABS
 
1603
    FISTP   DWORD PTR quot
 
1604
                FSTP    ST(0)
 
1605
    FLDCW   cw
 
1606
                // TODO:Quotient
 
1607
                // Should clear any possible exceptions here
 
1608
#endif
 
1609
 
 
1610
                FLD     TBYTE PTR [ESI]
 
1611
                FLD     TBYTE PTR [EDI]
 
1612
 
 
1613
// loop until the remainder is not partial any more.
 
1614
partial_loop:
 
1615
                FPREM
 
1616
                FNSTSW  status
 
1617
                TEST            status, SW_C2
 
1618
                JNE                     partial_loop
 
1619
 
 
1620
 
 
1621
                FXAM
 
1622
    FNSTSW  sw
 
1623
 
 
1624
                FSTP    TBYTE PTR [EDI]
 
1625
                FSTP    ST(0)
 
1626
        } */
 
1627
        
 
1628
#if !USE_3_BIT_QUOTIENT
 
1629
        
 
1630
        _ASM(   "movl   %6, %%ecx\n"    // %6: cw               (read)
 
1631
                        "andl   $(~X86_ROUND_CONTROL_MASK), %%ecx\n"
 
1632
                        "orl    $CW_RC_ZERO, %%ecx\n"
 
1633
                        "movl   %%ecx, %0\n"    // %0: cw_temp  (read/write)
 
1634
                        "fldcw  %0\n"
 
1635
                        "fldt   %5\n"
 
1636
                        "fldt   %4\n"
 
1637
                        "fdiv   %%st(1), %%st(0)\n"
 
1638
                        "fabs   \n"
 
1639
                        "fistpl %1\n"                   // %1: quot             (read/write)
 
1640
                        "fstp   %%st(0)\n"
 
1641
                        "fldcw  %6\n"
 
1642
                        "fldt   %5\n"
 
1643
                        "fldt   %4\n"
 
1644
                        "0:\n"                                  // partial_loop
 
1645
                        "fprem  \n"
 
1646
                        "fnstsw %2\n"                   // %2: status   (read/write)
 
1647
                        "testl  $SW_C2, %2\n"
 
1648
                        "jne    0b\n"
 
1649
                        "fxam   \n"
 
1650
                        "fnstsw %3\n"                   // %3: sw               (write)
 
1651
                        "fstpt  %4\n"
 
1652
                        "fstp   %%st(0)\n"
 
1653
                :       "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (sw), "+m" (*dest)
 
1654
                :       "m" (*src), "m" (cw)
 
1655
                :       "ecx"
 
1656
                );
 
1657
        
 
1658
#else
 
1659
        
 
1660
        _ASM(   "fldt   %4\n"
 
1661
                        "fldt   %2\n"
 
1662
                        "0:\n"                                  // partial_loop
 
1663
                        "fprem  \n"
 
1664
                        "fnstsw %0\n"                   // %0: status   (read/write)
 
1665
                        "testl  $SW_C2, %0\n"
 
1666
                        "jne    0b\n"
 
1667
                        "fxam   \n"
 
1668
                        "fnstsw %1\n"                   // %1: sw               (write)
 
1669
                        "fstpt  %2\n"
 
1670
                        "fstp   %%st(0)\n"
 
1671
                :       "+m" (status), "=m" (sw), "+m" (*dest)
 
1672
                :       "m" (*src)
 
1673
                );
 
1674
        
 
1675
#endif
 
1676
        
 
1677
        if(sw & SW_EXCEPTION_MASK) {
 
1678
//              _asm FNCLEX
 
1679
                _ASM("fnclex");
 
1680
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
 
1681
                sw_accrued |= sw;
 
1682
        }
 
1683
 
 
1684
#if USE_3_BIT_QUOTIENT
 
1685
        // SW_C1 Set to least significant bit of quotient (Q0).
 
1686
        // SW_C3 Set to bit 1 (Q1) of the quotient.
 
1687
        // SW_C0 Set to bit 2 (Q2) of the quotient.
 
1688
        quot = ((status & SW_C0) >> 6) | ((status & SW_C3) >> 13) | ((status & SW_C1) >> 9);
 
1689
        sw_quotient = (sign | quot) << 16;
 
1690
#else
 
1691
        sw_quotient = (sign | (quot&0x7F)) << 16;
 
1692
#endif
 
1693
 
 
1694
        FPU_CONSISTENCY_CHECK_STOP("do_fmod");
 
1695
}
 
1696
 
 
1697
static void do_frem( float80 dest, float80 src ) REGPARAM;
 
1698
static void do_frem( float80 dest, float80 src )
 
1699
{
 
1700
        FPU_CONSISTENCY_CHECK_START();
 
1701
 
 
1702
        volatile uint16 status;
 
1703
        uae_u32 quot;
 
1704
#if !USE_3_BIT_QUOTIENT
 
1705
        WORD cw_temp;
 
1706
#endif
 
1707
 
 
1708
        uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
 
1709
 
 
1710
/*      _asm {
 
1711
                MOV                     ESI, [src]
 
1712
                MOV                     EDI, [dest]
 
1713
 
 
1714
#if !USE_3_BIT_QUOTIENT
 
1715
                MOV                     CX, cw
 
1716
                AND                     CX, ~X86_ROUND_CONTROL_MASK
 
1717
                OR                      CX, CW_RC_NEAR
 
1718
                MOV                     cw_temp, CX
 
1719
    FLDCW   cw_temp
 
1720
 
 
1721
                FLD     TBYTE PTR [ESI]
 
1722
                FLD     TBYTE PTR [EDI]
 
1723
                FDIV            ST(0),ST(1)
 
1724
                FABS
 
1725
    FISTP   DWORD PTR quot
 
1726
                FSTP    ST(0)
 
1727
    FLDCW   cw
 
1728
                // TODO:Quotient
 
1729
                // Should clear any possible exceptions here
 
1730
#endif
 
1731
 
 
1732
                FLD     TBYTE PTR [ESI]
 
1733
                FLD     TBYTE PTR [EDI]
 
1734
 
 
1735
// loop until the remainder is not partial any more.
 
1736
partial_loop:
 
1737
                FPREM1
 
1738
                FNSTSW  status
 
1739
                TEST            status, SW_C2
 
1740
                JNE                     partial_loop
 
1741
 
 
1742
                FXAM
 
1743
    FNSTSW  sw
 
1744
                FSTP    TBYTE PTR [EDI]
 
1745
                FSTP    ST(0)
 
1746
        } */
 
1747
 
 
1748
#if !USE_3_BIT_QUOTIENT
 
1749
        
 
1750
        _ASM(   "movl   %6, %%ecx\n"    // %6: cw               (read)
 
1751
                        "andl   $(~X86_ROUND_CONTROL_MASK), %%ecx\n"
 
1752
                        "orl    $CW_RC_NEAR, %%ecx\n"
 
1753
                        "movl   %%ecx, %0\n"    // %0: cw_temp  (read/write)
 
1754
                        "fldcw  %0\n"
 
1755
                        "fldt   %5\n"
 
1756
                        "fldt   %4\n"
 
1757
                        "fdiv   %%st(1), %%st(0)\n"
 
1758
                        "fabs   \n"
 
1759
                        "fistpl %1\n"                   // %1: quot             (read/write)
 
1760
                        "fstp   %%st(0)\n"
 
1761
                        "fldcw  %6\n"
 
1762
                        "fldt   %5\n"
 
1763
                        "fldt   %4\n"
 
1764
                        "0:\n"                                  // partial_loop
 
1765
                        "fprem1 \n"
 
1766
                        "fnstsw %2\n"                   // %2: status   (read/write)
 
1767
                        "testl  $SW_C2, %2\n"
 
1768
                        "jne    0b\n"
 
1769
                        "fxam   \n"
 
1770
                        "fnstsw %3\n"                   // %3: sw               (write)
 
1771
                        "fstpt  %4\n"
 
1772
                        "fstp   %%st(0)\n"
 
1773
                :       "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (sw), "+m" (*dest)
 
1774
                :       "m" (*src), "m" (cw)
 
1775
                :       "ecx"
 
1776
                );
 
1777
        
 
1778
#else
 
1779
        
 
1780
        _ASM(   "fldt   %3\n"
 
1781
                        "fldt   %2\n"
 
1782
                        "0:\n"                                  // partial_loop
 
1783
                        "fprem1 \n"
 
1784
                        "fnstsw %0\n"                   // %0: status   (read/write)
 
1785
                        "testl  $SW_C2, %0\n"
 
1786
                        "jne    0b\n"
 
1787
                        "fxam   \n"
 
1788
                        "fnstsw %1\n"                   // %1: sw               (write)
 
1789
                        "fstpt  %2\n"
 
1790
                        "fstp   %%st(0)\n"
 
1791
                :       "+m" (status), "=m" (sw), "+m" (*dest)
 
1792
                :       "m" (*src)
 
1793
                );
 
1794
        
 
1795
#endif
 
1796
        
 
1797
        if(sw & SW_EXCEPTION_MASK) {
 
1798
//              _asm FNCLEX
 
1799
                _ASM("fnclex");
 
1800
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
 
1801
                sw_accrued |= sw;
 
1802
        }
 
1803
 
 
1804
#if USE_3_BIT_QUOTIENT
 
1805
        // SW_C1 Set to least significant bit of quotient (Q0).
 
1806
        // SW_C3 Set to bit 1 (Q1) of the quotient.
 
1807
        // SW_C0 Set to bit 2 (Q2) of the quotient.
 
1808
        quot = ((status & SW_C0) >> 6) | ((status & SW_C3) >> 13) | ((status & SW_C1) >> 9);
 
1809
        sw_quotient = (sign | quot) << 16;
 
1810
#else
 
1811
        sw_quotient = (sign | (quot&0x7F)) << 16;
 
1812
#endif
 
1813
 
 
1814
        FPU_CONSISTENCY_CHECK_STOP("do_frem");
 
1815
}
 
1816
 
 
1817
// Faster versions. The current rounding mode is already correct.
 
1818
#if !USE_3_BIT_QUOTIENT
 
1819
static void do_fmod_dont_set_cw( float80 dest, float80 src ) REGPARAM;
 
1820
static void do_fmod_dont_set_cw( float80 dest, float80 src )
 
1821
{
 
1822
        FPU_CONSISTENCY_CHECK_START();
 
1823
 
 
1824
        volatile uint16 status;
 
1825
        uae_u32 quot;
 
1826
 
 
1827
        uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
 
1828
 
 
1829
        _asm {
 
1830
                MOV                     ESI, [src]
 
1831
                MOV                     EDI, [dest]
 
1832
 
 
1833
                FLD     TBYTE PTR [ESI]
 
1834
                FLD     TBYTE PTR [EDI]
 
1835
                FDIV            ST(0),ST(1)
 
1836
                FABS
 
1837
    FISTP   DWORD PTR quot
 
1838
                FSTP    ST(0)
 
1839
                // TODO:Quotient
 
1840
                // Should clear any possible exceptions here
 
1841
 
 
1842
                FLD     TBYTE PTR [ESI]
 
1843
                FLD     TBYTE PTR [EDI]
 
1844
 
 
1845
// loop until the remainder is not partial any more.
 
1846
partial_loop:
 
1847
                FPREM
 
1848
                FNSTSW  status
 
1849
                TEST            status, SW_C2
 
1850
                JNE                     partial_loop
 
1851
 
 
1852
                FXAM
 
1853
    FNSTSW  sw
 
1854
 
 
1855
                FSTP    TBYTE PTR [EDI]
 
1856
                FSTP    ST(0)
 
1857
        }
 
1858
        if(sw & SW_EXCEPTION_MASK) {
 
1859
                _asm FNCLEX
 
1860
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
 
1861
                sw_accrued |= sw;
 
1862
        }
 
1863
        sw_quotient = (sign | (quot&0x7F)) << 16;
 
1864
        FPU_CONSISTENCY_CHECK_STOP("do_fmod_dont_set_cw");
 
1865
}
 
1866
 
 
1867
static void do_frem_dont_set_cw( float80 dest, float80 src ) REGPARAM;
 
1868
static void do_frem_dont_set_cw( float80 dest, float80 src )
 
1869
{
 
1870
        FPU_CONSISTENCY_CHECK_START();
 
1871
 
 
1872
        volatile uint16 status;
 
1873
        uae_u32 quot;
 
1874
 
 
1875
        uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
 
1876
 
 
1877
        _asm {
 
1878
                MOV                     ESI, [src]
 
1879
                MOV                     EDI, [dest]
 
1880
 
 
1881
                FLD     TBYTE PTR [ESI]
 
1882
                FLD     TBYTE PTR [EDI]
 
1883
                FDIV            ST(0),ST(1)
 
1884
                FABS
 
1885
    FISTP   DWORD PTR quot
 
1886
                FSTP    ST(0)
 
1887
                // TODO:Quotient
 
1888
                // Should clear any possible exceptions here
 
1889
 
 
1890
                FLD     TBYTE PTR [ESI]
 
1891
                FLD     TBYTE PTR [EDI]
 
1892
 
 
1893
// loop until the remainder is not partial any more.
 
1894
partial_loop:
 
1895
                FPREM1
 
1896
                FNSTSW  status
 
1897
                TEST            status, SW_C2
 
1898
                JNE                     partial_loop
 
1899
 
 
1900
                FXAM
 
1901
    FNSTSW  sw
 
1902
                FSTP    TBYTE PTR [EDI]
 
1903
                FSTP    ST(0)
 
1904
        }
 
1905
        if(sw & SW_EXCEPTION_MASK) {
 
1906
                _asm FNCLEX
 
1907
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
 
1908
                sw_accrued |= sw;
 
1909
        }
 
1910
        sw_quotient = (sign | (quot&0x7F)) << 16;
 
1911
        FPU_CONSISTENCY_CHECK_STOP("do_frem_dont_set_cw");
 
1912
}
 
1913
#endif //USE_3_BIT_QUOTIENT
 
1914
 
 
1915
static void do_fadd( float80 dest, float80 src ) REGPARAM;
 
1916
static void do_fadd( float80 dest, float80 src )
 
1917
{
 
1918
        FPU_CONSISTENCY_CHECK_START();
 
1919
/*      _asm {
 
1920
                MOV                     ESI, [src]
 
1921
                MOV                     EDI, [dest]
 
1922
    FLD     TBYTE PTR [ESI]
 
1923
    FLD     TBYTE PTR [EDI]
 
1924
                FADD
 
1925
                FXAM
 
1926
    FNSTSW  sw
 
1927
                FSTP    TBYTE PTR [EDI]
 
1928
        } */
 
1929
        _ASM(   "fldt   %2\n"
 
1930
                        "fldt   %1\n"
 
1931
                        "fadd   \n"
 
1932
                        "fxam   \n"
 
1933
                        "fnstsw %0\n"
 
1934
                        "fstpt  %1\n"
 
1935
                :       "=m" (sw), "+m" (*dest)
 
1936
                :       "m" (*src)
 
1937
                );
 
1938
        if(sw & SW_EXCEPTION_MASK) {
 
1939
//              _asm FNCLEX
 
1940
                _ASM("fnclex");
 
1941
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE);
 
1942
                sw_accrued |= sw;
 
1943
        }
 
1944
        FPU_CONSISTENCY_CHECK_STOP("do_fadd");
 
1945
}
 
1946
 
 
1947
static void do_fmul( float80 dest, float80 src ) REGPARAM;
 
1948
static void do_fmul( float80 dest, float80 src )
 
1949
{
 
1950
        FPU_CONSISTENCY_CHECK_START();
 
1951
/*      _asm {
 
1952
                MOV                     ESI, [src]
 
1953
                MOV                     EDI, [dest]
 
1954
    FLD     TBYTE PTR [ESI]
 
1955
    FLD     TBYTE PTR [EDI]
 
1956
                FMUL
 
1957
                FXAM
 
1958
    FNSTSW  sw
 
1959
                FSTP    TBYTE PTR [EDI]
 
1960
        } */
 
1961
        _ASM(   "fldt   %2\n"
 
1962
                        "fldt   %1\n"
 
1963
                        "fmul   \n"
 
1964
                        "fxam   \n"
 
1965
                        "fnstsw %0\n"
 
1966
                        "fstpt  %1\n"
 
1967
                :       "=m" (sw), "+m" (*dest)
 
1968
                :       "m" (*src)
 
1969
                );
 
1970
        if(sw & SW_EXCEPTION_MASK) {
 
1971
//              _asm FNCLEX
 
1972
                _ASM("fnclex");
 
1973
                sw_accrued |= sw;
 
1974
        }
 
1975
        FPU_CONSISTENCY_CHECK_STOP("do_fmul");
 
1976
}
 
1977
 
 
1978
static void do_fsgldiv( float80 dest, float80 src ) REGPARAM;
 
1979
static void do_fsgldiv( float80 dest, float80 src )
 
1980
{
 
1981
        FPU_CONSISTENCY_CHECK_START();
 
1982
        WORD cw_temp;
 
1983
/*      _asm {
 
1984
                FSTCW   cw_temp
 
1985
                and                     cw_temp, ~X86_PRECISION_CONTROL_MASK
 
1986
                or                      cw_temp, PRECISION_CONTROL_SINGLE
 
1987
    FLDCW   cw_temp
 
1988
 
 
1989
                MOV                     ESI, [src]
 
1990
                MOV                     EDI, [dest]
 
1991
    FLD     TBYTE PTR [ESI]
 
1992
    FLD     TBYTE PTR [EDI]
 
1993
                FDIV            ST(0),ST(1)
 
1994
                FXAM
 
1995
    FNSTSW  sw
 
1996
                FSTP    TBYTE PTR [EDI]
 
1997
                FSTP    ST(0)
 
1998
    FLDCW   cw
 
1999
        } */
 
2000
        _ASM(   "fstcw  %0\n"
 
2001
                        "andl   $(~X86_PRECISION_CONTROL_MASK), %0\n"
 
2002
                        "orl    $PRECISION_CONTROL_SINGLE, %0\n"
 
2003
                        "fldcw  %0\n"
 
2004
                        "fldt   %3\n"
 
2005
                        "fldt   %2\n"
 
2006
                        "fdiv   %%st(1), %%st(0)\n"
 
2007
                        "fxam   \n"
 
2008
                        "fnstsw %1\n"
 
2009
                        "fstpt  %2\n"
 
2010
                        "fstp   %%st(0)\n"
 
2011
                        "fldcw  %4\n"
 
2012
                :       "+m" (cw_temp), "=m" (sw), "+m" (*dest)
 
2013
                :       "m" (*src), "m" (cw)
 
2014
                );
 
2015
        if(sw & SW_EXCEPTION_MASK) {
 
2016
//              _asm FNCLEX
 
2017
                _ASM("fnclex");
 
2018
                sw_accrued |= sw;
 
2019
        }
 
2020
        FPU_CONSISTENCY_CHECK_STOP("do_fsgldiv");
 
2021
}
 
2022
 
 
2023
static void do_fscale( float80 dest, float80 src ) REGPARAM;
 
2024
static void do_fscale( float80 dest, float80 src )
 
2025
{
 
2026
        FPU_CONSISTENCY_CHECK_START();
 
2027
/*      _asm {
 
2028
                MOV                     ESI, [src]
 
2029
                MOV                     EDI, [dest]
 
2030
    FLD     TBYTE PTR [ESI]
 
2031
    FLD     TBYTE PTR [EDI]
 
2032
                FSCALE
 
2033
                FXAM
 
2034
    FNSTSW  sw
 
2035
                FSTP    TBYTE PTR [EDI]
 
2036
                FSTP    ST(0)
 
2037
        } */
 
2038
        _ASM(   "fldt   %2\n"
 
2039
                        "fldt   %1\n"
 
2040
                        "fscale \n"
 
2041
                        "fxam   \n"
 
2042
                        "fnstsw %0\n"
 
2043
                        "fstpt  %1\n"
 
2044
                        "fstp   %%st(0)\n"
 
2045
                :       "=m" (sw), "+m" (*dest)
 
2046
                :       "m" (*src)
 
2047
                );
 
2048
        if(sw & SW_EXCEPTION_MASK) {
 
2049
//              _asm FNCLEX
 
2050
                _ASM("fnclex");
 
2051
                sw &= ~(SW_EXCEPTION_MASK - SW_UE - SW_OE);
 
2052
                sw_accrued |= sw;
 
2053
        }
 
2054
        FPU_CONSISTENCY_CHECK_STOP("do_fscale");
 
2055
}
 
2056
 
 
2057
static void do_fsglmul( float80 dest, float80 src ) REGPARAM;
 
2058
static void do_fsglmul( float80 dest, float80 src )
 
2059
{
 
2060
        FPU_CONSISTENCY_CHECK_START();
 
2061
        WORD cw_temp;
 
2062
 
 
2063
/*      _asm {
 
2064
                FSTCW   cw_temp
 
2065
                and                     cw_temp, ~X86_PRECISION_CONTROL_MASK
 
2066
                or                      cw_temp, PRECISION_CONTROL_SINGLE
 
2067
    FLDCW   cw_temp
 
2068
 
 
2069
                MOV                     ESI, [src]
 
2070
                MOV                     EDI, [dest]
 
2071
    FLD     TBYTE PTR [ESI]
 
2072
    FLD     TBYTE PTR [EDI]
 
2073
                FMUL
 
2074
                FXAM
 
2075
    FNSTSW  sw
 
2076
                FSTP    TBYTE PTR [EDI]
 
2077
 
 
2078
    FLDCW   cw
 
2079
        } */
 
2080
        _ASM(   "fstcw  %0\n"
 
2081
                        "andl   $(~X86_PRECISION_CONTROL_MASK), %0\n"
 
2082
                        "orl    $PRECISION_CONTROL_SINGLE, %0\n"
 
2083
                        "fldcw  %0\n"
 
2084
                        "fldt   %3\n"
 
2085
                        "fldt   %2\n"
 
2086
                        "fmul   \n"
 
2087
                        "fxam   \n"
 
2088
                        "fnstsw %1\n"
 
2089
                        "fstpt  %2\n"
 
2090
                        "fldcw  %4\n"
 
2091
                :       "+m" (cw_temp), "=m" (sw), "+m" (*dest)
 
2092
                :       "m" (*src), "m" (sw)
 
2093
                );
 
2094
        if(sw & SW_EXCEPTION_MASK) {
 
2095
//              _asm FNCLEX
 
2096
                _ASM("fnclex");
 
2097
                sw_accrued |= sw;
 
2098
        }
 
2099
        FPU_CONSISTENCY_CHECK_STOP("do_fsglmul");
 
2100
}
 
2101
 
 
2102
static void do_fsub( float80 dest, float80 src ) REGPARAM;
 
2103
static void do_fsub( float80 dest, float80 src )
 
2104
{
 
2105
        FPU_CONSISTENCY_CHECK_START();
 
2106
/*      _asm {
 
2107
                MOV                     ESI, [src]
 
2108
                MOV                     EDI, [dest]
 
2109
    FLD     TBYTE PTR [ESI]
 
2110
    FLD     TBYTE PTR [EDI]
 
2111
                FSUB            ST(0),ST(1)
 
2112
                FXAM
 
2113
    FNSTSW  sw
 
2114
                FSTP    TBYTE PTR [EDI]
 
2115
                FSTP    ST(0)
 
2116
        } */
 
2117
        _ASM(   "fldt   %2\n"
 
2118
                        "fldt   %1\n"
 
2119
                        "fsub   %%st(1), %%st(0)\n"
 
2120
                        "fxam   \n"
 
2121
                        "fnstsw %0\n"
 
2122
                        "fstpt  %1\n"
 
2123
                        "fstp   %%st(0)\n"
 
2124
                :       "=m" (sw), "+m" (*dest)
 
2125
                :       "m" (*src)
 
2126
                );
 
2127
        if(sw & SW_EXCEPTION_MASK) {
 
2128
//              _asm FNCLEX
 
2129
                _ASM("fnclex");
 
2130
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE);
 
2131
                sw_accrued |= sw;
 
2132
        }
 
2133
        FPU_CONSISTENCY_CHECK_STOP("do_fsub");
 
2134
}
 
2135
 
 
2136
static void do_fsincos( float80 dest_sin, float80 dest_cos, float80 src ) REGPARAM;
 
2137
static void do_fsincos( float80 dest_sin, float80 dest_cos, float80 src )
 
2138
{
 
2139
        FPU_CONSISTENCY_CHECK_START();
 
2140
/*      _asm {
 
2141
                MOV                     ESI, [src]
 
2142
                MOV                     EDI, [dest_cos]
 
2143
    FLD     TBYTE PTR [ESI]
 
2144
                FSINCOS
 
2145
                FSTP    TBYTE PTR [EDI]
 
2146
                FXAM
 
2147
                MOV                     EDI, [dest_sin]
 
2148
    FNSTSW  sw
 
2149
                FSTP    TBYTE PTR [EDI]
 
2150
                FSTP    ST(0)
 
2151
        } */
 
2152
        _ASM(   "fldt   %3\n"
 
2153
                        "fsincos\n"
 
2154
                        "fstpt  %1\n"
 
2155
                        "fxam   \n"
 
2156
                        "fnstsw %0\n"
 
2157
                        "fstpt  %2\n"
 
2158
                        "fstp   %%st(0)\n"
 
2159
                :       "=m" (sw), "=m" (*dest_cos), "=m" (*dest_sin)
 
2160
                :       "m" (*src)
 
2161
                );
 
2162
        if(sw & SW_EXCEPTION_MASK) {
 
2163
//              _asm FNCLEX
 
2164
                _ASM("fnclex");
 
2165
                sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_PE);
 
2166
                sw_accrued |= sw;
 
2167
        }
 
2168
        FPU_CONSISTENCY_CHECK_STOP("do_fsincos");
 
2169
}
 
2170
 
 
2171
static void do_fcmp( float80 dest, float80 src ) REGPARAM;
 
2172
static void do_fcmp( float80 dest, float80 src )
 
2173
{
 
2174
        FPU_CONSISTENCY_CHECK_START();
 
2175
/*      _asm {
 
2176
                MOV                     ESI, [src]
 
2177
                MOV                     EDI, [dest]
 
2178
    FLD     TBYTE PTR [ESI]
 
2179
    FLD     TBYTE PTR [EDI]
 
2180
                FSUB    ST(0),ST(1)
 
2181
                FXAM
 
2182
    FNSTSW  sw
 
2183
                FSTP    ST(0)
 
2184
                FSTP    ST(0)
 
2185
        } */
 
2186
        _ASM(   "fldt   %2\n"
 
2187
                        "fldt   %1\n"
 
2188
                        "fsub   %%st(1), %%st(0)\n"
 
2189
                        "fxam   \n"
 
2190
                        "fnstsw %0\n"
 
2191
                        "fstp   %%st(0)\n"
 
2192
                        "fstp   %%st(0)\n"
 
2193
                :       "=m" (sw)
 
2194
                :       "m" (*dest), "m" (*src)
 
2195
                );
 
2196
        if(sw & SW_EXCEPTION_MASK) {
 
2197
//              _asm FNCLEX
 
2198
                _ASM("fnclex");
 
2199
                sw &= ~SW_EXCEPTION_MASK;
 
2200
        }
 
2201
        FPU_CONSISTENCY_CHECK_STOP("do_fcmp");
 
2202
}
 
2203
 
 
2204
// More or less original. Should be reviewed.
 
2205
static double to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) REGPARAM;
 
2206
static double to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
 
2207
{
 
2208
        FPU_CONSISTENCY_CHECK_START();
 
2209
 
 
2210
  double d;
 
2211
  char *cp;
 
2212
  char str[100];
 
2213
 
 
2214
  cp = str;
 
2215
  if (wrd1 & 0x80000000)
 
2216
                *cp++ = '-';
 
2217
  *cp++ = (char)((wrd1 & 0xf) + '0');
 
2218
  *cp++ = '.';
 
2219
  *cp++ = (char)(((wrd2 >> 28) & 0xf) + '0');
 
2220
  *cp++ = (char)(((wrd2 >> 24) & 0xf) + '0');
 
2221
  *cp++ = (char)(((wrd2 >> 20) & 0xf) + '0');
 
2222
  *cp++ = (char)(((wrd2 >> 16) & 0xf) + '0');
 
2223
  *cp++ = (char)(((wrd2 >> 12) & 0xf) + '0');
 
2224
  *cp++ = (char)(((wrd2 >> 8) & 0xf) + '0');
 
2225
  *cp++ = (char)(((wrd2 >> 4) & 0xf) + '0');
 
2226
  *cp++ = (char)(((wrd2 >> 0) & 0xf) + '0');
 
2227
  *cp++ = (char)(((wrd3 >> 28) & 0xf) + '0');
 
2228
  *cp++ = (char)(((wrd3 >> 24) & 0xf) + '0');
 
2229
  *cp++ = (char)(((wrd3 >> 20) & 0xf) + '0');
 
2230
  *cp++ = (char)(((wrd3 >> 16) & 0xf) + '0');
 
2231
  *cp++ = (char)(((wrd3 >> 12) & 0xf) + '0');
 
2232
  *cp++ = (char)(((wrd3 >> 8) & 0xf) + '0');
 
2233
  *cp++ = (char)(((wrd3 >> 4) & 0xf) + '0');
 
2234
  *cp++ = (char)(((wrd3 >> 0) & 0xf) + '0');
 
2235
  *cp++ = 'E';
 
2236
  if (wrd1 & 0x40000000)
 
2237
                *cp++ = '-';
 
2238
  *cp++ = (char)(((wrd1 >> 24) & 0xf) + '0');
 
2239
  *cp++ = (char)(((wrd1 >> 20) & 0xf) + '0');
 
2240
  *cp++ = (char)(((wrd1 >> 16) & 0xf) + '0');
 
2241
  *cp = 0;
 
2242
  sscanf(str, "%le", &d);
 
2243
 
 
2244
        D(bug("to_pack str = %s\r\n",str));
 
2245
 
 
2246
        D(bug("to_pack(%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)d));
 
2247
 
 
2248
        FPU_CONSISTENCY_CHECK_STOP("to_pack");
 
2249
 
 
2250
  return d;
 
2251
}
 
2252
 
 
2253
// More or less original. Should be reviewed.
 
2254
static void from_pack(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) REGPARAM;
 
2255
static void from_pack(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
 
2256
{
 
2257
        FPU_CONSISTENCY_CHECK_START();
 
2258
 
 
2259
  int i;
 
2260
  int t;
 
2261
  char *cp;
 
2262
  char str[100];
 
2263
  int exponent_digit_count = 0;
 
2264
 
 
2265
  sprintf(str, "%.16e", src);
 
2266
 
 
2267
        D(bug("from_pack(%.04f,%s)\r\n",(float)src,str));
 
2268
 
 
2269
  cp = str;
 
2270
  *wrd1 = *wrd2 = *wrd3 = 0;
 
2271
  if (*cp == '-') {
 
2272
                cp++;
 
2273
                *wrd1 = 0x80000000;
 
2274
  }
 
2275
  if (*cp == '+')
 
2276
                cp++;
 
2277
  *wrd1 |= (*cp++ - '0');
 
2278
  if (*cp == '.')
 
2279
                cp++;
 
2280
  for (i = 0; i < 8; i++) {
 
2281
                *wrd2 <<= 4;
 
2282
                if (*cp >= '0' && *cp <= '9')
 
2283
            *wrd2 |= *cp++ - '0';
 
2284
  }
 
2285
  for (i = 0; i < 8; i++) {
 
2286
                *wrd3 <<= 4;
 
2287
                if (*cp >= '0' && *cp <= '9')
 
2288
            *wrd3 |= *cp++ - '0';
 
2289
  }
 
2290
  if (*cp == 'e' || *cp == 'E') {
 
2291
                cp++;
 
2292
                if (*cp == '-') {
 
2293
                        cp++;
 
2294
                        *wrd1 |= 0x40000000;
 
2295
                }
 
2296
                if (*cp == '+')
 
2297
                        cp++;
 
2298
                t = 0;
 
2299
                for (i = 0; i < 3; i++) {
 
2300
                        if (*cp >= '0' && *cp <= '9') {
 
2301
                                t = (t << 4) | (*cp++ - '0');
 
2302
                                exponent_digit_count++;
 
2303
                        }
 
2304
                }
 
2305
                *wrd1 |= t << 16;
 
2306
  }
 
2307
 
 
2308
        D(bug("from_pack(%.04f) = %X,%X,%X\r\n",(float)src,*wrd1,*wrd2,*wrd3));
 
2309
 
 
2310
        WORD sw_temp;
 
2311
//      _asm FNSTSW sw_temp
 
2312
        _ASM("fnstsw %0" : "=m" (sw_temp));
 
2313
        if(sw_temp & SW_EXCEPTION_MASK) {
 
2314
//              _asm FNCLEX
 
2315
                _ASM("fnclex");
 
2316
                if(sw_temp & SW_PE) {
 
2317
                        sw |= SW_PE;
 
2318
                        sw_accrued |= SW_PE;
 
2319
                }
 
2320
        }
 
2321
 
 
2322
        /*
 
2323
        OPERR is set if the k-factor > + 17 or the magnitude of
 
2324
        the decimal exponent exceeds three digits;
 
2325
        cleared otherwise.
 
2326
        */
 
2327
        if(exponent_digit_count > 3) {
 
2328
                sw |= SW_IE;
 
2329
                sw_accrued |= SW_IE;
 
2330
        }
 
2331
 
 
2332
        FPU_CONSISTENCY_CHECK_STOP("from_pack");
 
2333
}
 
2334
 
 
2335
static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0};
 
2336
static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0};
 
2337
 
 
2338
static int get_fp_value (uae_u32 opcode, uae_u16 extra, float80 src) REGPARAM;
 
2339
static int get_fp_value (uae_u32 opcode, uae_u16 extra, float80 src)
 
2340
{
 
2341
        // D(bug("get_fp_value(%X,%X)\r\n",(int)opcode,(int)extra));
 
2342
        // dump_first_bytes( regs.pc_p-4, 16 );
 
2343
 
 
2344
  if ((extra & 0x4000) == 0) {
 
2345
                memcpy( src, fp_reg[(extra >> 10) & 7], sizeof(float80_s) );
 
2346
                // do_fmove_no_status( src, fp_reg[(extra >> 10) & 7] );
 
2347
                return 1;
 
2348
  }
 
2349
 
 
2350
        int mode = (opcode >> 3) & 7;
 
2351
  int reg = opcode & 7;
 
2352
  int size = (extra >> 10) & 7;
 
2353
  uae_u32 ad = 0;
 
2354
 
 
2355
        // D(bug("get_fp_value mode=%d, reg=%d, size=%d\r\n",(int)mode,(int)reg,(int)size));
 
2356
 
 
2357
  switch ((uae_u8)mode) {
 
2358
    case 0:
 
2359
                        switch ((uae_u8)size) {
 
2360
                                case 6:
 
2361
                                        signed_to_extended( (uae_s32)(uae_s8) m68k_dreg (regs, reg), src );
 
2362
                                        break;
 
2363
                                case 4:
 
2364
                                        signed_to_extended( (uae_s32)(uae_s16) m68k_dreg (regs, reg), src );
 
2365
                                        break;
 
2366
                                case 0:
 
2367
                                        signed_to_extended( (uae_s32) m68k_dreg (regs, reg), src );
 
2368
                                        break;
 
2369
                                case 1:
 
2370
                                        to_single( m68k_dreg (regs, reg), src );
 
2371
                                        break;
 
2372
                                default:
 
2373
                                        return 0;
 
2374
                        }
 
2375
                        return 1;
 
2376
    case 1:
 
2377
                        return 0;
 
2378
    case 2:
 
2379
                        ad = m68k_areg (regs, reg);
 
2380
                        break;
 
2381
    case 3:
 
2382
                        ad = m68k_areg (regs, reg);
 
2383
                        m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
 
2384
                        break;
 
2385
    case 4:
 
2386
                        m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
 
2387
                        ad = m68k_areg (regs, reg);
 
2388
                        break;
 
2389
    case 5:
 
2390
                        ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
 
2391
                        break;
 
2392
    case 6:
 
2393
                        ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
 
2394
                        break;
 
2395
    case 7:
 
2396
                        switch ((uae_u8)reg) {
 
2397
                                case 0:
 
2398
                            ad = (uae_s32) (uae_s16) next_iword();
 
2399
                                        break;
 
2400
                                case 1:
 
2401
                                        ad = next_ilong();
 
2402
                                        break;
 
2403
                                case 2:
 
2404
                                        ad = m68k_getpc ();
 
2405
                                        ad += (uae_s32) (uae_s16) next_iword();
 
2406
                                        break;
 
2407
                                case 3: {
 
2408
                                        uaecptr tmppc = m68k_getpc ();
 
2409
                                        uae_u16 tmp = (uae_u16)next_iword();
 
2410
                                        ad = get_disp_ea_020 (tmppc, tmp);
 
2411
                                        }
 
2412
                                        break;
 
2413
                                case 4:
 
2414
                                        ad = m68k_getpc ();
 
2415
                                        m68k_setpc (ad + sz2[size]);
 
2416
 
 
2417
                                        /*
 
2418
                                        +0000  000004  FSCALE.B   #$01,FP2     | F23C 5926 0001
 
2419
                                        F23C 1111001000111100
 
2420
                                        5926 0101100100100110
 
2421
                                        0001 0000000000000001
 
2422
                                        mode = 7
 
2423
                                        reg  = 4
 
2424
                                        size = 6
 
2425
                                        */
 
2426
                                        // Immediate addressing mode && Operation Length == Byte -> 
 
2427
                                        // Use the low-order byte of the extension word.
 
2428
 
 
2429
                                        if(size == 6) ad++;
 
2430
                                        
 
2431
                                        // May be faster on a PII(I), sz2[size] is already in register
 
2432
                                        // ad += sz2[size] - sz1[size];
 
2433
 
 
2434
                                        break;
 
2435
                                default:
 
2436
                                        return 0;
 
2437
                        }
 
2438
  }
 
2439
 
 
2440
  switch ((uae_u8)size) {
 
2441
    case 0:
 
2442
                        signed_to_extended( (uae_s32) get_long (ad), src );
 
2443
                        break;
 
2444
    case 1:
 
2445
                        to_single( get_long (ad), src );
 
2446
                        break;
 
2447
 
 
2448
    case 2:{
 
2449
            uae_u32 wrd1, wrd2, wrd3;
 
2450
            wrd1 = get_long (ad);
 
2451
            ad += 4;
 
2452
            wrd2 = get_long (ad);
 
2453
            ad += 4;
 
2454
            wrd3 = get_long (ad);
 
2455
                        to_exten( wrd1, wrd2, wrd3, src );
 
2456
                        }
 
2457
                        break;
 
2458
    case 3:{
 
2459
            uae_u32 wrd1, wrd2, wrd3;
 
2460
            wrd1 = get_long (ad);
 
2461
            ad += 4;
 
2462
            wrd2 = get_long (ad);
 
2463
            ad += 4;
 
2464
            wrd3 = get_long (ad);
 
2465
                        double_to_extended( to_pack(wrd1, wrd2, wrd3), src );
 
2466
                        }
 
2467
                        break;
 
2468
    case 4:
 
2469
                        signed_to_extended( (uae_s32)(uae_s16) get_word(ad), src );
 
2470
                        break;
 
2471
    case 5:{
 
2472
            uae_u32 wrd1, wrd2;
 
2473
            wrd1 = get_long (ad);
 
2474
            ad += 4;
 
2475
            wrd2 = get_long (ad);
 
2476
                        to_double(wrd1, wrd2, src);
 
2477
                        }
 
2478
                        break;
 
2479
    case 6:
 
2480
                        signed_to_extended( (uae_s32)(uae_s8) get_byte(ad), src );
 
2481
                        break;
 
2482
    default:
 
2483
                        return 0;
 
2484
  }
 
2485
 
 
2486
        // D(bug("get_fp_value result = %.04f\r\n",(float)*src));
 
2487
 
 
2488
  return 1;
 
2489
}
 
2490
 
 
2491
static int put_fp_value (float80 value, uae_u32 opcode, uae_u16 extra) REGPARAM;
 
2492
static int put_fp_value (float80 value, uae_u32 opcode, uae_u16 extra)
 
2493
{
 
2494
        // D(bug("put_fp_value(%.04f,%X,%X)\r\n",(float)value,(int)opcode,(int)extra));
 
2495
 
 
2496
  if ((extra & 0x4000) == 0) {
 
2497
                int dest_reg = (extra >> 10) & 7;
 
2498
                do_fmove( fp_reg[dest_reg], value );
 
2499
                build_ex_status();
 
2500
                return 1;
 
2501
  }
 
2502
 
 
2503
  int mode = (opcode >> 3) & 7;
 
2504
  int reg = opcode & 7;
 
2505
  int size = (extra >> 10) & 7;
 
2506
  uae_u32 ad = 0xffffffff;
 
2507
 
 
2508
        // Clear exception status
 
2509
        sw &= ~SW_EXCEPTION_MASK;
 
2510
 
 
2511
  switch ((uae_u8)mode) {
 
2512
    case 0:
 
2513
                        switch ((uae_u8)size) {
 
2514
                                case 6:
 
2515
                                        *((uae_u8 *)&m68k_dreg(regs, reg)) = extended_to_signed_8(value);
 
2516
                                        break;
 
2517
                                case 4:
 
2518
                                        // TODO_BIGENDIAN
 
2519
                                        *((uae_u16 *)&m68k_dreg(regs, reg)) = extended_to_signed_16(value);
 
2520
                                        break;
 
2521
                                case 0:
 
2522
                                        m68k_dreg (regs, reg) = extended_to_signed_32(value);
 
2523
                                        break;
 
2524
                                case 1:
 
2525
                                        m68k_dreg (regs, reg) = from_single(value);
 
2526
                                        break;
 
2527
                                default:
 
2528
                                        return 0;
 
2529
                        }
 
2530
                        return 1;
 
2531
                case 1:
 
2532
                        return 0;
 
2533
    case 2:
 
2534
                        ad = m68k_areg (regs, reg);
 
2535
                        break;
 
2536
    case 3:
 
2537
                        ad = m68k_areg (regs, reg);
 
2538
                        m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
 
2539
                        break;
 
2540
    case 4:
 
2541
                        m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
 
2542
                        ad = m68k_areg (regs, reg);
 
2543
                        break;
 
2544
    case 5:
 
2545
                        ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
 
2546
                        break;
 
2547
    case 6:
 
2548
                        ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
 
2549
                        break;
 
2550
    case 7:
 
2551
                        switch ((uae_u8)reg) {
 
2552
                                case 0:
 
2553
                                        ad = (uae_s32) (uae_s16) next_iword();
 
2554
                                        break;
 
2555
                                case 1:
 
2556
                                        ad = next_ilong();
 
2557
                                        break;
 
2558
                                case 2:
 
2559
                                        ad = m68k_getpc ();
 
2560
                                        ad += (uae_s32) (uae_s16) next_iword();
 
2561
                                        break;
 
2562
                                case 3: {
 
2563
                                        uaecptr tmppc = m68k_getpc ();
 
2564
                                        uae_u16 tmp = (uae_u16)next_iword();
 
2565
                                        ad = get_disp_ea_020 (tmppc, tmp);
 
2566
                                        }
 
2567
                                        break;
 
2568
                                case 4:
 
2569
                                        ad = m68k_getpc ();
 
2570
                                        m68k_setpc (ad + sz2[size]);
 
2571
                                        break;
 
2572
                                default:
 
2573
                                        return 0;
 
2574
                        }
 
2575
  }
 
2576
  switch ((uae_u8)size) {
 
2577
    case 0:
 
2578
                        put_long (ad, (uae_s32) extended_to_signed_32(value));
 
2579
                        break;
 
2580
    case 1:
 
2581
                        put_long (ad, from_single(value));
 
2582
                        break;
 
2583
                case 2: {
 
2584
                        uae_u32 wrd1, wrd2, wrd3;
 
2585
                        from_exten(value, &wrd1, &wrd2, &wrd3);
 
2586
                        
 
2587
                        sw &= ~SW_EXCEPTION_MASK;
 
2588
                        if(wrd3) { // TODO: not correct! Just a "smart" guess.
 
2589
                                sw |= SW_PE;
 
2590
                                sw_accrued |= SW_PE;
 
2591
                        }
 
2592
 
 
2593
                        put_long (ad, wrd1);
 
2594
                        ad += 4;
 
2595
                        put_long (ad, wrd2);
 
2596
                        ad += 4;
 
2597
                        put_long (ad, wrd3);
 
2598
                        }
 
2599
                        break;
 
2600
    case 3: {
 
2601
                        uae_u32 wrd1, wrd2, wrd3;
 
2602
                        from_pack(extended_to_double(value), &wrd1, &wrd2, &wrd3);
 
2603
                        put_long (ad, wrd1);
 
2604
                        ad += 4;
 
2605
                        put_long (ad, wrd2);
 
2606
                        ad += 4;
 
2607
                        put_long (ad, wrd3);
 
2608
                        }
 
2609
                        break;
 
2610
                case 4:
 
2611
                        put_word(ad, extended_to_signed_16(value));
 
2612
                        break;
 
2613
    case 5:{
 
2614
            uae_u32 wrd1, wrd2;
 
2615
            from_double(value, &wrd1, &wrd2);
 
2616
            put_long (ad, wrd1);
 
2617
            ad += 4;
 
2618
            put_long (ad, wrd2);
 
2619
                        }
 
2620
                        break;
 
2621
    case 6:
 
2622
                        put_byte(ad, extended_to_signed_8(value));
 
2623
 
 
2624
                        break;
 
2625
    default:
 
2626
                        return 0;
 
2627
  }
 
2628
  return 1;
 
2629
}
 
2630
 
 
2631
static int get_fp_ad(uae_u32 opcode, uae_u32 * ad) REGPARAM;
 
2632
static int get_fp_ad(uae_u32 opcode, uae_u32 * ad)
 
2633
{
 
2634
  int mode = (opcode >> 3) & 7;
 
2635
  int reg = opcode & 7;
 
2636
  switch ( (uae_u8)mode ) {
 
2637
    case 0:
 
2638
    case 1:
 
2639
        if( (opcode & 0xFF00) == 0xF300 ) {
 
2640
                // fsave, frestore
 
2641
                                m68k_setpc (m68k_getpc () - 2);
 
2642
        } else {
 
2643
                                m68k_setpc (m68k_getpc () - 4);
 
2644
        }
 
2645
                        op_illg (opcode);
 
2646
                        dump_fp_regs( "END  ");
 
2647
                        return 0;
 
2648
    case 2:
 
2649
                        *ad = m68k_areg (regs, reg);
 
2650
                        break;
 
2651
    case 3:
 
2652
                        *ad = m68k_areg (regs, reg);
 
2653
                        break;
 
2654
    case 4:
 
2655
                        *ad = m68k_areg (regs, reg);
 
2656
                        break;
 
2657
    case 5:
 
2658
                        *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
 
2659
                        break;
 
2660
    case 6:
 
2661
                        *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
 
2662
                        break;
 
2663
    case 7:
 
2664
                        switch ( (uae_u8)reg ) {
 
2665
                                case 0:
 
2666
                                        *ad = (uae_s32) (uae_s16) next_iword();
 
2667
                                        break;
 
2668
                                case 1:
 
2669
                                        *ad = next_ilong();
 
2670
                                        break;
 
2671
                                case 2:
 
2672
                                        *ad = m68k_getpc ();
 
2673
                                        *ad += (uae_s32) (uae_s16) next_iword();
 
2674
                                        break;
 
2675
                                case 3: {
 
2676
                                        uaecptr tmppc = m68k_getpc ();
 
2677
                                        uae_u16 tmp = (uae_u16)next_iword();
 
2678
                                        *ad = get_disp_ea_020 (tmppc, tmp);
 
2679
                                        }
 
2680
                                        break;
 
2681
                                default:
 
2682
                                        if( (opcode & 0xFF00) == 0xF300 ) {
 
2683
                                                // fsave, frestore
 
2684
                                                m68k_setpc (m68k_getpc () - 2);
 
2685
                                        } else {
 
2686
                                                m68k_setpc (m68k_getpc () - 4);
 
2687
                                        }
 
2688
                                        op_illg (opcode);
 
2689
                                        dump_fp_regs( "END  ");
 
2690
                                        return 0;
 
2691
                        }
 
2692
  }
 
2693
  return 1;
 
2694
}
 
2695
 
 
2696
static int fpp_cond(uae_u32 opcode, int condition) REGPARAM;
 
2697
static int fpp_cond(uae_u32 opcode, int condition)
 
2698
{
 
2699
 
 
2700
#define N                               (sw & SW_N)
 
2701
#define Z                               ((sw & (SW_Z_I_NAN_MASK)) == SW_Z)
 
2702
#define I                               ((sw & (SW_Z_I_NAN_MASK)) == (SW_I))
 
2703
#define NotANumber              ((sw & (SW_Z_I_NAN_MASK)) == SW_NAN)
 
2704
 
 
2705
  switch (condition) {
 
2706
                // Common Tests, no BSUN
 
2707
    case 0x01:
 
2708
                        CONDRET("Equal",Z);
 
2709
    case 0x0e:
 
2710
                        CONDRET("Not Equal",!Z);
 
2711
 
 
2712
                // IEEE Nonaware Tests, BSUN
 
2713
    case 0x12:
 
2714
                        SET_BSUN_ON_NAN();
 
2715
                        CONDRET("Greater Than",!(NotANumber || Z || N));
 
2716
    case 0x1d:
 
2717
                        SET_BSUN_ON_NAN();
 
2718
                        CONDRET("Not Greater Than",NotANumber || Z || N);
 
2719
    case 0x13:
 
2720
                        SET_BSUN_ON_NAN();
 
2721
                        CONDRET("Greater Than or Equal",Z || !(NotANumber || N));
 
2722
    case 0x1c:
 
2723
                        SET_BSUN_ON_NAN();
 
2724
                        CONDRET("Not Greater Than or Equal",!Z && (NotANumber || N));
 
2725
    case 0x14:
 
2726
                        SET_BSUN_ON_NAN();
 
2727
                        CONDRET("Less Than",N && !(NotANumber || Z));
 
2728
    case 0x1b:
 
2729
                        SET_BSUN_ON_NAN();
 
2730
                        CONDRET("Not Less Than",NotANumber || Z || !N);
 
2731
    case 0x15:
 
2732
                        SET_BSUN_ON_NAN();
 
2733
                        CONDRET("Less Than or Equal",Z || (N && !NotANumber));
 
2734
    case 0x1a:
 
2735
                        SET_BSUN_ON_NAN();
 
2736
                        CONDRET("Not Less Than or Equal",NotANumber || !(N || Z));
 
2737
    case 0x16:
 
2738
                        SET_BSUN_ON_NAN();
 
2739
                        CONDRET("Greater or Less Than",!(NotANumber || Z));
 
2740
    case 0x19:
 
2741
                        SET_BSUN_ON_NAN();
 
2742
                        CONDRET("Not Greater or Less Than",NotANumber || Z);
 
2743
    case 0x17:
 
2744
                        CONDRET("Greater, Less or Equal",!NotANumber);
 
2745
    case 0x18:
 
2746
                        SET_BSUN_ON_NAN();
 
2747
                        CONDRET("Not Greater, Less or Equal",NotANumber);
 
2748
 
 
2749
                // IEEE Aware Tests, no BSUN
 
2750
    case 0x02:
 
2751
                        CONDRET("Ordered Greater Than",!(NotANumber || Z || N));
 
2752
    case 0x0d:
 
2753
                        CONDRET("Unordered or Less or Equal",NotANumber || Z || N);
 
2754
    case 0x03:
 
2755
                        CONDRET("Ordered Greater Than or Equal",Z || !(NotANumber || N));
 
2756
    case 0x0c:
 
2757
                        CONDRET("Unordered or Less Than",NotANumber || (N && !Z));
 
2758
    case 0x04:
 
2759
                        CONDRET("Ordered Less Than",N && !(NotANumber || Z));
 
2760
    case 0x0b:
 
2761
                        CONDRET("Unordered or Greater or Equal",NotANumber || Z || !N);
 
2762
    case 0x05:
 
2763
                        CONDRET("Ordered Less Than or Equal",Z || (N && !NotANumber));
 
2764
    case 0x0a:
 
2765
                        CONDRET("Unordered or Greater Than",NotANumber || !(N || Z));
 
2766
    case 0x06:
 
2767
                        CONDRET("Ordered Greater or Less Than",!(NotANumber || Z));
 
2768
    case 0x09:
 
2769
                        CONDRET("Unordered or Equal",NotANumber || Z);
 
2770
    case 0x07:
 
2771
                        CONDRET("Ordered",!NotANumber);
 
2772
    case 0x08:
 
2773
                        CONDRET("Unordered",NotANumber);
 
2774
 
 
2775
                // Miscellaneous Tests, no BSUN
 
2776
    case 0x00:
 
2777
                        CONDRET("False",0);
 
2778
    case 0x0f:
 
2779
                        CONDRET("True",1);
 
2780
 
 
2781
                // Miscellaneous Tests, BSUN
 
2782
    case 0x10:
 
2783
                        SET_BSUN_ON_NAN();
 
2784
                        CONDRET("Signaling False",0);
 
2785
    case 0x1f:
 
2786
                        SET_BSUN_ON_NAN();
 
2787
                        CONDRET("Signaling True",1);
 
2788
    case 0x11:
 
2789
                        SET_BSUN_ON_NAN();
 
2790
                        CONDRET("Signaling Equal",Z);
 
2791
    case 0x1e:
 
2792
                        SET_BSUN_ON_NAN();
 
2793
                        CONDRET("Signaling Not Equal",!Z);
 
2794
  }
 
2795
        CONDRET("",-1);
 
2796
 
 
2797
#undef N
 
2798
#undef Z
 
2799
#undef I
 
2800
#undef NotANumber
 
2801
 
 
2802
}
 
2803
 
 
2804
void REGPARAM2 fdbcc_opp(uae_u32 opcode, uae_u16 extra)
 
2805
{
 
2806
  uaecptr pc = (uae_u32) m68k_getpc ();
 
2807
  uae_s32 disp = (uae_s32) (uae_s16) next_iword();
 
2808
  int cc;
 
2809
 
 
2810
  D(bug("fdbcc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ()));
 
2811
 
 
2812
  cc = fpp_cond(opcode, extra & 0x3f);
 
2813
  if (cc < 0) {
 
2814
                m68k_setpc (pc - 4);
 
2815
                op_illg (opcode);
 
2816
  } else if (!cc) {
 
2817
                int reg = opcode & 0x7;
 
2818
 
 
2819
                // TODO_BIGENDIAN
 
2820
                uae_u16 newv = (uae_u16)(m68k_dreg (regs, reg) & 0xffff) - 1;
 
2821
                *((uae_u16 *)&m68k_dreg(regs, reg)) = newv;
 
2822
 
 
2823
                if (newv != 0xffff)
 
2824
            m68k_setpc (pc + disp);
 
2825
  }
 
2826
}
 
2827
 
 
2828
void REGPARAM2 fscc_opp(uae_u32 opcode, uae_u16 extra)
 
2829
{
 
2830
  uae_u32 ad;
 
2831
  int cc;
 
2832
 
 
2833
  D(bug("fscc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ()));
 
2834
 
 
2835
  cc = fpp_cond(opcode, extra & 0x3f);
 
2836
  if (cc < 0) {
 
2837
                m68k_setpc (m68k_getpc () - 4);
 
2838
                op_illg (opcode);
 
2839
  } else if ((opcode & 0x38) == 0) {
 
2840
                // TODO_BIGENDIAN
 
2841
                m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) |
 
2842
            (cc ? 0xff : 0x00);
 
2843
  } else {
 
2844
                if (get_fp_ad(opcode, &ad)) {
 
2845
            put_byte(ad, cc ? 0xff : 0x00);
 
2846
          }
 
2847
  }
 
2848
}
 
2849
 
 
2850
void REGPARAM2 ftrapcc_opp(uae_u32 opcode, uaecptr oldpc)
 
2851
{
 
2852
  int cc;
 
2853
 
 
2854
  D(bug("ftrapcc_opp %X at %08lx\r\n", (uae_u32)opcode, m68k_getpc ()));
 
2855
 
 
2856
#if I3_ON_FTRAPCC
 
2857
#error "FIXME: _asm int 3"
 
2858
        _asm int 3
 
2859
#endif
 
2860
 
 
2861
        // This must be broken.
 
2862
  cc = fpp_cond(opcode, opcode & 0x3f);
 
2863
 
 
2864
  if (cc < 0) {
 
2865
                m68k_setpc (oldpc);
 
2866
                op_illg (opcode);
 
2867
  } else if (cc)
 
2868
                Exception(7, oldpc - 2);
 
2869
}
 
2870
 
 
2871
// NOTE that we get here also when there is a FNOP (nontrapping false, displ 0)
 
2872
void REGPARAM2 fbcc_opp(uae_u32 opcode, uaecptr pc, uae_u32 extra)
 
2873
{
 
2874
  int cc;
 
2875
 
 
2876
  D(bug("fbcc_opp %X, %X at %08lx, jumpto=%X\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc (), extra ));
 
2877
 
 
2878
  cc = fpp_cond(opcode, opcode & 0x3f);
 
2879
  if (cc < 0) {
 
2880
                m68k_setpc (pc);
 
2881
                op_illg (opcode);
 
2882
  } else if (cc) {
 
2883
                if ((opcode & 0x40) == 0)
 
2884
            extra = (uae_s32) (uae_s16) extra;
 
2885
                m68k_setpc (pc + extra);
 
2886
  }
 
2887
}
 
2888
 
 
2889
// FSAVE has no post-increment
 
2890
// 0x1f180000 == IDLE state frame, coprocessor version number 1F
 
2891
void REGPARAM2 fsave_opp(uae_u32 opcode)
 
2892
{
 
2893
  uae_u32 ad;
 
2894
  int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
 
2895
  int i;
 
2896
 
 
2897
  D(bug("fsave_opp at %08lx\r\n", m68k_getpc ()));
 
2898
 
 
2899
  if (get_fp_ad(opcode, &ad)) {
 
2900
                if (is_integral_68040_fpu) {
 
2901
                        // Put 4 byte 68040 IDLE frame.
 
2902
                        if (incr < 0) {
 
2903
                                ad -= 4;
 
2904
                                put_long (ad, 0x41000000);
 
2905
                        } else {
 
2906
                                put_long (ad, 0x41000000);
 
2907
                                ad += 4;
 
2908
                        }
 
2909
                } else {
 
2910
                        // Put 28 byte 68881 IDLE frame.
 
2911
                        if (incr < 0) {
 
2912
                                D(bug("fsave_opp pre-decrement\r\n"));
 
2913
                                ad -= 4;
 
2914
                                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
 
2915
                                put_long (ad, 0x70000000);
 
2916
                                for (i = 0; i < 5; i++) {
 
2917
                                        ad -= 4;
 
2918
                                        put_long (ad, 0x00000000);
 
2919
                                }
 
2920
                                ad -= 4;
 
2921
                                put_long (ad, 0x1f180000); // IDLE, vers 1f
 
2922
                        } else {
 
2923
                                put_long (ad, 0x1f180000); // IDLE, vers 1f
 
2924
                                ad += 4;
 
2925
                                for (i = 0; i < 5; i++) {
 
2926
                                        put_long (ad, 0x00000000);
 
2927
                                        ad += 4;
 
2928
                                }
 
2929
                                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
 
2930
                                put_long (ad, 0x70000000);
 
2931
                                ad += 4;
 
2932
                        }
 
2933
                }
 
2934
                if ((opcode & 0x38) == 0x18) {
 
2935
                        m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881
 
2936
                        D(bug("PROBLEM: fsave_opp post-increment\r\n"));
 
2937
                }
 
2938
                if ((opcode & 0x38) == 0x20) {
 
2939
                        m68k_areg (regs, opcode & 7) = ad;
 
2940
                        D(bug("fsave_opp pre-decrement %X -> A%d\r\n",ad,opcode & 7));
 
2941
                }
 
2942
  }
 
2943
}
 
2944
 
 
2945
static void do_null_frestore()
 
2946
{
 
2947
        // A null-restore operation sets FP7-FP0 positive, nonsignaling NANs.
 
2948
        for( int i=0; i<8; i++ ) {
 
2949
                MAKE_NAN( fp_reg[i] );
 
2950
        }
 
2951
 
 
2952
        regs.fpiar = 0;
 
2953
        regs.fpcr = 0;
 
2954
        regs.fpsr = 0;
 
2955
 
 
2956
        sw = SW_INITIAL;
 
2957
        sw_accrued = 0;
 
2958
        sw_quotient = 0;
 
2959
 
 
2960
        cw = CW_INITIAL;
 
2961
/*  _asm        FLDCW   cw
 
2962
        _asm    FNCLEX */
 
2963
        _ASM("fldcw %0\n\tfnclex" : : "m" (cw));
 
2964
}
 
2965
 
 
2966
// FSAVE has no pre-decrement
 
2967
void REGPARAM2 frestore_opp(uae_u32 opcode)
 
2968
{
 
2969
  uae_u32 ad;
 
2970
  uae_u32 d;
 
2971
  int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
 
2972
 
 
2973
  D(bug("frestore_opp at %08lx\r\n", m68k_getpc ()));
 
2974
 
 
2975
  if (get_fp_ad(opcode, &ad)) {
 
2976
                if (is_integral_68040_fpu) {
 
2977
                        // 68040
 
2978
                        if (incr < 0) {
 
2979
                                D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
 
2980
                                // this may be wrong, but it's never called.
 
2981
                                ad -= 4;
 
2982
                                d = get_long (ad);
 
2983
                                if ((d & 0xff000000) == 0) { // NULL
 
2984
                                        D(bug("frestore_opp found NULL frame at %X\r\n",ad-4));
 
2985
                                        do_null_frestore();
 
2986
                                } else if ((d & 0x00ff0000) == 0) { // IDLE
 
2987
                                        D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
 
2988
                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
 
2989
                                        D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
 
2990
                                        ad -= 44;
 
2991
                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
 
2992
                                        D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
 
2993
                                        ad -= 92;
 
2994
                                } else {
 
2995
                                        D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d));
 
2996
                                }
 
2997
                        } else {
 
2998
                                d = get_long (ad);
 
2999
                                D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
 
3000
                                ad += 4;
 
3001
                                if ((d & 0xff000000) == 0) { // NULL
 
3002
                                        D(bug("frestore_opp found NULL frame at %X\r\n",ad-4));
 
3003
                                        do_null_frestore();
 
3004
                                } else if ((d & 0x00ff0000) == 0) { // IDLE
 
3005
                                        D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
 
3006
                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
 
3007
                                        D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
 
3008
                                        ad += 44;
 
3009
                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
 
3010
                                        D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
 
3011
                                        ad += 92;
 
3012
                                } else {
 
3013
                                        D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d));
 
3014
                                }
 
3015
                        }
 
3016
                } else {
 
3017
                        // 68881
 
3018
                        if (incr < 0) {
 
3019
                                D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
 
3020
                                // this may be wrong, but it's never called.
 
3021
                                ad -= 4;
 
3022
                                d = get_long (ad);
 
3023
                                if ((d & 0xff000000) == 0) { // NULL
 
3024
                                        do_null_frestore();
 
3025
                                } else if ((d & 0x00ff0000) == 0x00180000) {
 
3026
                                        ad -= 6 * 4;
 
3027
                                } else if ((d & 0x00ff0000) == 0x00380000) {
 
3028
                                        ad -= 14 * 4;
 
3029
                                } else if ((d & 0x00ff0000) == 0x00b40000) {
 
3030
                                        ad -= 45 * 4;
 
3031
                                }
 
3032
                        } else {
 
3033
                                d = get_long (ad);
 
3034
                                D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
 
3035
                                ad += 4;
 
3036
                                if ((d & 0xff000000) == 0) { // NULL
 
3037
                                        D(bug("frestore_opp found NULL frame at %X\r\n",ad-4));
 
3038
                                        do_null_frestore();
 
3039
                                } else if ((d & 0x00ff0000) == 0x00180000) { // IDLE
 
3040
                                        D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
 
3041
                                        ad += 6 * 4;
 
3042
                                } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
 
3043
                                        ad += 14 * 4;
 
3044
                                        D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
 
3045
                                } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
 
3046
                                        D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
 
3047
                                        ad += 45 * 4;
 
3048
                                } else {
 
3049
                                        D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d));
 
3050
                                }
 
3051
                        }
 
3052
                }
 
3053
 
 
3054
                if ((opcode & 0x38) == 0x18) {
 
3055
                        m68k_areg (regs, opcode & 7) = ad;
 
3056
                        D(bug("frestore_opp post-increment %X -> A%d\r\n",ad,opcode & 7));
 
3057
                }
 
3058
                if ((opcode & 0x38) == 0x20) {
 
3059
                        m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881
 
3060
                        D(bug("PROBLEM: frestore_opp pre-decrement\r\n"));
 
3061
                }
 
3062
  }
 
3063
}
 
3064
 
 
3065
 
 
3066
/* ---------------------------- Old-style interface ---------------------------- */
 
3067
 
 
3068
// #ifndef OPTIMIZED_8BIT_MEMORY_ACCESS
 
3069
void REGPARAM2 fpp_opp(uae_u32 opcode, uae_u16 extra)
 
3070
{
 
3071
        uae_u32 mask = (extra & 0xFC7F) | ((opcode & 0x0038) << 4);
 
3072
        (*fpufunctbl[mask])(opcode,extra);
 
3073
}
 
3074
// #endif
 
3075
 
 
3076
 
 
3077
/* ---------------------------- Illegal ---------------------------- */
 
3078
 
 
3079
void REGPARAM2 fpuop_illg( uae_u32 opcode, uae_u16 extra )
 
3080
{
 
3081
        D(bug("ILLEGAL F OP 2 %X\r\n",opcode));
 
3082
 
 
3083
#if I3_ON_ILLEGAL_FPU_OP
 
3084
#error "FIXME: asm int 3"
 
3085
        _asm int 3
 
3086
#endif
 
3087
 
 
3088
        m68k_setpc (m68k_getpc () - 4);
 
3089
        op_illg (opcode);
 
3090
        dump_fp_regs( "END  ");
 
3091
}
 
3092
 
 
3093
 
 
3094
/* ---------------------------- FPP -> <ea> ---------------------------- */
 
3095
 
 
3096
void REGPARAM2 fpuop_fmove_2_ea( uae_u32 opcode, uae_u16 extra )
 
3097
{
 
3098
        D(bug("FMOVE -> <ea>\r\n"));
 
3099
 
 
3100
        if (put_fp_value (fp_reg[(extra >> 7) & 7], opcode, extra) == 0) {
 
3101
                m68k_setpc (m68k_getpc () - 4);
 
3102
                op_illg (opcode);
 
3103
        }
 
3104
 
 
3105
        /*
 
3106
        Needed (among other things) by some Pack5/Elems68k transcendental
 
3107
        functions, they require the ACCR_INEX flag after a "MOVE.D, Dreg".
 
3108
        However, now put_fp_value() is responsible of clearing the exceptions
 
3109
        and merging statuses.
 
3110
        */
 
3111
 
 
3112
        /*
 
3113
        WORD sw_temp;
 
3114
        _asm FNSTSW sw_temp
 
3115
        if(sw_temp & SW_PE) {
 
3116
                _asm FNCLEX
 
3117
                sw |= SW_PE;
 
3118
                sw_accrued |= SW_PE;
 
3119
        }
 
3120
        */
 
3121
 
 
3122
        dump_fp_regs( "END  ");
 
3123
}
 
3124
 
 
3125
 
 
3126
/* ---------------------------- CONTROL REGS -> Dreg ---------------------------- */
 
3127
 
 
3128
void REGPARAM2 fpuop_fmovem_none_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3129
{
 
3130
        D(bug("FMOVEM control(none) -> D%d\r\n", opcode & 7));
 
3131
        dump_fp_regs( "END  ");
 
3132
}
 
3133
 
 
3134
void REGPARAM2 fpuop_fmovem_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3135
{
 
3136
        D(bug("FMOVEM regs.fpiar (%X) -> D%d\r\n", regs.fpiar, opcode & 7));
 
3137
        m68k_dreg (regs, opcode & 7) = regs.fpiar;
 
3138
        dump_fp_regs( "END  ");
 
3139
}
 
3140
 
 
3141
void REGPARAM2 fpuop_fmovem_fpsr_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3142
{
 
3143
        to_fpsr();
 
3144
        D(bug("FMOVEM regs.fpsr (%X) -> D%d\r\n", regs.fpsr, opcode & 7));
 
3145
        m68k_dreg (regs, opcode & 7) = regs.fpsr;
 
3146
        dump_fp_regs( "END  ");
 
3147
}
 
3148
 
 
3149
void REGPARAM2 fpuop_fmovem_fpcr_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3150
{
 
3151
        D(bug("FMOVEM regs.fpcr (%X) -> D%d\r\n", regs.fpcr, opcode & 7));
 
3152
        m68k_dreg (regs, opcode & 7) = regs.fpcr;
 
3153
        dump_fp_regs( "END  ");
 
3154
}
 
3155
 
 
3156
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3157
{
 
3158
        to_fpsr();
 
3159
        D(bug("FMOVEM regs.fpsr (%X) -> D%d\r\n", regs.fpsr, opcode & 7));
 
3160
        m68k_dreg (regs, opcode & 7) = regs.fpsr;
 
3161
        D(bug("FMOVEM regs.fpiar (%X) -> D%d\r\n", regs.fpiar, opcode & 7));
 
3162
        m68k_dreg (regs, opcode & 7) = regs.fpiar;
 
3163
        dump_fp_regs( "END  ");
 
3164
}
 
3165
 
 
3166
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3167
{
 
3168
        D(bug("FMOVEM regs.fpcr (%X) -> D%d\r\n", regs.fpcr, opcode & 7));
 
3169
        m68k_dreg (regs, opcode & 7) = regs.fpcr;
 
3170
        D(bug("FMOVEM regs.fpiar (%X) -> D%d\r\n", regs.fpiar, opcode & 7));
 
3171
        m68k_dreg (regs, opcode & 7) = regs.fpiar;
 
3172
        dump_fp_regs( "END  ");
 
3173
}
 
3174
 
 
3175
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3176
{
 
3177
        D(bug("FMOVEM regs.fpcr (%X) -> D%d\r\n", regs.fpcr, opcode & 7));
 
3178
        m68k_dreg (regs, opcode & 7) = regs.fpcr;
 
3179
        to_fpsr();
 
3180
        D(bug("FMOVEM regs.fpsr (%X) -> D%d\r\n", regs.fpsr, opcode & 7));
 
3181
        m68k_dreg (regs, opcode & 7) = regs.fpsr;
 
3182
        dump_fp_regs( "END  ");
 
3183
}
 
3184
 
 
3185
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
 
3186
{
 
3187
        D(bug("FMOVEM regs.fpcr (%X) -> D%d\r\n", regs.fpcr, opcode & 7));
 
3188
        m68k_dreg (regs, opcode & 7) = regs.fpcr;
 
3189
        to_fpsr();
 
3190
        D(bug("FMOVEM regs.fpsr (%X) -> D%d\r\n", regs.fpsr, opcode & 7));
 
3191
        m68k_dreg (regs, opcode & 7) = regs.fpsr;
 
3192
        D(bug("FMOVEM regs.fpiar (%X) -> D%d\r\n", regs.fpiar, opcode & 7));
 
3193
        m68k_dreg (regs, opcode & 7) = regs.fpiar;
 
3194
        dump_fp_regs( "END  ");
 
3195
}
 
3196
 
 
3197
 
 
3198
/* ---------------------------- Dreg -> CONTROL REGS ---------------------------- */
 
3199
 
 
3200
void REGPARAM2 fpuop_fmovem_Dreg_2_none( uae_u32 opcode, uae_u16 extra )
 
3201
{
 
3202
        D(bug("FMOVEM D%d -> control(none)\r\n", opcode & 7));
 
3203
        dump_fp_regs( "END  ");
 
3204
}
 
3205
 
 
3206
void REGPARAM2 fpuop_fmovem_Dreg_2_fpiar( uae_u32 opcode, uae_u16 extra )
 
3207
{
 
3208
        regs.fpiar = m68k_dreg (regs, opcode & 7);
 
3209
        D(bug("FMOVEM D%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3210
        dump_fp_regs( "END  ");
 
3211
}
 
3212
 
 
3213
void REGPARAM2 fpuop_fmovem_Dreg_2_fpsr( uae_u32 opcode, uae_u16 extra )
 
3214
{
 
3215
        regs.fpsr = m68k_dreg (regs, opcode & 7);
 
3216
        from_fpsr();
 
3217
        D(bug("FMOVEM D%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3218
        dump_fp_regs( "END  ");
 
3219
}
 
3220
 
 
3221
void REGPARAM2 fpuop_fmovem_Dreg_2_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
 
3222
{
 
3223
        regs.fpsr = m68k_dreg (regs, opcode & 7);
 
3224
        from_fpsr();
 
3225
        D(bug("FMOVEM D%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3226
        regs.fpiar = m68k_dreg (regs, opcode & 7);
 
3227
        D(bug("FMOVEM D%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3228
        dump_fp_regs( "END  ");
 
3229
}
 
3230
 
 
3231
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr( uae_u32 opcode, uae_u16 extra )
 
3232
{
 
3233
        regs.fpcr = m68k_dreg (regs, opcode & 7);
 
3234
        set_host_fpu_control_word();
 
3235
        D(bug("FMOVEM D%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3236
        dump_fp_regs( "END  ");
 
3237
}
 
3238
 
 
3239
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr_fpiar( uae_u32 opcode, uae_u16 extra )
 
3240
{
 
3241
        regs.fpcr = m68k_dreg (regs, opcode & 7);
 
3242
        set_host_fpu_control_word();
 
3243
        D(bug("FMOVEM D%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3244
        regs.fpiar = m68k_dreg (regs, opcode & 7);
 
3245
        D(bug("FMOVEM D%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3246
        dump_fp_regs( "END  ");
 
3247
}
 
3248
 
 
3249
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr_fpsr( uae_u32 opcode, uae_u16 extra )
 
3250
{
 
3251
        regs.fpcr = m68k_dreg (regs, opcode & 7);
 
3252
        set_host_fpu_control_word();
 
3253
        D(bug("FMOVEM D%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3254
        regs.fpsr = m68k_dreg (regs, opcode & 7);
 
3255
        from_fpsr();
 
3256
        D(bug("FMOVEM D%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3257
        dump_fp_regs( "END  ");
 
3258
}
 
3259
 
 
3260
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
 
3261
{
 
3262
        regs.fpcr = m68k_dreg (regs, opcode & 7);
 
3263
        set_host_fpu_control_word();
 
3264
        D(bug("FMOVEM D%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3265
        regs.fpsr = m68k_dreg (regs, opcode & 7);
 
3266
        from_fpsr();
 
3267
        D(bug("FMOVEM D%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3268
        regs.fpiar = m68k_dreg (regs, opcode & 7);
 
3269
        D(bug("FMOVEM D%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3270
        dump_fp_regs( "END  ");
 
3271
}
 
3272
 
 
3273
 
 
3274
/* ---------------------------- CONTROL REGS -> Areg ---------------------------- */
 
3275
 
 
3276
void REGPARAM2 fpuop_fmovem_none_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3277
{
 
3278
        D(bug("FMOVEM control(none) -> A%d\r\n", opcode & 7));
 
3279
        dump_fp_regs( "END  ");
 
3280
}
 
3281
 
 
3282
void REGPARAM2 fpuop_fmovem_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3283
{
 
3284
        D(bug("FMOVEM regs.fpiar (%X) -> A%d\r\n", regs.fpiar, opcode & 7));
 
3285
        m68k_areg (regs, opcode & 7) = regs.fpiar;
 
3286
        dump_fp_regs( "END  ");
 
3287
}
 
3288
 
 
3289
void REGPARAM2 fpuop_fmovem_fpsr_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3290
{
 
3291
        to_fpsr();
 
3292
        D(bug("FMOVEM regs.fpsr (%X) -> A%d\r\n", regs.fpsr, opcode & 7));
 
3293
        m68k_areg (regs, opcode & 7) = regs.fpsr;
 
3294
        dump_fp_regs( "END  ");
 
3295
}
 
3296
 
 
3297
void REGPARAM2 fpuop_fmovem_fpcr_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3298
{
 
3299
        D(bug("FMOVEM regs.fpcr (%X) -> A%d\r\n", regs.fpcr, opcode & 7));
 
3300
        m68k_areg (regs, opcode & 7) = regs.fpcr;
 
3301
        dump_fp_regs( "END  ");
 
3302
}
 
3303
 
 
3304
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3305
{
 
3306
        to_fpsr();
 
3307
        D(bug("FMOVEM regs.fpsr (%X) -> A%d\r\n", regs.fpsr, opcode & 7));
 
3308
        m68k_areg (regs, opcode & 7) = regs.fpsr;
 
3309
        D(bug("FMOVEM regs.fpiar (%X) -> A%d\r\n", regs.fpiar, opcode & 7));
 
3310
        m68k_areg (regs, opcode & 7) = regs.fpiar;
 
3311
        dump_fp_regs( "END  ");
 
3312
}
 
3313
 
 
3314
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3315
{
 
3316
        D(bug("FMOVEM regs.fpcr (%X) -> A%d\r\n", regs.fpcr, opcode & 7));
 
3317
        m68k_areg (regs, opcode & 7) = regs.fpcr;
 
3318
        D(bug("FMOVEM regs.fpiar (%X) -> A%d\r\n", regs.fpiar, opcode & 7));
 
3319
        m68k_areg (regs, opcode & 7) = regs.fpiar;
 
3320
        dump_fp_regs( "END  ");
 
3321
}
 
3322
 
 
3323
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3324
{
 
3325
        D(bug("FMOVEM regs.fpcr (%X) -> A%d\r\n", regs.fpcr, opcode & 7));
 
3326
        m68k_areg (regs, opcode & 7) = regs.fpcr;
 
3327
        to_fpsr();
 
3328
        D(bug("FMOVEM regs.fpsr (%X) -> A%d\r\n", regs.fpsr, opcode & 7));
 
3329
        m68k_areg (regs, opcode & 7) = regs.fpsr;
 
3330
        dump_fp_regs( "END  ");
 
3331
}
 
3332
 
 
3333
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
 
3334
{
 
3335
        D(bug("FMOVEM regs.fpcr (%X) -> A%d\r\n", regs.fpcr, opcode & 7));
 
3336
        m68k_areg (regs, opcode & 7) = regs.fpcr;
 
3337
        to_fpsr();
 
3338
        D(bug("FMOVEM regs.fpsr (%X) -> A%d\r\n", regs.fpsr, opcode & 7));
 
3339
        m68k_areg (regs, opcode & 7) = regs.fpsr;
 
3340
        D(bug("FMOVEM regs.fpiar (%X) -> A%d\r\n", regs.fpiar, opcode & 7));
 
3341
        m68k_areg (regs, opcode & 7) = regs.fpiar;
 
3342
        dump_fp_regs( "END  ");
 
3343
}
 
3344
 
 
3345
 
 
3346
/* ---------------------------- Areg -> CONTROL REGS ---------------------------- */
 
3347
 
 
3348
void REGPARAM2 fpuop_fmovem_Areg_2_none( uae_u32 opcode, uae_u16 extra )
 
3349
{
 
3350
        D(bug("FMOVEM A%d -> control(none)\r\n", opcode & 7));
 
3351
        dump_fp_regs( "END  ");
 
3352
}
 
3353
 
 
3354
void REGPARAM2 fpuop_fmovem_Areg_2_fpiar( uae_u32 opcode, uae_u16 extra )
 
3355
{
 
3356
        regs.fpiar = m68k_areg (regs, opcode & 7);
 
3357
        D(bug("FMOVEM A%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3358
        dump_fp_regs( "END  ");
 
3359
}
 
3360
 
 
3361
void REGPARAM2 fpuop_fmovem_Areg_2_fpsr( uae_u32 opcode, uae_u16 extra )
 
3362
{
 
3363
        regs.fpsr = m68k_areg (regs, opcode & 7);
 
3364
        from_fpsr();
 
3365
        D(bug("FMOVEM A%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3366
        dump_fp_regs( "END  ");
 
3367
}
 
3368
 
 
3369
void REGPARAM2 fpuop_fmovem_Areg_2_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
 
3370
{
 
3371
        regs.fpsr = m68k_areg (regs, opcode & 7);
 
3372
        from_fpsr();
 
3373
        D(bug("FMOVEM A%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3374
        regs.fpiar = m68k_areg (regs, opcode & 7);
 
3375
        D(bug("FMOVEM A%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3376
        dump_fp_regs( "END  ");
 
3377
}
 
3378
 
 
3379
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr( uae_u32 opcode, uae_u16 extra )
 
3380
{
 
3381
        regs.fpcr = m68k_areg (regs, opcode & 7);
 
3382
        set_host_fpu_control_word();
 
3383
        D(bug("FMOVEM A%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3384
        dump_fp_regs( "END  ");
 
3385
}
 
3386
 
 
3387
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr_fpiar( uae_u32 opcode, uae_u16 extra )
 
3388
{
 
3389
        regs.fpcr = m68k_areg (regs, opcode & 7);
 
3390
        set_host_fpu_control_word();
 
3391
        D(bug("FMOVEM A%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3392
        regs.fpiar = m68k_areg (regs, opcode & 7);
 
3393
        D(bug("FMOVEM A%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3394
        dump_fp_regs( "END  ");
 
3395
}
 
3396
 
 
3397
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr_fpsr( uae_u32 opcode, uae_u16 extra )
 
3398
{
 
3399
        regs.fpcr = m68k_areg (regs, opcode & 7);
 
3400
        set_host_fpu_control_word();
 
3401
        D(bug("FMOVEM A%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3402
        regs.fpsr = m68k_areg (regs, opcode & 7);
 
3403
        from_fpsr();
 
3404
        D(bug("FMOVEM A%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3405
        dump_fp_regs( "END  ");
 
3406
}
 
3407
 
 
3408
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
 
3409
{
 
3410
        regs.fpcr = m68k_areg (regs, opcode & 7);
 
3411
        set_host_fpu_control_word();
 
3412
        D(bug("FMOVEM A%d (%X) -> regs.fpcr\r\n", opcode & 7, regs.fpcr));
 
3413
        regs.fpsr = m68k_areg (regs, opcode & 7);
 
3414
        from_fpsr();
 
3415
        D(bug("FMOVEM A%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
 
3416
        regs.fpiar = m68k_areg (regs, opcode & 7);
 
3417
        D(bug("FMOVEM A%d (%X) -> regs.fpiar\r\n", opcode & 7, regs.fpiar));
 
3418
        dump_fp_regs( "END  ");
 
3419
}
 
3420
 
 
3421
 
 
3422
/* ---------------------------- CONTROL REGS -> --MEMORY---------------------------- */
 
3423
 
 
3424
void REGPARAM2 fpuop_fmovem_none_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3425
{
 
3426
        D(bug("FMOVEM Control regs (none) -> mem\r\n" ));
 
3427
        dump_fp_regs( "END  ");
 
3428
}
 
3429
 
 
3430
void REGPARAM2 fpuop_fmovem_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3431
{
 
3432
        uae_u32 ad;
 
3433
        if (get_fp_ad(opcode, &ad)) {
 
3434
                ad -= 4;
 
3435
                put_long (ad, regs.fpiar);
 
3436
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad ));
 
3437
                m68k_areg (regs, opcode & 7) = ad;
 
3438
                dump_fp_regs( "END  ");
 
3439
        }
 
3440
}
 
3441
 
 
3442
void REGPARAM2 fpuop_fmovem_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3443
{
 
3444
        uae_u32 ad;
 
3445
        if (get_fp_ad(opcode, &ad)) {
 
3446
                ad -= 4;
 
3447
                to_fpsr();
 
3448
                put_long (ad, regs.fpsr);
 
3449
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad ));
 
3450
                m68k_areg (regs, opcode & 7) = ad;
 
3451
                dump_fp_regs( "END  ");
 
3452
        }
 
3453
}
 
3454
 
 
3455
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3456
{
 
3457
        uae_u32 ad;
 
3458
        if (get_fp_ad(opcode, &ad)) {
 
3459
                ad -= 8;
 
3460
                to_fpsr();
 
3461
                put_long (ad, regs.fpsr);
 
3462
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad ));
 
3463
                put_long (ad+4, regs.fpiar);
 
3464
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+4 ));
 
3465
                m68k_areg (regs, opcode & 7) = ad;
 
3466
                dump_fp_regs( "END  ");
 
3467
        }
 
3468
}
 
3469
 
 
3470
void REGPARAM2 fpuop_fmovem_fpcr_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3471
{
 
3472
        uae_u32 ad;
 
3473
        if (get_fp_ad(opcode, &ad)) {
 
3474
                ad -= 4;
 
3475
                put_long (ad, regs.fpcr);
 
3476
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3477
                m68k_areg (regs, opcode & 7) = ad;
 
3478
                dump_fp_regs( "END  ");
 
3479
        }
 
3480
}
 
3481
 
 
3482
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3483
{
 
3484
        uae_u32 ad;
 
3485
        if (get_fp_ad(opcode, &ad)) {
 
3486
                ad -= 8;
 
3487
                put_long (ad, regs.fpcr);
 
3488
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3489
                put_long (ad+4, regs.fpiar);
 
3490
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+4 ));
 
3491
                m68k_areg (regs, opcode & 7) = ad;
 
3492
                dump_fp_regs( "END  ");
 
3493
        }
 
3494
}
 
3495
 
 
3496
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3497
{
 
3498
        uae_u32 ad;
 
3499
        if (get_fp_ad(opcode, &ad)) {
 
3500
                ad -= 8;
 
3501
                put_long (ad, regs.fpcr);
 
3502
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3503
                to_fpsr();
 
3504
                put_long (ad+4, regs.fpsr);
 
3505
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad+4 ));
 
3506
                m68k_areg (regs, opcode & 7) = ad;
 
3507
                dump_fp_regs( "END  ");
 
3508
        }
 
3509
}
 
3510
 
 
3511
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
 
3512
{
 
3513
        uae_u32 ad;
 
3514
        if (get_fp_ad(opcode, &ad)) {
 
3515
                ad -= 12;
 
3516
                put_long (ad, regs.fpcr);
 
3517
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3518
                to_fpsr();
 
3519
                put_long (ad+4, regs.fpsr);
 
3520
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad+4 ));
 
3521
                put_long (ad+8, regs.fpiar);
 
3522
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+8 ));
 
3523
                m68k_areg (regs, opcode & 7) = ad;
 
3524
                dump_fp_regs( "END  ");
 
3525
        }
 
3526
}
 
3527
 
 
3528
 
 
3529
/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */
 
3530
 
 
3531
void REGPARAM2 fpuop_fmovem_none_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3532
{
 
3533
        D(bug("FMOVEM Control regs (none) -> mem\r\n" ));
 
3534
        dump_fp_regs( "END  ");
 
3535
}
 
3536
 
 
3537
void REGPARAM2 fpuop_fmovem_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3538
{
 
3539
        uae_u32 ad;
 
3540
        if (get_fp_ad(opcode, &ad)) {
 
3541
                put_long (ad, regs.fpiar);
 
3542
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad ));
 
3543
                m68k_areg (regs, opcode & 7) = ad+4;
 
3544
                dump_fp_regs( "END  ");
 
3545
        }
 
3546
}
 
3547
 
 
3548
void REGPARAM2 fpuop_fmovem_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3549
{
 
3550
        uae_u32 ad;
 
3551
        if (get_fp_ad(opcode, &ad)) {
 
3552
                to_fpsr();
 
3553
                put_long (ad, regs.fpsr);
 
3554
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad ));
 
3555
                m68k_areg (regs, opcode & 7) = ad+4;
 
3556
                dump_fp_regs( "END  ");
 
3557
        }
 
3558
}
 
3559
 
 
3560
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3561
{
 
3562
        uae_u32 ad;
 
3563
        if (get_fp_ad(opcode, &ad)) {
 
3564
                to_fpsr();
 
3565
                put_long (ad, regs.fpsr);
 
3566
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad ));
 
3567
                put_long (ad+4, regs.fpiar);
 
3568
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+4 ));
 
3569
                m68k_areg (regs, opcode & 7) = ad+8;
 
3570
                dump_fp_regs( "END  ");
 
3571
        }
 
3572
}
 
3573
 
 
3574
void REGPARAM2 fpuop_fmovem_fpcr_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3575
{
 
3576
        uae_u32 ad;
 
3577
        if (get_fp_ad(opcode, &ad)) {
 
3578
                put_long (ad, regs.fpcr);
 
3579
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3580
                m68k_areg (regs, opcode & 7) = ad+4;
 
3581
                dump_fp_regs( "END  ");
 
3582
        }
 
3583
}
 
3584
 
 
3585
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3586
{
 
3587
        uae_u32 ad;
 
3588
        if (get_fp_ad(opcode, &ad)) {
 
3589
                put_long (ad, regs.fpcr);
 
3590
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3591
                put_long (ad+4, regs.fpiar);
 
3592
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+4 ));
 
3593
                m68k_areg (regs, opcode & 7) = ad+8;
 
3594
                dump_fp_regs( "END  ");
 
3595
        }
 
3596
}
 
3597
 
 
3598
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3599
{
 
3600
        dump_fp_regs( "END  ");
 
3601
        uae_u32 ad;
 
3602
        if (get_fp_ad(opcode, &ad)) {
 
3603
                put_long (ad, regs.fpcr);
 
3604
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3605
                to_fpsr();
 
3606
                put_long (ad+4, regs.fpsr);
 
3607
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad+4 ));
 
3608
                m68k_areg (regs, opcode & 7) = ad+8;
 
3609
        }
 
3610
}
 
3611
 
 
3612
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
 
3613
{
 
3614
        uae_u32 ad;
 
3615
        if (get_fp_ad(opcode, &ad)) {
 
3616
                put_long (ad, regs.fpcr);
 
3617
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3618
                to_fpsr();
 
3619
                put_long (ad+4, regs.fpsr);
 
3620
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad+4 ));
 
3621
                put_long (ad+8, regs.fpiar);
 
3622
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+8 ));
 
3623
                m68k_areg (regs, opcode & 7) = ad+12;
 
3624
                dump_fp_regs( "END  ");
 
3625
        }
 
3626
}
 
3627
 
 
3628
 
 
3629
/* ---------------------------- CONTROL REGS -> MEMORY ---------------------------- */
 
3630
 
 
3631
void REGPARAM2 fpuop_fmovem_none_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3632
{
 
3633
        D(bug("FMOVEM Control regs (none) -> mem\r\n" ));
 
3634
        dump_fp_regs( "END  ");
 
3635
}
 
3636
 
 
3637
void REGPARAM2 fpuop_fmovem_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3638
{
 
3639
        uae_u32 ad;
 
3640
        if (get_fp_ad(opcode, &ad)) {
 
3641
                put_long (ad, regs.fpiar);
 
3642
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad ));
 
3643
                dump_fp_regs( "END  ");
 
3644
        }
 
3645
}
 
3646
 
 
3647
void REGPARAM2 fpuop_fmovem_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3648
{
 
3649
        uae_u32 ad;
 
3650
        if (get_fp_ad(opcode, &ad)) {
 
3651
                to_fpsr();
 
3652
                put_long (ad, regs.fpsr);
 
3653
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad ));
 
3654
                dump_fp_regs( "END  ");
 
3655
        }
 
3656
}
 
3657
 
 
3658
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3659
{
 
3660
        uae_u32 ad;
 
3661
        if (get_fp_ad(opcode, &ad)) {
 
3662
                to_fpsr();
 
3663
                put_long (ad, regs.fpsr);
 
3664
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad ));
 
3665
                put_long (ad+4, regs.fpiar);
 
3666
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+4 ));
 
3667
                dump_fp_regs( "END  ");
 
3668
        }
 
3669
}
 
3670
 
 
3671
void REGPARAM2 fpuop_fmovem_fpcr_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3672
{
 
3673
        uae_u32 ad;
 
3674
        if (get_fp_ad(opcode, &ad)) {
 
3675
                put_long (ad, regs.fpcr);
 
3676
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3677
                dump_fp_regs( "END  ");
 
3678
        }
 
3679
}
 
3680
 
 
3681
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3682
{
 
3683
        uae_u32 ad;
 
3684
        if (get_fp_ad(opcode, &ad)) {
 
3685
                put_long (ad, regs.fpcr);
 
3686
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3687
                put_long (ad+4, regs.fpiar);
 
3688
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+4 ));
 
3689
                dump_fp_regs( "END  ");
 
3690
        }
 
3691
}
 
3692
 
 
3693
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3694
{
 
3695
        uae_u32 ad;
 
3696
        if (get_fp_ad(opcode, &ad)) {
 
3697
                put_long (ad, regs.fpcr);
 
3698
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3699
                to_fpsr();
 
3700
                put_long (ad+4, regs.fpsr);
 
3701
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad+4 ));
 
3702
                dump_fp_regs( "END  ");
 
3703
        }
 
3704
}
 
3705
 
 
3706
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3707
{
 
3708
        uae_u32 ad;
 
3709
        if (get_fp_ad(opcode, &ad)) {
 
3710
                put_long (ad, regs.fpcr);
 
3711
                D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
 
3712
                to_fpsr();
 
3713
                put_long (ad+4, regs.fpsr);
 
3714
                D(bug("FMOVEM regs.fpsr (%X) -> mem %X\r\n", regs.fpsr, ad+4 ));
 
3715
                put_long (ad+8, regs.fpiar);
 
3716
                D(bug("FMOVEM regs.fpiar (%X) -> mem %X\r\n", regs.fpiar, ad+8 ));
 
3717
                dump_fp_regs( "END  ");
 
3718
        }
 
3719
}
 
3720
 
 
3721
 
 
3722
/* ---------------------------- --MEMORY -> CONTROL REGS ---------------------------- */
 
3723
 
 
3724
void REGPARAM2 fpuop_fmovem_Mem_2_none_predecrement( uae_u32 opcode, uae_u16 extra )
 
3725
{
 
3726
        D(bug("FMOVEM --Mem -> control(none)\r\n"));
 
3727
        dump_fp_regs( "END  ");
 
3728
}
 
3729
 
 
3730
void REGPARAM2 fpuop_fmovem_Mem_2_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
 
3731
{
 
3732
        uae_u32 ad;
 
3733
        if (get_fp_ad(opcode, &ad)) {
 
3734
                ad -= 4;
 
3735
                regs.fpiar = get_long (ad);
 
3736
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad, regs.fpiar ));
 
3737
                m68k_areg (regs, opcode & 7) = ad;
 
3738
                dump_fp_regs( "END  ");
 
3739
        }
 
3740
}
 
3741
 
 
3742
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_predecrement( uae_u32 opcode, uae_u16 extra )
 
3743
{
 
3744
        uae_u32 ad;
 
3745
        if (get_fp_ad(opcode, &ad)) {
 
3746
                ad -= 4;
 
3747
                regs.fpsr = get_long (ad);
 
3748
                from_fpsr();
 
3749
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad, regs.fpsr ));
 
3750
                m68k_areg (regs, opcode & 7) = ad;
 
3751
                dump_fp_regs( "END  ");
 
3752
        }
 
3753
}
 
3754
 
 
3755
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
 
3756
{
 
3757
        uae_u32 ad;
 
3758
        if (get_fp_ad(opcode, &ad)) {
 
3759
                ad -= 8;
 
3760
                regs.fpsr = get_long (ad);
 
3761
                from_fpsr();
 
3762
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad, regs.fpsr ));
 
3763
                regs.fpiar = get_long (ad+4);
 
3764
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+4, regs.fpiar ));
 
3765
                m68k_areg (regs, opcode & 7) = ad;
 
3766
                dump_fp_regs( "END  ");
 
3767
        }
 
3768
}
 
3769
 
 
3770
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_predecrement( uae_u32 opcode, uae_u16 extra )
 
3771
{
 
3772
        uae_u32 ad;
 
3773
        if (get_fp_ad(opcode, &ad)) {
 
3774
                ad -= 4;
 
3775
                regs.fpcr = get_long (ad);
 
3776
                set_host_fpu_control_word();
 
3777
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3778
                m68k_areg (regs, opcode & 7) = ad;
 
3779
                dump_fp_regs( "END  ");
 
3780
        }
 
3781
}
 
3782
 
 
3783
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
 
3784
{
 
3785
        uae_u32 ad;
 
3786
        if (get_fp_ad(opcode, &ad)) {
 
3787
                ad -= 8;
 
3788
                regs.fpcr = get_long (ad);
 
3789
                set_host_fpu_control_word();
 
3790
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3791
                regs.fpiar = get_long (ad+4);
 
3792
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+4, regs.fpiar ));
 
3793
                m68k_areg (regs, opcode & 7) = ad;
 
3794
                dump_fp_regs( "END  ");
 
3795
        }
 
3796
}
 
3797
 
 
3798
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement( uae_u32 opcode, uae_u16 extra )
 
3799
{
 
3800
        uae_u32 ad;
 
3801
        if (get_fp_ad(opcode, &ad)) {
 
3802
                ad -= 8;
 
3803
                regs.fpcr = get_long (ad);
 
3804
                set_host_fpu_control_word();
 
3805
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3806
                regs.fpsr = get_long (ad+4);
 
3807
                from_fpsr();
 
3808
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad+4, regs.fpsr ));
 
3809
                m68k_areg (regs, opcode & 7) = ad;
 
3810
                dump_fp_regs( "END  ");
 
3811
        }
 
3812
}
 
3813
 
 
3814
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
 
3815
{
 
3816
        uae_u32 ad;
 
3817
        if (get_fp_ad(opcode, &ad)) {
 
3818
                ad -= 12;
 
3819
                regs.fpcr = get_long (ad);
 
3820
                set_host_fpu_control_word();
 
3821
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3822
                regs.fpsr = get_long (ad+4);
 
3823
                from_fpsr();
 
3824
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad+4, regs.fpsr ));
 
3825
                regs.fpiar = get_long (ad+8);
 
3826
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+8, regs.fpiar ));
 
3827
                m68k_areg (regs, opcode & 7) = ad;
 
3828
                dump_fp_regs( "END  ");
 
3829
        }
 
3830
}
 
3831
 
 
3832
 
 
3833
/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */
 
3834
 
 
3835
void REGPARAM2 fpuop_fmovem_Mem_2_none_postincrement( uae_u32 opcode, uae_u16 extra )
 
3836
{
 
3837
        D(bug("FMOVEM Mem++ -> control(none)\r\n"));
 
3838
        dump_fp_regs( "END  ");
 
3839
}
 
3840
 
 
3841
void REGPARAM2 fpuop_fmovem_Mem_2_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
 
3842
{
 
3843
        uae_u32 ad;
 
3844
        if (get_fp_ad(opcode, &ad)) {
 
3845
                regs.fpiar = get_long (ad);
 
3846
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad, regs.fpiar ));
 
3847
                m68k_areg (regs, opcode & 7) = ad+4;
 
3848
                dump_fp_regs( "END  ");
 
3849
        }
 
3850
}
 
3851
 
 
3852
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_postincrement( uae_u32 opcode, uae_u16 extra )
 
3853
{
 
3854
        uae_u32 ad;
 
3855
        if (get_fp_ad(opcode, &ad)) {
 
3856
                regs.fpsr = get_long (ad);
 
3857
                from_fpsr();
 
3858
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad, regs.fpsr ));
 
3859
                m68k_areg (regs, opcode & 7) = ad+4;
 
3860
                dump_fp_regs( "END  ");
 
3861
        }
 
3862
}
 
3863
 
 
3864
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
 
3865
{
 
3866
        uae_u32 ad;
 
3867
        if (get_fp_ad(opcode, &ad)) {
 
3868
                regs.fpsr = get_long (ad);
 
3869
                from_fpsr();
 
3870
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad, regs.fpsr ));
 
3871
                regs.fpiar = get_long (ad+4);
 
3872
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+4, regs.fpiar ));
 
3873
                m68k_areg (regs, opcode & 7) = ad+8;
 
3874
                dump_fp_regs( "END  ");
 
3875
        }
 
3876
}
 
3877
 
 
3878
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_postincrement( uae_u32 opcode, uae_u16 extra )
 
3879
{
 
3880
        uae_u32 ad;
 
3881
        if (get_fp_ad(opcode, &ad)) {
 
3882
                regs.fpcr = get_long (ad);
 
3883
                set_host_fpu_control_word();
 
3884
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3885
                m68k_areg (regs, opcode & 7) = ad+4;
 
3886
                dump_fp_regs( "END  ");
 
3887
        }
 
3888
}
 
3889
 
 
3890
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
 
3891
{
 
3892
        uae_u32 ad;
 
3893
        if (get_fp_ad(opcode, &ad)) {
 
3894
                regs.fpcr = get_long (ad);
 
3895
                set_host_fpu_control_word();
 
3896
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3897
                regs.fpiar = get_long (ad+4);
 
3898
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+4, regs.fpiar ));
 
3899
                m68k_areg (regs, opcode & 7) = ad+8;
 
3900
                dump_fp_regs( "END  ");
 
3901
        }
 
3902
}
 
3903
 
 
3904
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement( uae_u32 opcode, uae_u16 extra )
 
3905
{
 
3906
        uae_u32 ad;
 
3907
        if (get_fp_ad(opcode, &ad)) {
 
3908
                regs.fpcr = get_long (ad);
 
3909
                set_host_fpu_control_word();
 
3910
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3911
                regs.fpsr = get_long (ad+4);
 
3912
                from_fpsr();
 
3913
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad+4, regs.fpsr ));
 
3914
                m68k_areg (regs, opcode & 7) = ad+8;
 
3915
                dump_fp_regs( "END  ");
 
3916
        }
 
3917
}
 
3918
 
 
3919
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
 
3920
{
 
3921
        uae_u32 ad;
 
3922
        if (get_fp_ad(opcode, &ad)) {
 
3923
                regs.fpcr = get_long (ad);
 
3924
                set_host_fpu_control_word();
 
3925
                D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
3926
                regs.fpsr = get_long (ad+4);
 
3927
                from_fpsr();
 
3928
                D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad+4, regs.fpsr ));
 
3929
                regs.fpiar = get_long (ad+8);
 
3930
                D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+8, regs.fpiar ));
 
3931
                m68k_areg (regs, opcode & 7) = ad+12;
 
3932
                dump_fp_regs( "END  ");
 
3933
        }
 
3934
}
 
3935
 
 
3936
 
 
3937
/* ----------------------------   MEMORY -> CONTROL REGS  ---------------------------- */
 
3938
/* ----------------------------            and            ---------------------------- */
 
3939
/* ---------------------------- IMMEDIATE -> CONTROL REGS ---------------------------- */
 
3940
 
 
3941
void REGPARAM2 fpuop_fmovem_Mem_2_none_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3942
{
 
3943
        D(bug("FMOVEM Mem -> control(none)\r\n"));
 
3944
        dump_fp_regs( "END  ");
 
3945
}
 
3946
 
 
3947
void REGPARAM2 fpuop_fmovem_Mem_2_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3948
{
 
3949
        if ((opcode & 0x3f) == 0x3c) {
 
3950
                regs.fpiar = next_ilong();
 
3951
                D(bug("FMOVEM #<%X> -> regs.fpiar\r\n", regs.fpiar));
 
3952
        } else {
 
3953
                uae_u32 ad;
 
3954
                if (get_fp_ad(opcode, &ad)) {
 
3955
                        regs.fpiar = get_long (ad);
 
3956
                        D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad, regs.fpiar ));
 
3957
                }
 
3958
        }
 
3959
        dump_fp_regs( "END  ");
 
3960
}
 
3961
 
 
3962
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3963
{
 
3964
        if ((opcode & 0x3f) == 0x3c) {
 
3965
                regs.fpsr = next_ilong();
 
3966
                from_fpsr();
 
3967
                D(bug("FMOVEM #<%X> -> regs.fpsr\r\n", regs.fpsr));
 
3968
        } else {
 
3969
                uae_u32 ad;
 
3970
                if (get_fp_ad(opcode, &ad)) {
 
3971
                        regs.fpsr = get_long (ad);
 
3972
                        from_fpsr();
 
3973
                        D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad, regs.fpsr ));
 
3974
                }
 
3975
        }
 
3976
        dump_fp_regs( "END  ");
 
3977
}
 
3978
 
 
3979
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
3980
{
 
3981
        if ((opcode & 0x3f) == 0x3c) {
 
3982
                regs.fpsr = next_ilong();
 
3983
                from_fpsr();
 
3984
                D(bug("FMOVEM #<%X> -> regs.fpsr\r\n", regs.fpsr));
 
3985
                regs.fpiar = next_ilong();
 
3986
                D(bug("FMOVEM #<%X> -> regs.fpiar\r\n", regs.fpiar));
 
3987
        } else {
 
3988
                uae_u32 ad;
 
3989
                if (get_fp_ad(opcode, &ad)) {
 
3990
                        regs.fpsr = get_long (ad);
 
3991
                        from_fpsr();
 
3992
                        D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad, regs.fpsr ));
 
3993
                        regs.fpiar = get_long (ad+4);
 
3994
                        D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+4, regs.fpiar ));
 
3995
                }
 
3996
        }
 
3997
        dump_fp_regs( "END  ");
 
3998
}
 
3999
 
 
4000
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_2_Mem( uae_u32 opcode, uae_u16 extra )
 
4001
{
 
4002
        if ((opcode & 0x3f) == 0x3c) {
 
4003
                regs.fpcr = next_ilong();
 
4004
                set_host_fpu_control_word();
 
4005
                D(bug("FMOVEM #<%X> -> regs.fpcr\r\n", regs.fpcr));
 
4006
        } else {
 
4007
                uae_u32 ad;
 
4008
                if (get_fp_ad(opcode, &ad)) {
 
4009
                        regs.fpcr = get_long (ad);
 
4010
                        set_host_fpu_control_word();
 
4011
                        D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
4012
                }
 
4013
        }
 
4014
        dump_fp_regs( "END  ");
 
4015
}
 
4016
 
 
4017
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
4018
{
 
4019
        if ((opcode & 0x3f) == 0x3c) {
 
4020
                regs.fpcr = next_ilong();
 
4021
                set_host_fpu_control_word();
 
4022
                D(bug("FMOVEM #<%X> -> regs.fpcr\r\n", regs.fpcr));
 
4023
                regs.fpiar = next_ilong();
 
4024
                D(bug("FMOVEM #<%X> -> regs.fpiar\r\n", regs.fpiar));
 
4025
        } else {
 
4026
                uae_u32 ad;
 
4027
                if (get_fp_ad(opcode, &ad)) {
 
4028
                        regs.fpcr = get_long (ad);
 
4029
                        set_host_fpu_control_word();
 
4030
                        D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
4031
                        regs.fpiar = get_long (ad+4);
 
4032
                        D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+4, regs.fpiar ));
 
4033
                }
 
4034
        }
 
4035
        dump_fp_regs( "END  ");
 
4036
}
 
4037
 
 
4038
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
 
4039
{
 
4040
        if ((opcode & 0x3f) == 0x3c) {
 
4041
                regs.fpcr = next_ilong();
 
4042
                set_host_fpu_control_word();
 
4043
                D(bug("FMOVEM #<%X> -> regs.fpcr\r\n", regs.fpcr));
 
4044
                regs.fpsr = next_ilong();
 
4045
                from_fpsr();
 
4046
                D(bug("FMOVEM #<%X> -> regs.fpsr\r\n", regs.fpsr));
 
4047
        } else {
 
4048
                uae_u32 ad;
 
4049
                if (get_fp_ad(opcode, &ad)) {
 
4050
                        regs.fpcr = get_long (ad);
 
4051
                        set_host_fpu_control_word();
 
4052
                        D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
4053
                        regs.fpsr = get_long (ad+4);
 
4054
                        from_fpsr();
 
4055
                        D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad+4, regs.fpsr ));
 
4056
                }
 
4057
        }
 
4058
        dump_fp_regs( "END  ");
 
4059
}
 
4060
 
 
4061
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
 
4062
{
 
4063
        if ((opcode & 0x3f) == 0x3c) {
 
4064
                regs.fpcr = next_ilong();
 
4065
                set_host_fpu_control_word();
 
4066
                D(bug("FMOVEM #<%X> -> regs.fpcr\r\n", regs.fpcr));
 
4067
                regs.fpsr = next_ilong();
 
4068
                from_fpsr();
 
4069
                D(bug("FMOVEM #<%X> -> regs.fpsr\r\n", regs.fpsr));
 
4070
                regs.fpiar = next_ilong();
 
4071
                D(bug("FMOVEM #<%X> -> regs.fpiar\r\n", regs.fpiar));
 
4072
        } else {
 
4073
                uae_u32 ad;
 
4074
                if (get_fp_ad(opcode, &ad)) {
 
4075
                        regs.fpcr = get_long (ad);
 
4076
                        set_host_fpu_control_word();
 
4077
                        D(bug("FMOVEM mem %X (%X) -> regs.fpcr\r\n", ad, regs.fpcr ));
 
4078
                        regs.fpsr = get_long (ad+4);
 
4079
                        from_fpsr();
 
4080
                        D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad+4, regs.fpsr ));
 
4081
                        regs.fpiar = get_long (ad+8);
 
4082
                        D(bug("FMOVEM mem %X (%X) -> regs.fpiar\r\n", ad+8, regs.fpiar ));
 
4083
                }
 
4084
        }
 
4085
        dump_fp_regs( "END  ");
 
4086
}
 
4087
 
 
4088
 
 
4089
/* ---------------------------- FMOVEM MEMORY -> FPP ---------------------------- */
 
4090
 
 
4091
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_pred_postincrement( uae_u32 opcode, uae_u16 extra )
 
4092
{
 
4093
        uae_u32 ad, list = extra & 0xff;
 
4094
        D(bug("FMOVEM memory->FPP\r\n"));
 
4095
        if (get_fp_ad(opcode, &ad)) {
 
4096
                for( int reg=7; reg>=0; reg-- ) {
 
4097
                        uae_u32 wrd1, wrd2, wrd3;
 
4098
                        if( list & 0x80 ) {
 
4099
                                ad -= 4;
 
4100
                                wrd3 = get_long (ad);
 
4101
                                ad -= 4;
 
4102
                                wrd2 = get_long (ad);
 
4103
                                ad -= 4;
 
4104
                                wrd1 = get_long (ad);
 
4105
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4106
                        }
 
4107
                        list <<= 1;
 
4108
                }
 
4109
                m68k_areg (regs, opcode & 7) = ad;
 
4110
                dump_fp_regs( "END  ");
 
4111
        }
 
4112
}
 
4113
 
 
4114
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_pred_predecrement( uae_u32 opcode, uae_u16 extra )
 
4115
{
 
4116
        uae_u32 ad, list = extra & 0xff;
 
4117
        D(bug("FMOVEM memory->FPP\r\n"));
 
4118
        if (get_fp_ad(opcode, &ad)) {
 
4119
                for( int reg=7; reg>=0; reg-- ) {
 
4120
                        uae_u32 wrd1, wrd2, wrd3;
 
4121
                        if( list & 0x80 ) {
 
4122
                                ad -= 4;
 
4123
                                wrd3 = get_long (ad);
 
4124
                                ad -= 4;
 
4125
                                wrd2 = get_long (ad);
 
4126
                                ad -= 4;
 
4127
                                wrd1 = get_long (ad);
 
4128
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4129
                        }
 
4130
                        list <<= 1;
 
4131
                }
 
4132
                m68k_areg (regs, opcode & 7) = ad;
 
4133
                dump_fp_regs( "END  ");
 
4134
        }
 
4135
}
 
4136
 
 
4137
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_pred( uae_u32 opcode, uae_u16 extra )
 
4138
{
 
4139
        uae_u32 ad, list = extra & 0xff;
 
4140
        D(bug("FMOVEM memory->FPP\r\n"));
 
4141
        if (get_fp_ad(opcode, &ad)) {
 
4142
                for( int reg=7; reg>=0; reg-- ) {
 
4143
                        uae_u32 wrd1, wrd2, wrd3;
 
4144
                        if( list & 0x80 ) {
 
4145
                                ad -= 4;
 
4146
                                wrd3 = get_long (ad);
 
4147
                                ad -= 4;
 
4148
                                wrd2 = get_long (ad);
 
4149
                                ad -= 4;
 
4150
                                wrd1 = get_long (ad);
 
4151
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4152
                        }
 
4153
                        list <<= 1;
 
4154
                }
 
4155
                dump_fp_regs( "END  ");
 
4156
        }
 
4157
}
 
4158
 
 
4159
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement( uae_u32 opcode, uae_u16 extra )
 
4160
{
 
4161
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4162
        D(bug("FMOVEM memory->FPP\r\n"));
 
4163
        if (get_fp_ad(opcode, &ad)) {
 
4164
                for( int reg=7; reg>=0; reg-- ) {
 
4165
                        uae_u32 wrd1, wrd2, wrd3;
 
4166
                        if( list & 0x80 ) {
 
4167
                                ad -= 4;
 
4168
                                wrd3 = get_long (ad);
 
4169
                                ad -= 4;
 
4170
                                wrd2 = get_long (ad);
 
4171
                                ad -= 4;
 
4172
                                wrd1 = get_long (ad);
 
4173
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4174
                        }
 
4175
                        list <<= 1;
 
4176
                }
 
4177
                m68k_areg (regs, opcode & 7) = ad;
 
4178
                dump_fp_regs( "END  ");
 
4179
        }
 
4180
}
 
4181
 
 
4182
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement( uae_u32 opcode, uae_u16 extra )
 
4183
{
 
4184
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4185
        D(bug("FMOVEM memory->FPP\r\n"));
 
4186
        if (get_fp_ad(opcode, &ad)) {
 
4187
                for( int reg=7; reg>=0; reg-- ) {
 
4188
                        uae_u32 wrd1, wrd2, wrd3;
 
4189
                        if( list & 0x80 ) {
 
4190
                                ad -= 4;
 
4191
                                wrd3 = get_long (ad);
 
4192
                                ad -= 4;
 
4193
                                wrd2 = get_long (ad);
 
4194
                                ad -= 4;
 
4195
                                wrd1 = get_long (ad);
 
4196
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4197
                        }
 
4198
                        list <<= 1;
 
4199
                }
 
4200
                m68k_areg (regs, opcode & 7) = ad;
 
4201
                dump_fp_regs( "END  ");
 
4202
        }
 
4203
}
 
4204
 
 
4205
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_pred( uae_u32 opcode, uae_u16 extra )
 
4206
{
 
4207
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4208
        D(bug("FMOVEM memory->FPP\r\n"));
 
4209
        if (get_fp_ad(opcode, &ad)) {
 
4210
                for( int reg=7; reg>=0; reg-- ) {
 
4211
                        uae_u32 wrd1, wrd2, wrd3;
 
4212
                        if( list & 0x80 ) {
 
4213
                                ad -= 4;
 
4214
                                wrd3 = get_long (ad);
 
4215
                                ad -= 4;
 
4216
                                wrd2 = get_long (ad);
 
4217
                                ad -= 4;
 
4218
                                wrd1 = get_long (ad);
 
4219
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4220
                        }
 
4221
                        list <<= 1;
 
4222
                }
 
4223
                dump_fp_regs( "END  ");
 
4224
        }
 
4225
}
 
4226
 
 
4227
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
 
4228
{
 
4229
        uae_u32 ad, list = extra & 0xff;
 
4230
        D(bug("FMOVEM memory->FPP\r\n"));
 
4231
        if (get_fp_ad(opcode, &ad)) {
 
4232
                for( int reg=0; reg<8; reg++ ) {
 
4233
                        uae_u32 wrd1, wrd2, wrd3;
 
4234
                        if( list & 0x80 ) {
 
4235
                                wrd1 = get_long (ad);
 
4236
                                ad += 4;
 
4237
                                wrd2 = get_long (ad);
 
4238
                                ad += 4;
 
4239
                                wrd3 = get_long (ad);
 
4240
                                ad += 4;
 
4241
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4242
                        }
 
4243
                        list <<= 1;
 
4244
                }
 
4245
                m68k_areg (regs, opcode & 7) = ad;
 
4246
                dump_fp_regs( "END  ");
 
4247
        }
 
4248
}
 
4249
 
 
4250
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
 
4251
{
 
4252
        uae_u32 ad, list = extra & 0xff;
 
4253
        D(bug("FMOVEM memory->FPP\r\n"));
 
4254
        if (get_fp_ad(opcode, &ad)) {
 
4255
                for( int reg=0; reg<8; reg++ ) {
 
4256
                        uae_u32 wrd1, wrd2, wrd3;
 
4257
                        if( list & 0x80 ) {
 
4258
                                wrd1 = get_long (ad);
 
4259
                                ad += 4;
 
4260
                                wrd2 = get_long (ad);
 
4261
                                ad += 4;
 
4262
                                wrd3 = get_long (ad);
 
4263
                                ad += 4;
 
4264
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4265
                        }
 
4266
                        list <<= 1;
 
4267
                }
 
4268
                m68k_areg (regs, opcode & 7) = ad;
 
4269
                dump_fp_regs( "END  ");
 
4270
        }
 
4271
}
 
4272
 
 
4273
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_postinc( uae_u32 opcode, uae_u16 extra )
 
4274
{
 
4275
        uae_u32 ad, list = extra & 0xff;
 
4276
        D(bug("FMOVEM memory->FPP\r\n"));
 
4277
        if (get_fp_ad(opcode, &ad)) {
 
4278
                for( int reg=0; reg<8; reg++ ) {
 
4279
                        uae_u32 wrd1, wrd2, wrd3;
 
4280
                        if( list & 0x80 ) {
 
4281
                                wrd1 = get_long (ad);
 
4282
                                ad += 4;
 
4283
                                wrd2 = get_long (ad);
 
4284
                                ad += 4;
 
4285
                                wrd3 = get_long (ad);
 
4286
                                ad += 4;
 
4287
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4288
                        }
 
4289
                        list <<= 1;
 
4290
                }
 
4291
                dump_fp_regs( "END  ");
 
4292
        }
 
4293
}
 
4294
 
 
4295
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
 
4296
{
 
4297
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4298
        D(bug("FMOVEM memory->FPP\r\n"));
 
4299
        if (get_fp_ad(opcode, &ad)) {
 
4300
                for( int reg=0; reg<8; reg++ ) {
 
4301
                        uae_u32 wrd1, wrd2, wrd3;
 
4302
                        if( list & 0x80 ) {
 
4303
                                wrd1 = get_long (ad);
 
4304
                                ad += 4;
 
4305
                                wrd2 = get_long (ad);
 
4306
                                ad += 4;
 
4307
                                wrd3 = get_long (ad);
 
4308
                                ad += 4;
 
4309
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4310
                        }
 
4311
                        list <<= 1;
 
4312
                }
 
4313
                m68k_areg (regs, opcode & 7) = ad;
 
4314
                dump_fp_regs( "END  ");
 
4315
        }
 
4316
}
 
4317
 
 
4318
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
 
4319
{
 
4320
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4321
        D(bug("FMOVEM memory->FPP\r\n"));
 
4322
        if (get_fp_ad(opcode, &ad)) {
 
4323
                for( int reg=0; reg<8; reg++ ) {
 
4324
                        uae_u32 wrd1, wrd2, wrd3;
 
4325
                        if( list & 0x80 ) {
 
4326
                                wrd1 = get_long (ad);
 
4327
                                ad += 4;
 
4328
                                wrd2 = get_long (ad);
 
4329
                                ad += 4;
 
4330
                                wrd3 = get_long (ad);
 
4331
                                ad += 4;
 
4332
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4333
                        }
 
4334
                        list <<= 1;
 
4335
                }
 
4336
                m68k_areg (regs, opcode & 7) = ad;
 
4337
                dump_fp_regs( "END  ");
 
4338
        }
 
4339
}
 
4340
 
 
4341
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_postinc( uae_u32 opcode, uae_u16 extra )
 
4342
{
 
4343
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4344
        D(bug("FMOVEM memory->FPP\r\n"));
 
4345
        if (get_fp_ad(opcode, &ad)) {
 
4346
                for( int reg=0; reg<8; reg++ ) {
 
4347
                        uae_u32 wrd1, wrd2, wrd3;
 
4348
                        if( list & 0x80 ) {
 
4349
                                wrd1 = get_long (ad);
 
4350
                                ad += 4;
 
4351
                                wrd2 = get_long (ad);
 
4352
                                ad += 4;
 
4353
                                wrd3 = get_long (ad);
 
4354
                                ad += 4;
 
4355
                                to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
 
4356
                        }
 
4357
                        list <<= 1;
 
4358
                }
 
4359
                dump_fp_regs( "END  ");
 
4360
        }
 
4361
}
 
4362
 
 
4363
 
 
4364
/* ---------------------------- FPP -> FMOVEM MEMORY ---------------------------- */
 
4365
 
 
4366
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_pred_postincrement( uae_u32 opcode, uae_u16 extra )
 
4367
{
 
4368
        uae_u32 ad, list = extra & 0xff;
 
4369
        D(bug("FMOVEM FPP->memory\r\n"));
 
4370
        if (get_fp_ad(opcode, &ad)) {
 
4371
                for( int reg=7; reg>=0; reg-- ) {
 
4372
                        uae_u32 wrd1, wrd2, wrd3;
 
4373
                        if( list & 0x80 ) {
 
4374
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4375
                                ad -= 4;
 
4376
                                put_long (ad, wrd3);
 
4377
                                ad -= 4;
 
4378
                                put_long (ad, wrd2);
 
4379
                                ad -= 4;
 
4380
                                put_long (ad, wrd1);
 
4381
                        }
 
4382
                        list <<= 1;
 
4383
                }
 
4384
                m68k_areg (regs, opcode & 7) = ad;
 
4385
                dump_fp_regs( "END  ");
 
4386
        }
 
4387
}
 
4388
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_pred_predecrement( uae_u32 opcode, uae_u16 extra )
 
4389
{
 
4390
        uae_u32 ad, list = extra & 0xff;
 
4391
        D(bug("FMOVEM FPP->memory\r\n"));
 
4392
        if (get_fp_ad(opcode, &ad)) {
 
4393
                for( int reg=7; reg>=0; reg-- ) {
 
4394
                        uae_u32 wrd1, wrd2, wrd3;
 
4395
                        if( list & 0x80 ) {
 
4396
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4397
                                ad -= 4;
 
4398
                                put_long (ad, wrd3);
 
4399
                                ad -= 4;
 
4400
                                put_long (ad, wrd2);
 
4401
                                ad -= 4;
 
4402
                                put_long (ad, wrd1);
 
4403
                        }
 
4404
                        list <<= 1;
 
4405
                }
 
4406
                m68k_areg (regs, opcode & 7) = ad;
 
4407
                dump_fp_regs( "END  ");
 
4408
        }
 
4409
}
 
4410
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_pred( uae_u32 opcode, uae_u16 extra )
 
4411
{
 
4412
        uae_u32 ad, list = extra & 0xff;
 
4413
        D(bug("FMOVEM FPP->memory\r\n"));
 
4414
        if (get_fp_ad(opcode, &ad)) {
 
4415
                for( int reg=7; reg>=0; reg-- ) {
 
4416
                        uae_u32 wrd1, wrd2, wrd3;
 
4417
                        if( list & 0x80 ) {
 
4418
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4419
                                ad -= 4;
 
4420
                                put_long (ad, wrd3);
 
4421
                                ad -= 4;
 
4422
                                put_long (ad, wrd2);
 
4423
                                ad -= 4;
 
4424
                                put_long (ad, wrd1);
 
4425
                        }
 
4426
                        list <<= 1;
 
4427
                }
 
4428
                dump_fp_regs( "END  ");
 
4429
        }
 
4430
}
 
4431
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement( uae_u32 opcode, uae_u16 extra )
 
4432
{
 
4433
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4434
        D(bug("FMOVEM FPP->memory\r\n"));
 
4435
        if (get_fp_ad(opcode, &ad)) {
 
4436
                for( int reg=7; reg>=0; reg-- ) {
 
4437
                        uae_u32 wrd1, wrd2, wrd3;
 
4438
                        if( list & 0x80 ) {
 
4439
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4440
                                ad -= 4;
 
4441
                                put_long (ad, wrd3);
 
4442
                                ad -= 4;
 
4443
                                put_long (ad, wrd2);
 
4444
                                ad -= 4;
 
4445
                                put_long (ad, wrd1);
 
4446
                        }
 
4447
                        list <<= 1;
 
4448
                }
 
4449
                m68k_areg (regs, opcode & 7) = ad;
 
4450
                dump_fp_regs( "END  ");
 
4451
        }
 
4452
}
 
4453
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement( uae_u32 opcode, uae_u16 extra )
 
4454
{
 
4455
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4456
        D(bug("FMOVEM FPP->memory\r\n"));
 
4457
        if (get_fp_ad(opcode, &ad)) {
 
4458
                for( int reg=7; reg>=0; reg-- ) {
 
4459
                        uae_u32 wrd1, wrd2, wrd3;
 
4460
                        if( list & 0x80 ) {
 
4461
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4462
                                ad -= 4;
 
4463
                                put_long (ad, wrd3);
 
4464
                                ad -= 4;
 
4465
                                put_long (ad, wrd2);
 
4466
                                ad -= 4;
 
4467
                                put_long (ad, wrd1);
 
4468
                        }
 
4469
                        list <<= 1;
 
4470
                }
 
4471
                m68k_areg (regs, opcode & 7) = ad;
 
4472
                dump_fp_regs( "END  ");
 
4473
        }
 
4474
}
 
4475
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_pred( uae_u32 opcode, uae_u16 extra )
 
4476
{
 
4477
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4478
        D(bug("FMOVEM FPP->memory\r\n"));
 
4479
        if (get_fp_ad(opcode, &ad)) {
 
4480
                for( int reg=7; reg>=0; reg-- ) {
 
4481
                        uae_u32 wrd1, wrd2, wrd3;
 
4482
                        if( list & 0x80 ) {
 
4483
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4484
                                ad -= 4;
 
4485
                                put_long (ad, wrd3);
 
4486
                                ad -= 4;
 
4487
                                put_long (ad, wrd2);
 
4488
                                ad -= 4;
 
4489
                                put_long (ad, wrd1);
 
4490
                        }
 
4491
                        list <<= 1;
 
4492
                }
 
4493
                dump_fp_regs( "END  ");
 
4494
        }
 
4495
}
 
4496
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
 
4497
{
 
4498
        uae_u32 ad, list = extra & 0xff;
 
4499
        D(bug("FMOVEM FPP->memory\r\n"));
 
4500
        if (get_fp_ad(opcode, &ad)) {
 
4501
                for( int reg=0; reg<8; reg++ ) {
 
4502
                        uae_u32 wrd1, wrd2, wrd3;
 
4503
                        if( list & 0x80 ) {
 
4504
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4505
                                put_long (ad, wrd1);
 
4506
                                ad += 4;
 
4507
                                put_long (ad, wrd2);
 
4508
                                ad += 4;
 
4509
                                put_long (ad, wrd3);
 
4510
                                ad += 4;
 
4511
                        }
 
4512
                        list <<= 1;
 
4513
                }
 
4514
                m68k_areg (regs, opcode & 7) = ad;
 
4515
                dump_fp_regs( "END  ");
 
4516
        }
 
4517
}
 
4518
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
 
4519
{
 
4520
        uae_u32 ad, list = extra & 0xff;
 
4521
        D(bug("FMOVEM FPP->memory\r\n"));
 
4522
        if (get_fp_ad(opcode, &ad)) {
 
4523
                for( int reg=0; reg<8; reg++ ) {
 
4524
                        uae_u32 wrd1, wrd2, wrd3;
 
4525
                        if( list & 0x80 ) {
 
4526
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4527
                                put_long (ad, wrd1);
 
4528
                                ad += 4;
 
4529
                                put_long (ad, wrd2);
 
4530
                                ad += 4;
 
4531
                                put_long (ad, wrd3);
 
4532
                                ad += 4;
 
4533
                        }
 
4534
                        list <<= 1;
 
4535
                }
 
4536
                m68k_areg (regs, opcode & 7) = ad;
 
4537
                dump_fp_regs( "END  ");
 
4538
        }
 
4539
}
 
4540
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_postinc( uae_u32 opcode, uae_u16 extra )
 
4541
{
 
4542
        uae_u32 ad, list = extra & 0xff;
 
4543
        D(bug("FMOVEM FPP->memory\r\n"));
 
4544
        if (get_fp_ad(opcode, &ad)) {
 
4545
                for( int reg=0; reg<8; reg++ ) {
 
4546
                        uae_u32 wrd1, wrd2, wrd3;
 
4547
                        if( list & 0x80 ) {
 
4548
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4549
                                put_long (ad, wrd1);
 
4550
                                ad += 4;
 
4551
                                put_long (ad, wrd2);
 
4552
                                ad += 4;
 
4553
                                put_long (ad, wrd3);
 
4554
                                ad += 4;
 
4555
                        }
 
4556
                        list <<= 1;
 
4557
                }
 
4558
                dump_fp_regs( "END  ");
 
4559
        }
 
4560
}
 
4561
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
 
4562
{
 
4563
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4564
        D(bug("FMOVEM FPP->memory\r\n"));
 
4565
        if (get_fp_ad(opcode, &ad)) {
 
4566
                for( int reg=0; reg<8; reg++ ) {
 
4567
                        uae_u32 wrd1, wrd2, wrd3;
 
4568
                        if( list & 0x80 ) {
 
4569
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4570
                                put_long (ad, wrd1);
 
4571
                                ad += 4;
 
4572
                                put_long (ad, wrd2);
 
4573
                                ad += 4;
 
4574
                                put_long (ad, wrd3);
 
4575
                                ad += 4;
 
4576
                        }
 
4577
                        list <<= 1;
 
4578
                }
 
4579
                m68k_areg (regs, opcode & 7) = ad;
 
4580
                dump_fp_regs( "END  ");
 
4581
        }
 
4582
}
 
4583
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
 
4584
{
 
4585
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4586
        D(bug("FMOVEM FPP->memory\r\n"));
 
4587
        if (get_fp_ad(opcode, &ad)) {
 
4588
                for( int reg=0; reg<8; reg++ ) {
 
4589
                        uae_u32 wrd1, wrd2, wrd3;
 
4590
                        if( list & 0x80 ) {
 
4591
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4592
                                put_long (ad, wrd1);
 
4593
                                ad += 4;
 
4594
                                put_long (ad, wrd2);
 
4595
                                ad += 4;
 
4596
                                put_long (ad, wrd3);
 
4597
                                ad += 4;
 
4598
                        }
 
4599
                        list <<= 1;
 
4600
                }
 
4601
                m68k_areg (regs, opcode & 7) = ad;
 
4602
                dump_fp_regs( "END  ");
 
4603
        }
 
4604
}
 
4605
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_postinc( uae_u32 opcode, uae_u16 extra )
 
4606
{
 
4607
        uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
 
4608
        D(bug("FMOVEM FPP->memory\r\n"));
 
4609
        if (get_fp_ad(opcode, &ad)) {
 
4610
                for( int reg=0; reg<8; reg++ ) {
 
4611
                        uae_u32 wrd1, wrd2, wrd3;
 
4612
                        if( list & 0x80 ) {
 
4613
                                from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
 
4614
                                put_long (ad, wrd1);
 
4615
                                ad += 4;
 
4616
                                put_long (ad, wrd2);
 
4617
                                ad += 4;
 
4618
                                put_long (ad, wrd3);
 
4619
                                ad += 4;
 
4620
                        }
 
4621
                        list <<= 1;
 
4622
                }
 
4623
                dump_fp_regs( "END  ");
 
4624
        }
 
4625
}
 
4626
 
 
4627
 
 
4628
/* ---------------------------- FMOVEM CONSTANT ROM -> FPP ---------------------------- */
 
4629
 
 
4630
void REGPARAM2 fpuop_do_fldpi( uae_u32 opcode, uae_u16 extra )
 
4631
{
 
4632
        D(bug("FMOVECR memory->FPP FP const: Pi\r\n"));
 
4633
        memcpy( fp_reg[(extra>>7) & 7], const_pi, sizeof(float80_s) );
 
4634
        sw = SW_FINITE | INEX2;
 
4635
        dump_fp_regs( "END  ");
 
4636
}
 
4637
 
 
4638
void REGPARAM2 fpuop_do_fldlg2( uae_u32 opcode, uae_u16 extra )
 
4639
{
 
4640
        D(bug("FMOVECR memory->FPP FP const: Log 10 (2)\r\n"));
 
4641
        memcpy( fp_reg[(extra>>7) & 7], const_lg2, sizeof(float80_s) );
 
4642
        sw = SW_FINITE | INEX2;
 
4643
        dump_fp_regs( "END  ");
 
4644
}
 
4645
 
 
4646
void REGPARAM2 fpuop_do_load_const_e( uae_u32 opcode, uae_u16 extra )
 
4647
{
 
4648
        D(bug("FMOVECR memory->FPP FP const: e\r\n"));
 
4649
        memcpy( fp_reg[(extra>>7) & 7], const_e, sizeof(float80_s) );
 
4650
        sw = SW_FINITE | INEX2;
 
4651
        dump_fp_regs( "END  ");
 
4652
}
 
4653
 
 
4654
void REGPARAM2 fpuop_do_fldl2e( uae_u32 opcode, uae_u16 extra )
 
4655
{
 
4656
        D(bug("FMOVECR memory->FPP FP const: Log 2 (e)\r\n"));
 
4657
        memcpy( fp_reg[(extra>>7) & 7], const_l2e, sizeof(float80_s) );
 
4658
        sw = SW_FINITE | INEX2;
 
4659
        dump_fp_regs( "END  ");
 
4660
}
 
4661
 
 
4662
void REGPARAM2 fpuop_do_load_const_log_10_e( uae_u32 opcode, uae_u16 extra )
 
4663
{
 
4664
        D(bug("FMOVECR memory->FPP FP const: Log 10 (e)\r\n"));
 
4665
        memcpy( fp_reg[(extra>>7) & 7], const_log_10_e, sizeof(float80_s) );
 
4666
        sw = SW_FINITE | INEX2;
 
4667
        dump_fp_regs( "END  ");
 
4668
}
 
4669
 
 
4670
void REGPARAM2 fpuop_do_fldz( uae_u32 opcode, uae_u16 extra )
 
4671
{
 
4672
        D(bug("FMOVECR memory->FPP FP const: zero\r\n"));
 
4673
        memcpy( fp_reg[(extra>>7) & 7], const_z, sizeof(float80_s) );
 
4674
        sw = SW_Z;
 
4675
        dump_fp_regs( "END  ");
 
4676
}
 
4677
 
 
4678
void REGPARAM2 fpuop_do_fldln2( uae_u32 opcode, uae_u16 extra )
 
4679
{
 
4680
        D(bug("FMOVECR memory->FPP FP const: ln(2)\r\n"));
 
4681
        memcpy( fp_reg[(extra>>7) & 7], const_ln2, sizeof(float80_s) );
 
4682
        sw = SW_FINITE | INEX2;
 
4683
        dump_fp_regs( "END  ");
 
4684
}
 
4685
 
 
4686
void REGPARAM2 fpuop_do_load_const_ln_10( uae_u32 opcode, uae_u16 extra )
 
4687
{
 
4688
        D(bug("FMOVECR memory->FPP FP const: ln(10)\r\n"));
 
4689
        memcpy( fp_reg[(extra>>7) & 7], const_ln_10, sizeof(float80_s) );
 
4690
        sw = SW_FINITE | INEX2;
 
4691
        dump_fp_regs( "END  ");
 
4692
}
 
4693
 
 
4694
void REGPARAM2 fpuop_do_fld1( uae_u32 opcode, uae_u16 extra )
 
4695
{
 
4696
        D(bug("FMOVECR memory->FPP FP const: 1.0e0\r\n"));
 
4697
        memcpy( fp_reg[(extra>>7) & 7], const_1, sizeof(float80_s) );
 
4698
        sw = SW_FINITE;
 
4699
        dump_fp_regs( "END  ");
 
4700
}
 
4701
 
 
4702
void REGPARAM2 fpuop_do_load_const_1e1( uae_u32 opcode, uae_u16 extra )
 
4703
{
 
4704
        D(bug("FMOVECR memory->FPP FP const: 1.0e1\r\n"));
 
4705
        memcpy( fp_reg[(extra>>7) & 7], const_1e1, sizeof(float80_s) );
 
4706
        sw = SW_FINITE;
 
4707
        dump_fp_regs( "END  ");
 
4708
}
 
4709
 
 
4710
void REGPARAM2 fpuop_do_load_const_1e2( uae_u32 opcode, uae_u16 extra )
 
4711
{
 
4712
        D(bug("FMOVECR memory->FPP FP const: 1.0e2\r\n"));
 
4713
        memcpy( fp_reg[(extra>>7) & 7], const_1e2, sizeof(float80_s) );
 
4714
        sw = SW_FINITE;
 
4715
        dump_fp_regs( "END  ");
 
4716
}
 
4717
 
 
4718
void REGPARAM2 fpuop_do_load_const_1e4( uae_u32 opcode, uae_u16 extra )
 
4719
{
 
4720
        D(bug("FMOVECR memory->FPP FP const: 1.0e4\r\n"));
 
4721
        memcpy( fp_reg[(extra>>7) & 7], const_1e4, sizeof(float80_s) );
 
4722
        sw = SW_FINITE;
 
4723
        dump_fp_regs( "END  ");
 
4724
}
 
4725
 
 
4726
void REGPARAM2 fpuop_do_load_const_1e8( uae_u32 opcode, uae_u16 extra )
 
4727
{
 
4728
        D(bug("FMOVECR memory->FPP FP const: 1.0e8\r\n"));
 
4729
        memcpy( fp_reg[(extra>>7) & 7], const_1e8, sizeof(float80_s) );
 
4730
        sw = SW_FINITE | INEX2; // Is it really INEX2?
 
4731
        dump_fp_regs( "END  ");
 
4732
}
 
4733
 
 
4734
void REGPARAM2 fpuop_do_load_const_1e16( uae_u32 opcode, uae_u16 extra )
 
4735
{
 
4736
        D(bug("FMOVECR memory->FPP FP const: 1.0e16\r\n"));
 
4737
        memcpy( fp_reg[(extra>>7) & 7], const_1e16, sizeof(float80_s) );
 
4738
        sw = SW_FINITE | INEX2;
 
4739
        dump_fp_regs( "END  ");
 
4740
}
 
4741
 
 
4742
void REGPARAM2 fpuop_do_load_const_1e32( uae_u32 opcode, uae_u16 extra )
 
4743
{
 
4744
        D(bug("FMOVECR memory->FPP FP const: 1.0e32\r\n"));
 
4745
        memcpy( fp_reg[(extra>>7) & 7], const_1e32, sizeof(float80_s) );
 
4746
        sw = SW_FINITE | INEX2;
 
4747
        dump_fp_regs( "END  ");
 
4748
}
 
4749
 
 
4750
void REGPARAM2 fpuop_do_load_const_1e64( uae_u32 opcode, uae_u16 extra )
 
4751
{
 
4752
        D(bug("FMOVECR memory->FPP FP const: 1.0e64\r\n"));
 
4753
        memcpy( fp_reg[(extra>>7) & 7], const_1e64, sizeof(float80_s) );
 
4754
        sw = SW_FINITE | INEX2;
 
4755
        dump_fp_regs( "END  ");
 
4756
}
 
4757
 
 
4758
void REGPARAM2 fpuop_do_load_const_1e128( uae_u32 opcode, uae_u16 extra )
 
4759
{
 
4760
        D(bug("FMOVECR memory->FPP FP const: 1.0e128\r\n"));
 
4761
        memcpy( fp_reg[(extra>>7) & 7], const_1e128, sizeof(float80_s) );
 
4762
        sw = SW_FINITE | INEX2;
 
4763
        dump_fp_regs( "END  ");
 
4764
}
 
4765
 
 
4766
void REGPARAM2 fpuop_do_load_const_1e256( uae_u32 opcode, uae_u16 extra )
 
4767
{
 
4768
        D(bug("FMOVECR memory->FPP FP const: 1.0e256\r\n"));
 
4769
        memcpy( fp_reg[(extra>>7) & 7], const_1e256, sizeof(float80_s) );
 
4770
        sw = SW_FINITE | INEX2;
 
4771
        dump_fp_regs( "END  ");
 
4772
}
 
4773
 
 
4774
void REGPARAM2 fpuop_do_load_const_1e512( uae_u32 opcode, uae_u16 extra )
 
4775
{
 
4776
        D(bug("FMOVECR memory->FPP FP const: 1.0e512\r\n"));
 
4777
        memcpy( fp_reg[(extra>>7) & 7], const_1e512, sizeof(float80_s) );
 
4778
        sw = SW_FINITE | INEX2;
 
4779
        dump_fp_regs( "END  ");
 
4780
}
 
4781
 
 
4782
void REGPARAM2 fpuop_do_load_const_1e1024( uae_u32 opcode, uae_u16 extra )
 
4783
{
 
4784
        D(bug("FMOVECR memory->FPP FP const: 1.0e1024\r\n"));
 
4785
        memcpy( fp_reg[(extra>>7) & 7], const_1e1024, sizeof(float80_s) );
 
4786
        sw = SW_FINITE | INEX2;
 
4787
        dump_fp_regs( "END  ");
 
4788
}
 
4789
 
 
4790
void REGPARAM2 fpuop_do_load_const_1e2048( uae_u32 opcode, uae_u16 extra )
 
4791
{
 
4792
        D(bug("FMOVECR memory->FPP FP const: 1.0e2048\r\n"));
 
4793
        memcpy( fp_reg[(extra>>7) & 7], const_1e2048, sizeof(float80_s) );
 
4794
        sw = SW_FINITE | INEX2;
 
4795
        dump_fp_regs( "END  ");
 
4796
}
 
4797
 
 
4798
void REGPARAM2 fpuop_do_load_const_1e4096( uae_u32 opcode, uae_u16 extra )
 
4799
{
 
4800
        D(bug("FMOVECR memory->FPP FP const: 1.0e4096\r\n"));
 
4801
        memcpy( fp_reg[(extra>>7) & 7], const_1e4096, sizeof(float80_s) );
 
4802
        sw = SW_FINITE | INEX2;
 
4803
        dump_fp_regs( "END  ");
 
4804
}
 
4805
 
 
4806
 
 
4807
/* ---------------------------- ALU ---------------------------- */
 
4808
 
 
4809
void REGPARAM2 fpuop_do_fmove( uae_u32 opcode, uae_u16 extra )
 
4810
{
 
4811
        int reg = (extra >> 7) & 7;
 
4812
  float80_s src;
 
4813
        if (get_fp_value (opcode, extra, src) == 0) {
 
4814
                m68k_setpc (m68k_getpc () - 4);
 
4815
                op_illg (opcode);
 
4816
                dump_fp_regs( "END  ");
 
4817
                return;
 
4818
        }
 
4819
        D(bug("FMOVE %s\r\n",etos(src)));
 
4820
        do_fmove( fp_reg[reg], src );
 
4821
        build_ex_status();
 
4822
        dump_fp_regs( "END  ");
 
4823
}
 
4824
 
 
4825
void REGPARAM2 fpuop_do_fint( uae_u32 opcode, uae_u16 extra )
 
4826
{
 
4827
        int reg = (extra >> 7) & 7;
 
4828
  float80_s src;
 
4829
        if (get_fp_value (opcode, extra, src) == 0) {
 
4830
                m68k_setpc (m68k_getpc () - 4);
 
4831
                op_illg (opcode);
 
4832
                dump_fp_regs( "END  ");
 
4833
                return;
 
4834
        }
 
4835
        D(bug("FINT %s, opcode=%X, extra=%X, ta %X\r\n",etos(src),opcode,extra,m68k_getpc()));
 
4836
        do_fint( fp_reg[reg], src );
 
4837
        dump_fp_regs( "END  ");
 
4838
}
 
4839
 
 
4840
void REGPARAM2 fpuop_do_fsinh( uae_u32 opcode, uae_u16 extra )
 
4841
{
 
4842
        int reg = (extra >> 7) & 7;
 
4843
  float80_s src;
 
4844
        if (get_fp_value (opcode, extra, src) == 0) {
 
4845
                m68k_setpc (m68k_getpc () - 4);
 
4846
                op_illg (opcode);
 
4847
                dump_fp_regs( "END  ");
 
4848
                return;
 
4849
        }
 
4850
        D(bug("FSINH %s\r\n",etos(src)));
 
4851
        do_fsinh( fp_reg[reg], src );
 
4852
        build_ex_status();
 
4853
        dump_fp_regs( "END  ");
 
4854
}
 
4855
 
 
4856
void REGPARAM2 fpuop_do_fintrz( uae_u32 opcode, uae_u16 extra )
 
4857
{
 
4858
        int reg = (extra >> 7) & 7;
 
4859
  float80_s src;
 
4860
        if (get_fp_value (opcode, extra, src) == 0) {
 
4861
                m68k_setpc (m68k_getpc () - 4);
 
4862
                op_illg (opcode);
 
4863
                dump_fp_regs( "END  ");
 
4864
                return;
 
4865
        }
 
4866
        D(bug("FINTRZ %s\r\n",etos(src)));
 
4867
        do_fintrz( fp_reg[reg], src );
 
4868
        dump_fp_regs( "END  ");
 
4869
}
 
4870
 
 
4871
void REGPARAM2 fpuop_do_fsqrt( uae_u32 opcode, uae_u16 extra )
 
4872
{
 
4873
        int reg = (extra >> 7) & 7;
 
4874
  float80_s src;
 
4875
        if (get_fp_value (opcode, extra, src) == 0) {
 
4876
                m68k_setpc (m68k_getpc () - 4);
 
4877
                op_illg (opcode);
 
4878
                dump_fp_regs( "END  ");
 
4879
                return;
 
4880
        }
 
4881
        D(bug("FSQRT %s\r\n",etos(src)));
 
4882
        do_fsqrt( fp_reg[reg], src );
 
4883
        dump_fp_regs( "END  ");
 
4884
}
 
4885
 
 
4886
void REGPARAM2 fpuop_do_flognp1( uae_u32 opcode, uae_u16 extra )
 
4887
{
 
4888
        int reg = (extra >> 7) & 7;
 
4889
  float80_s src;
 
4890
        if (get_fp_value (opcode, extra, src) == 0) {
 
4891
                m68k_setpc (m68k_getpc () - 4);
 
4892
                op_illg (opcode);
 
4893
                dump_fp_regs( "END  ");
 
4894
                return;
 
4895
        }
 
4896
        D(bug("FLOGNP1 %s\r\n",etos(src)));
 
4897
        do_flognp1( fp_reg[reg], src );
 
4898
        build_ex_status();
 
4899
        dump_fp_regs( "END  ");
 
4900
}
 
4901
 
 
4902
void REGPARAM2 fpuop_do_fetoxm1( uae_u32 opcode, uae_u16 extra )
 
4903
{
 
4904
        int reg = (extra >> 7) & 7;
 
4905
  float80_s src;
 
4906
        if (get_fp_value (opcode, extra, src) == 0) {
 
4907
                m68k_setpc (m68k_getpc () - 4);
 
4908
                op_illg (opcode);
 
4909
                dump_fp_regs( "END  ");
 
4910
                return;
 
4911
        }
 
4912
        D(bug("FETOXM1 %s\r\n",etos(src)));
 
4913
        do_fetoxm1( fp_reg[reg], src );
 
4914
        build_ex_status();
 
4915
        dump_fp_regs( "END  ");
 
4916
}
 
4917
 
 
4918
void REGPARAM2 fpuop_do_ftanh( uae_u32 opcode, uae_u16 extra )
 
4919
{
 
4920
        int reg = (extra >> 7) & 7;
 
4921
  float80_s src;
 
4922
        if (get_fp_value (opcode, extra, src) == 0) {
 
4923
                m68k_setpc (m68k_getpc () - 4);
 
4924
                op_illg (opcode);
 
4925
                dump_fp_regs( "END  ");
 
4926
                return;
 
4927
        }
 
4928
        D(bug("FTANH %s\r\n",etos(src)));
 
4929
        do_ftanh( fp_reg[reg], src );
 
4930
        build_ex_status();
 
4931
        dump_fp_regs( "END  ");
 
4932
}
 
4933
 
 
4934
void REGPARAM2 fpuop_do_fatan( uae_u32 opcode, uae_u16 extra )
 
4935
{
 
4936
        int reg = (extra >> 7) & 7;
 
4937
  float80_s src;
 
4938
        if (get_fp_value (opcode, extra, src) == 0) {
 
4939
                m68k_setpc (m68k_getpc () - 4);
 
4940
                op_illg (opcode);
 
4941
                dump_fp_regs( "END  ");
 
4942
                return;
 
4943
        }
 
4944
        D(bug("FATAN %s\r\n",etos(src)));
 
4945
        do_fatan( fp_reg[reg], src );
 
4946
        build_ex_status();
 
4947
        dump_fp_regs( "END  ");
 
4948
}
 
4949
 
 
4950
void REGPARAM2 fpuop_do_fasin( uae_u32 opcode, uae_u16 extra )
 
4951
{
 
4952
        int reg = (extra >> 7) & 7;
 
4953
  float80_s src;
 
4954
        if (get_fp_value (opcode, extra, src) == 0) {
 
4955
                m68k_setpc (m68k_getpc () - 4);
 
4956
                op_illg (opcode);
 
4957
                dump_fp_regs( "END  ");
 
4958
                return;
 
4959
        }
 
4960
        D(bug("FASIN %s\r\n",etos(src)));
 
4961
        do_fasin( fp_reg[reg], src );
 
4962
        build_ex_status();
 
4963
        dump_fp_regs( "END  ");
 
4964
}
 
4965
 
 
4966
void REGPARAM2 fpuop_do_fatanh( uae_u32 opcode, uae_u16 extra )
 
4967
{
 
4968
        int reg = (extra >> 7) & 7;
 
4969
  float80_s src;
 
4970
        if (get_fp_value (opcode, extra, src) == 0) {
 
4971
                m68k_setpc (m68k_getpc () - 4);
 
4972
                op_illg (opcode);
 
4973
                dump_fp_regs( "END  ");
 
4974
                return;
 
4975
        }
 
4976
        D(bug("FATANH %s\r\n",etos(src)));
 
4977
        do_fatanh( fp_reg[reg], src );
 
4978
        build_ex_status();
 
4979
        dump_fp_regs( "END  ");
 
4980
}
 
4981
 
 
4982
void REGPARAM2 fpuop_do_fsin( uae_u32 opcode, uae_u16 extra )
 
4983
{
 
4984
        int reg = (extra >> 7) & 7;
 
4985
  float80_s src;
 
4986
        if (get_fp_value (opcode, extra, src) == 0) {
 
4987
                m68k_setpc (m68k_getpc () - 4);
 
4988
                op_illg (opcode);
 
4989
                dump_fp_regs( "END  ");
 
4990
                return;
 
4991
        }
 
4992
        D(bug("FSIN %s\r\n",etos(src)));
 
4993
        do_fsin( fp_reg[reg], src );
 
4994
        dump_fp_regs( "END  ");
 
4995
}
 
4996
 
 
4997
void REGPARAM2 fpuop_do_ftan( uae_u32 opcode, uae_u16 extra )
 
4998
{
 
4999
        int reg = (extra >> 7) & 7;
 
5000
  float80_s src;
 
5001
        if (get_fp_value (opcode, extra, src) == 0) {
 
5002
                m68k_setpc (m68k_getpc () - 4);
 
5003
                op_illg (opcode);
 
5004
                dump_fp_regs( "END  ");
 
5005
                return;
 
5006
        }
 
5007
        D(bug("FTAN %s\r\n",etos(src)));
 
5008
        do_ftan( fp_reg[reg], src );
 
5009
        dump_fp_regs( "END  ");
 
5010
}
 
5011
 
 
5012
void REGPARAM2 fpuop_do_fetox( uae_u32 opcode, uae_u16 extra )
 
5013
{
 
5014
        int reg = (extra >> 7) & 7;
 
5015
  float80_s src;
 
5016
        if (get_fp_value (opcode, extra, src) == 0) {
 
5017
                m68k_setpc (m68k_getpc () - 4);
 
5018
                op_illg (opcode);
 
5019
                dump_fp_regs( "END  ");
 
5020
                return;
 
5021
        }
 
5022
        D(bug("FETOX %s\r\n",etos(src)));
 
5023
        do_fetox( fp_reg[reg], src );
 
5024
        build_ex_status();
 
5025
        dump_fp_regs( "END  ");
 
5026
}
 
5027
 
 
5028
void REGPARAM2 fpuop_do_ftwotox( uae_u32 opcode, uae_u16 extra )
 
5029
{
 
5030
        int reg = (extra >> 7) & 7;
 
5031
  float80_s src;
 
5032
        if (get_fp_value (opcode, extra, src) == 0) {
 
5033
                m68k_setpc (m68k_getpc () - 4);
 
5034
                op_illg (opcode);
 
5035
                dump_fp_regs( "END  ");
 
5036
                return;
 
5037
        }
 
5038
        D(bug("FTWOTOX %s\r\n",etos(src)));
 
5039
        do_ftwotox( fp_reg[reg], src );
 
5040
        build_ex_status();
 
5041
        dump_fp_regs( "END  ");
 
5042
}
 
5043
 
 
5044
void REGPARAM2 fpuop_do_ftentox( uae_u32 opcode, uae_u16 extra )
 
5045
{
 
5046
        int reg = (extra >> 7) & 7;
 
5047
  float80_s src;
 
5048
        if (get_fp_value (opcode, extra, src) == 0) {
 
5049
                m68k_setpc (m68k_getpc () - 4);
 
5050
                op_illg (opcode);
 
5051
                dump_fp_regs( "END  ");
 
5052
                return;
 
5053
        }
 
5054
        D(bug("FTENTOX %s\r\n",etos(src)));
 
5055
        do_ftentox( fp_reg[reg], src );
 
5056
        build_ex_status();
 
5057
        dump_fp_regs( "END  ");
 
5058
}
 
5059
 
 
5060
void REGPARAM2 fpuop_do_flogn( uae_u32 opcode, uae_u16 extra )
 
5061
{
 
5062
        int reg = (extra >> 7) & 7;
 
5063
  float80_s src;
 
5064
        if (get_fp_value (opcode, extra, src) == 0) {
 
5065
                m68k_setpc (m68k_getpc () - 4);
 
5066
                op_illg (opcode);
 
5067
                dump_fp_regs( "END  ");
 
5068
                return;
 
5069
        }
 
5070
        D(bug("FLOGN %s\r\n",etos(src)));
 
5071
        do_flogn( fp_reg[reg], src );
 
5072
        build_ex_status();
 
5073
        dump_fp_regs( "END  ");
 
5074
}
 
5075
 
 
5076
void REGPARAM2 fpuop_do_flog10( uae_u32 opcode, uae_u16 extra )
 
5077
{
 
5078
        int reg = (extra >> 7) & 7;
 
5079
  float80_s src;
 
5080
        if (get_fp_value (opcode, extra, src) == 0) {
 
5081
                m68k_setpc (m68k_getpc () - 4);
 
5082
                op_illg (opcode);
 
5083
                dump_fp_regs( "END  ");
 
5084
                return;
 
5085
        }
 
5086
        D(bug("FLOG10 %s\r\n",etos(src)));
 
5087
        do_flog10( fp_reg[reg], src );
 
5088
        build_ex_status();
 
5089
        dump_fp_regs( "END  ");
 
5090
}
 
5091
 
 
5092
void REGPARAM2 fpuop_do_flog2( uae_u32 opcode, uae_u16 extra )
 
5093
{
 
5094
        int reg = (extra >> 7) & 7;
 
5095
  float80_s src;
 
5096
        if (get_fp_value (opcode, extra, src) == 0) {
 
5097
                m68k_setpc (m68k_getpc () - 4);
 
5098
                op_illg (opcode);
 
5099
                dump_fp_regs( "END  ");
 
5100
                return;
 
5101
        }
 
5102
        D(bug("FLOG2 %s\r\n",etos(src)));
 
5103
        do_flog2( fp_reg[reg], src );
 
5104
        build_ex_status();
 
5105
        dump_fp_regs( "END  ");
 
5106
}
 
5107
 
 
5108
void REGPARAM2 fpuop_do_fabs( uae_u32 opcode, uae_u16 extra )
 
5109
{
 
5110
        int reg = (extra >> 7) & 7;
 
5111
  float80_s src;
 
5112
        if (get_fp_value (opcode, extra, src) == 0) {
 
5113
                m68k_setpc (m68k_getpc () - 4);
 
5114
                op_illg (opcode);
 
5115
                dump_fp_regs( "END  ");
 
5116
                return;
 
5117
        }
 
5118
        D(bug("FABS %s\r\n",etos(src)));
 
5119
        do_fabs( fp_reg[reg], src );
 
5120
        dump_fp_regs( "END  ");
 
5121
}
 
5122
 
 
5123
void REGPARAM2 fpuop_do_fcosh( uae_u32 opcode, uae_u16 extra )
 
5124
{
 
5125
        int reg = (extra >> 7) & 7;
 
5126
  float80_s src;
 
5127
        if (get_fp_value (opcode, extra, src) == 0) {
 
5128
                m68k_setpc (m68k_getpc () - 4);
 
5129
                op_illg (opcode);
 
5130
                dump_fp_regs( "END  ");
 
5131
                return;
 
5132
        }
 
5133
        D(bug("FCOSH %s\r\n",etos(src)));
 
5134
        do_fcosh( fp_reg[reg], src );
 
5135
        build_ex_status();
 
5136
        dump_fp_regs( "END  ");
 
5137
}
 
5138
 
 
5139
void REGPARAM2 fpuop_do_fneg( uae_u32 opcode, uae_u16 extra )
 
5140
{
 
5141
        int reg = (extra >> 7) & 7;
 
5142
  float80_s src;
 
5143
        if (get_fp_value (opcode, extra, src) == 0) {
 
5144
                m68k_setpc (m68k_getpc () - 4);
 
5145
                op_illg (opcode);
 
5146
                dump_fp_regs( "END  ");
 
5147
                return;
 
5148
        }
 
5149
        D(bug("FNEG %s\r\n",etos(src)));
 
5150
        do_fneg( fp_reg[reg], src );
 
5151
        dump_fp_regs( "END  ");
 
5152
}
 
5153
 
 
5154
void REGPARAM2 fpuop_do_facos( uae_u32 opcode, uae_u16 extra )
 
5155
{
 
5156
        int reg = (extra >> 7) & 7;
 
5157
  float80_s src;
 
5158
        if (get_fp_value (opcode, extra, src) == 0) {
 
5159
                m68k_setpc (m68k_getpc () - 4);
 
5160
                op_illg (opcode);
 
5161
                dump_fp_regs( "END  ");
 
5162
                return;
 
5163
        }
 
5164
        D(bug("FACOS %s\r\n",etos(src)));
 
5165
        do_facos( fp_reg[reg], src );
 
5166
        build_ex_status();
 
5167
        dump_fp_regs( "END  ");
 
5168
}
 
5169
 
 
5170
void REGPARAM2 fpuop_do_fcos( uae_u32 opcode, uae_u16 extra )
 
5171
{
 
5172
        int reg = (extra >> 7) & 7;
 
5173
  float80_s src;
 
5174
        if (get_fp_value (opcode, extra, src) == 0) {
 
5175
                m68k_setpc (m68k_getpc () - 4);
 
5176
                op_illg (opcode);
 
5177
                dump_fp_regs( "END  ");
 
5178
                return;
 
5179
        }
 
5180
        D(bug("FCOS %s\r\n",etos(src)));
 
5181
        do_fcos( fp_reg[reg], src );
 
5182
        dump_fp_regs( "END  ");
 
5183
}
 
5184
 
 
5185
void REGPARAM2 fpuop_do_fgetexp( uae_u32 opcode, uae_u16 extra )
 
5186
{
 
5187
        int reg = (extra >> 7) & 7;
 
5188
  float80_s src;
 
5189
        if (get_fp_value (opcode, extra, src) == 0) {
 
5190
                m68k_setpc (m68k_getpc () - 4);
 
5191
                op_illg (opcode);
 
5192
                dump_fp_regs( "END  ");
 
5193
                return;
 
5194
        }
 
5195
        D(bug("FGETEXP %s\r\n",etos(src)));
 
5196
 
 
5197
        if( IS_INFINITY(src) ) {
 
5198
                MAKE_NAN( fp_reg[reg] );
 
5199
                do_ftst( fp_reg[reg] );
 
5200
                sw |= SW_IE;
 
5201
        } else {
 
5202
                do_fgetexp( fp_reg[reg], src );
 
5203
        }
 
5204
        dump_fp_regs( "END  ");
 
5205
}
 
5206
 
 
5207
void REGPARAM2 fpuop_do_fgetman( uae_u32 opcode, uae_u16 extra )
 
5208
{
 
5209
        int reg = (extra >> 7) & 7;
 
5210
  float80_s src;
 
5211
        if (get_fp_value (opcode, extra, src) == 0) {
 
5212
                m68k_setpc (m68k_getpc () - 4);
 
5213
                op_illg (opcode);
 
5214
                dump_fp_regs( "END  ");
 
5215
                return;
 
5216
        }
 
5217
        D(bug("FGETMAN %s\r\n",etos(src)));
 
5218
        if( IS_INFINITY(src) ) {
 
5219
                MAKE_NAN( fp_reg[reg] );
 
5220
                do_ftst( fp_reg[reg] );
 
5221
                sw |= SW_IE;
 
5222
        } else {
 
5223
                do_fgetman( fp_reg[reg], src );
 
5224
        }
 
5225
        dump_fp_regs( "END  ");
 
5226
}
 
5227
 
 
5228
void REGPARAM2 fpuop_do_fdiv( uae_u32 opcode, uae_u16 extra )
 
5229
{
 
5230
        int reg = (extra >> 7) & 7;
 
5231
  float80_s src;
 
5232
        if (get_fp_value (opcode, extra, src) == 0) {
 
5233
                m68k_setpc (m68k_getpc () - 4);
 
5234
                op_illg (opcode);
 
5235
                dump_fp_regs( "END  ");
 
5236
                return;
 
5237
        }
 
5238
        D(bug("FDIV %s\r\n",etos(src)));
 
5239
        do_fdiv( fp_reg[reg], src );
 
5240
        dump_fp_regs( "END  ");
 
5241
}
 
5242
 
 
5243
void REGPARAM2 fpuop_do_fmod( uae_u32 opcode, uae_u16 extra )
 
5244
{
 
5245
        int reg = (extra >> 7) & 7;
 
5246
  float80_s src;
 
5247
        if (get_fp_value (opcode, extra, src) == 0) {
 
5248
                m68k_setpc (m68k_getpc () - 4);
 
5249
                op_illg (opcode);
 
5250
                dump_fp_regs( "END  ");
 
5251
                return;
 
5252
        }
 
5253
        D(bug("FMOD %s\r\n",etos(src)));
 
5254
 
 
5255
#if USE_3_BIT_QUOTIENT
 
5256
        do_fmod( fp_reg[reg], src );
 
5257
#else
 
5258
        if( (cw & X86_ROUND_CONTROL_MASK) == CW_RC_ZERO ) {
 
5259
                do_fmod_dont_set_cw( fp_reg[reg], src );
 
5260
        } else {
 
5261
                do_fmod( fp_reg[reg], src );
 
5262
        }
 
5263
#endif
 
5264
        dump_fp_regs( "END  ");
 
5265
}
 
5266
 
 
5267
void REGPARAM2 fpuop_do_frem( uae_u32 opcode, uae_u16 extra )
 
5268
{
 
5269
        int reg = (extra >> 7) & 7;
 
5270
  float80_s src;
 
5271
        if (get_fp_value (opcode, extra, src) == 0) {
 
5272
                m68k_setpc (m68k_getpc () - 4);
 
5273
                op_illg (opcode);
 
5274
                dump_fp_regs( "END  ");
 
5275
                return;
 
5276
        }
 
5277
        D(bug("FREM %s\r\n",etos(src)));
 
5278
#if USE_3_BIT_QUOTIENT
 
5279
        do_frem( fp_reg[reg], src );
 
5280
#else
 
5281
        if( (cw & X86_ROUND_CONTROL_MASK) == CW_RC_NEAR ) {
 
5282
                do_frem_dont_set_cw( fp_reg[reg], src );
 
5283
        } else {
 
5284
                do_frem( fp_reg[reg], src );
 
5285
        }
 
5286
#endif
 
5287
        dump_fp_regs( "END  ");
 
5288
}
 
5289
 
 
5290
void REGPARAM2 fpuop_do_fadd( uae_u32 opcode, uae_u16 extra )
 
5291
{
 
5292
        int reg = (extra >> 7) & 7;
 
5293
  float80_s src;
 
5294
        if (get_fp_value (opcode, extra, src) == 0) {
 
5295
                m68k_setpc (m68k_getpc () - 4);
 
5296
                op_illg (opcode);
 
5297
                dump_fp_regs( "END  ");
 
5298
                return;
 
5299
        }
 
5300
        D(bug("FADD %s\r\n",etos(src)));
 
5301
        do_fadd( fp_reg[reg], src );
 
5302
        dump_fp_regs( "END  ");
 
5303
}
 
5304
 
 
5305
void REGPARAM2 fpuop_do_fmul( uae_u32 opcode, uae_u16 extra )
 
5306
{
 
5307
        int reg = (extra >> 7) & 7;
 
5308
  float80_s src;
 
5309
        if (get_fp_value (opcode, extra, src) == 0) {
 
5310
                m68k_setpc (m68k_getpc () - 4);
 
5311
                op_illg (opcode);
 
5312
                dump_fp_regs( "END  ");
 
5313
                return;
 
5314
        }
 
5315
        D(bug("FMUL %s\r\n",etos(src)));
 
5316
        do_fmul( fp_reg[reg], src );
 
5317
        dump_fp_regs( "END  ");
 
5318
}
 
5319
 
 
5320
void REGPARAM2 fpuop_do_fsgldiv( uae_u32 opcode, uae_u16 extra )
 
5321
{
 
5322
        int reg = (extra >> 7) & 7;
 
5323
  float80_s src;
 
5324
        if (get_fp_value (opcode, extra, src) == 0) {
 
5325
                m68k_setpc (m68k_getpc () - 4);
 
5326
                op_illg (opcode);
 
5327
                dump_fp_regs( "END  ");
 
5328
                return;
 
5329
        }
 
5330
        D(bug("FSGLDIV %s\r\n",etos(src)));
 
5331
        do_fsgldiv( fp_reg[reg], src );
 
5332
        dump_fp_regs( "END  ");
 
5333
}
 
5334
 
 
5335
void REGPARAM2 fpuop_do_fscale( uae_u32 opcode, uae_u16 extra )
 
5336
{
 
5337
        int reg = (extra >> 7) & 7;
 
5338
  float80_s src;
 
5339
        if (get_fp_value (opcode, extra, src) == 0) {
 
5340
                m68k_setpc (m68k_getpc () - 4);
 
5341
                op_illg (opcode);
 
5342
                dump_fp_regs( "END  ");
 
5343
                return;
 
5344
        }
 
5345
        D(bug("FSCALE %s, opcode=%X, extra=%X, ta %X\r\n",etos(src),opcode,extra,m68k_getpc()));
 
5346
        if( IS_INFINITY(fp_reg[reg]) ) {
 
5347
                MAKE_NAN( fp_reg[reg] );
 
5348
                do_ftst( fp_reg[reg] );
 
5349
                sw |= SW_IE;
 
5350
        } else {
 
5351
                // When the absolute value of the source operand is >= 2^14,
 
5352
                // an overflow or underflow always results.
 
5353
                do_fscale( fp_reg[reg], src );
 
5354
        }
 
5355
        dump_fp_regs( "END  ");
 
5356
}
 
5357
 
 
5358
void REGPARAM2 fpuop_do_fsglmul( uae_u32 opcode, uae_u16 extra )
 
5359
{
 
5360
        int reg = (extra >> 7) & 7;
 
5361
  float80_s src;
 
5362
        if (get_fp_value (opcode, extra, src) == 0) {
 
5363
                m68k_setpc (m68k_getpc () - 4);
 
5364
                op_illg (opcode);
 
5365
                dump_fp_regs( "END  ");
 
5366
                return;
 
5367
        }
 
5368
        D(bug("FSGLMUL %s\r\n",etos(src)));
 
5369
        do_fsglmul( fp_reg[reg], src );
 
5370
        dump_fp_regs( "END  ");
 
5371
}
 
5372
 
 
5373
void REGPARAM2 fpuop_do_fsub( uae_u32 opcode, uae_u16 extra )
 
5374
{
 
5375
        int reg = (extra >> 7) & 7;
 
5376
  float80_s src;
 
5377
        if (get_fp_value (opcode, extra, src) == 0) {
 
5378
                m68k_setpc (m68k_getpc () - 4);
 
5379
                op_illg (opcode);
 
5380
                dump_fp_regs( "END  ");
 
5381
                return;
 
5382
        }
 
5383
        D(bug("FSUB %s\r\n",etos(src)));
 
5384
        do_fsub( fp_reg[reg], src );
 
5385
        dump_fp_regs( "END  ");
 
5386
}
 
5387
 
 
5388
void REGPARAM2 fpuop_do_fsincos( uae_u32 opcode, uae_u16 extra )
 
5389
{
 
5390
        int reg = (extra >> 7) & 7;
 
5391
  float80_s src;
 
5392
        if (get_fp_value (opcode, extra, src) == 0) {
 
5393
                m68k_setpc (m68k_getpc () - 4);
 
5394
                op_illg (opcode);
 
5395
                dump_fp_regs( "END  ");
 
5396
                return;
 
5397
        }
 
5398
        D(bug("FSINCOS %s\r\n",etos(src)));
 
5399
        do_fsincos( fp_reg[reg], fp_reg[extra & 7], src );
 
5400
        dump_fp_regs( "END  ");
 
5401
}
 
5402
 
 
5403
void REGPARAM2 fpuop_do_fcmp( uae_u32 opcode, uae_u16 extra )
 
5404
{
 
5405
        int reg = (extra >> 7) & 7;
 
5406
  float80_s src;
 
5407
        if (get_fp_value (opcode, extra, src) == 0) {
 
5408
                m68k_setpc (m68k_getpc () - 4);
 
5409
                op_illg (opcode);
 
5410
                dump_fp_regs( "END  ");
 
5411
                return;
 
5412
        }
 
5413
        D(bug("FCMP %s\r\n",etos(src)));
 
5414
 
 
5415
        if( IS_INFINITY(src) ) {
 
5416
                if( IS_NEGATIVE(src) ) {
 
5417
                        if( IS_INFINITY(fp_reg[reg]) && IS_NEGATIVE(fp_reg[reg]) ) {
 
5418
                                sw = SW_Z | SW_N;
 
5419
                                D(bug("-INF FCMP -INF -> NZ\r\n"));
 
5420
                        } else {
 
5421
                                sw = SW_FINITE;
 
5422
                                D(bug("X FCMP -INF -> None\r\n"));
 
5423
                        }
 
5424
                } else {
 
5425
                        if( IS_INFINITY(fp_reg[reg]) && !IS_NEGATIVE(fp_reg[reg]) ) {
 
5426
                                sw = SW_Z;
 
5427
                                D(bug("+INF FCMP +INF -> Z\r\n"));
 
5428
                        } else {
 
5429
                                sw = SW_N;
 
5430
                                D(bug("X FCMP +INF -> N\r\n"));
 
5431
                        }
 
5432
                }
 
5433
        } else if( IS_INFINITY(fp_reg[reg]) ) {
 
5434
                if( IS_NEGATIVE(fp_reg[reg]) ) {
 
5435
                        sw = SW_N;
 
5436
                        D(bug("-INF FCMP X -> Negative\r\n"));
 
5437
                } else {
 
5438
                        sw = SW_FINITE;
 
5439
                        D(bug("+INF FCMP X -> None\r\n"));
 
5440
                }
 
5441
        } else {
 
5442
                do_fcmp( fp_reg[reg], src );
 
5443
        }
 
5444
 
 
5445
        dump_fp_regs( "END  ");
 
5446
}
 
5447
 
 
5448
void REGPARAM2 fpuop_do_ftst( uae_u32 opcode, uae_u16 extra )
 
5449
{
 
5450
        int reg = (extra >> 7) & 7;
 
5451
  float80_s src;
 
5452
        if (get_fp_value (opcode, extra, src) == 0) {
 
5453
                m68k_setpc (m68k_getpc () - 4);
 
5454
                op_illg (opcode);
 
5455
                dump_fp_regs( "END  ");
 
5456
                return;
 
5457
        }
 
5458
        D(bug("FTST %s\r\n",etos(src)));
 
5459
        do_ftst( src );
 
5460
        build_ex_status();
 
5461
        dump_fp_regs( "END  ");
 
5462
}
 
5463
 
 
5464
 
 
5465
 
 
5466
/* ---------------------------- SET FPU MODE ---------------------------- */
 
5467
 
 
5468
void fpu_set_integral_fpu( bool is_integral )
 
5469
{
 
5470
        is_integral_68040_fpu = (uae_u32)is_integral;
 
5471
}
 
5472
 
 
5473
 
 
5474
/* ---------------------------- SETUP TABLES ---------------------------- */
 
5475
 
 
5476
static void build_fpp_opp_lookup_table()
 
5477
{
 
5478
        for( uae_u32 opcode=0; opcode<=0x38; opcode+=8 ) {
 
5479
                for( uae_u32 extra=0; extra<65536; extra++ ) {
 
5480
                        uae_u32 mask = (extra & 0xFC7F) | ((opcode & 0x0038) << 4);
 
5481
                        fpufunctbl[mask] = fpuop_illg;
 
5482
 
 
5483
                        switch ((extra >> 13) & 0x7) {
 
5484
                                case 3:
 
5485
                                        fpufunctbl[mask] = fpuop_fmove_2_ea;
 
5486
                                        break;
 
5487
                                case 4:
 
5488
                                case 5:
 
5489
                                        if ((opcode & 0x38) == 0) {
 
5490
                                                if (extra & 0x2000) { // dr bit
 
5491
                                                        switch( extra & 0x1C00 ) {
 
5492
                                                                case 0x0000:
 
5493
                                                                        fpufunctbl[mask] = fpuop_fmovem_none_2_Dreg;
 
5494
                                                                        break;
 
5495
                                                                case 0x0400:
 
5496
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Dreg;
 
5497
                                                                        break;
 
5498
                                                                case 0x0800:
 
5499
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Dreg;
 
5500
                                                                        break;
 
5501
                                                                case 0x0C00:
 
5502
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Dreg;
 
5503
                                                                        break;
 
5504
                                                                case 0x1000:
 
5505
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Dreg;
 
5506
                                                                        break;
 
5507
                                                                case 0x1400:
 
5508
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Dreg;
 
5509
                                                                        break;
 
5510
                                                                case 0x1800:
 
5511
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Dreg;
 
5512
                                                                        break;
 
5513
                                                                case 0x1C00:
 
5514
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg;
 
5515
                                                                        break;
 
5516
                                                        }
 
5517
                                                } else {
 
5518
                                                        switch( extra & 0x1C00 ) {
 
5519
                                                                case 0x0000:
 
5520
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_none;
 
5521
                                                                        break;
 
5522
                                                                case 0x0400:
 
5523
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpiar;
 
5524
                                                                        break;
 
5525
                                                                case 0x0800:
 
5526
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpsr;
 
5527
                                                                        break;
 
5528
                                                                case 0x0C00:
 
5529
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpsr_fpiar;
 
5530
                                                                        break;
 
5531
                                                                case 0x1000:
 
5532
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr;
 
5533
                                                                        break;
 
5534
                                                                case 0x1400:
 
5535
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr_fpiar;
 
5536
                                                                        break;
 
5537
                                                                case 0x1800:
 
5538
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr_fpsr;
 
5539
                                                                        break;
 
5540
                                                                case 0x1C00:
 
5541
                                                                        fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar;
 
5542
                                                                        break;
 
5543
                                                        }
 
5544
                                                }
 
5545
                                        } else if ((opcode & 0x38) == 8) {
 
5546
                                                if (extra & 0x2000) { // dr bit
 
5547
                                                        switch( extra & 0x1C00 ) {
 
5548
                                                                case 0x0000:
 
5549
                                                                        fpufunctbl[mask] = fpuop_fmovem_none_2_Areg;
 
5550
                                                                        break;
 
5551
                                                                case 0x0400:
 
5552
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Areg;
 
5553
                                                                        break;
 
5554
                                                                case 0x0800:
 
5555
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Areg;
 
5556
                                                                        break;
 
5557
                                                                case 0x0C00:
 
5558
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Areg;
 
5559
                                                                        break;
 
5560
                                                                case 0x1000:
 
5561
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Areg;
 
5562
                                                                        break;
 
5563
                                                                case 0x1400:
 
5564
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Areg;
 
5565
                                                                        break;
 
5566
                                                                case 0x1800:
 
5567
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Areg;
 
5568
                                                                        break;
 
5569
                                                                case 0x1C00:
 
5570
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg;
 
5571
                                                                        break;
 
5572
                                                        }
 
5573
                                                } else {
 
5574
                                                        switch( extra & 0x1C00 ) {
 
5575
                                                                case 0x0000:
 
5576
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_none;
 
5577
                                                                        break;
 
5578
                                                                case 0x0400:
 
5579
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpiar;
 
5580
                                                                        break;
 
5581
                                                                case 0x0800:
 
5582
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpsr;
 
5583
                                                                        break;
 
5584
                                                                case 0x0C00:
 
5585
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpsr_fpiar;
 
5586
                                                                        break;
 
5587
                                                                case 0x1000:
 
5588
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr;
 
5589
                                                                        break;
 
5590
                                                                case 0x1400:
 
5591
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr_fpiar;
 
5592
                                                                        break;
 
5593
                                                                case 0x1800:
 
5594
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr_fpsr;
 
5595
                                                                        break;
 
5596
                                                                case 0x1C00:
 
5597
                                                                        fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar;
 
5598
                                                                        break;
 
5599
                                                        }
 
5600
                                                }
 
5601
                                        } else if (extra & 0x2000) {
 
5602
                                                if ((opcode & 0x38) == 0x20) {
 
5603
                                                        switch( extra & 0x1C00 ) {
 
5604
                                                                case 0x0000:
 
5605
                                                                        fpufunctbl[mask] = fpuop_fmovem_none_2_Mem_predecrement;
 
5606
                                                                        break;
 
5607
                                                                case 0x0400:
 
5608
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Mem_predecrement;
 
5609
                                                                        break;
 
5610
                                                                case 0x0800:
 
5611
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Mem_predecrement;
 
5612
                                                                        break;
 
5613
                                                                case 0x0C00:
 
5614
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement;
 
5615
                                                                        break;
 
5616
                                                                case 0x1000:
 
5617
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Mem_predecrement;
 
5618
                                                                        break;
 
5619
                                                                case 0x1400:
 
5620
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement;
 
5621
                                                                        break;
 
5622
                                                                case 0x1800:
 
5623
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement;
 
5624
                                                                        break;
 
5625
                                                                case 0x1C00:
 
5626
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement;
 
5627
                                                                        break;
 
5628
                                                        }
 
5629
                                                } else if ((opcode & 0x38) == 0x18) {
 
5630
                                                        switch( extra & 0x1C00 ) {
 
5631
                                                                case 0x0000:
 
5632
                                                                        fpufunctbl[mask] = fpuop_fmovem_none_2_Mem_postincrement;
 
5633
                                                                        break;
 
5634
                                                                case 0x0400:
 
5635
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Mem_postincrement;
 
5636
                                                                        break;
 
5637
                                                                case 0x0800:
 
5638
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Mem_postincrement;
 
5639
                                                                        break;
 
5640
                                                                case 0x0C00:
 
5641
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement;
 
5642
                                                                        break;
 
5643
                                                                case 0x1000:
 
5644
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Mem_postincrement;
 
5645
                                                                        break;
 
5646
                                                                case 0x1400:
 
5647
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement;
 
5648
                                                                        break;
 
5649
                                                                case 0x1800:
 
5650
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement;
 
5651
                                                                        break;
 
5652
                                                                case 0x1C00:
 
5653
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement;
 
5654
                                                                        break;
 
5655
                                                        }
 
5656
                                                } else {
 
5657
                                                        switch( extra & 0x1C00 ) {
 
5658
                                                                case 0x0000:
 
5659
                                                                        fpufunctbl[mask] = fpuop_fmovem_none_2_Mem;
 
5660
                                                                        break;
 
5661
                                                                case 0x0400:
 
5662
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Mem;
 
5663
                                                                        break;
 
5664
                                                                case 0x0800:
 
5665
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Mem;
 
5666
                                                                        break;
 
5667
                                                                case 0x0C00:
 
5668
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Mem;
 
5669
                                                                        break;
 
5670
                                                                case 0x1000:
 
5671
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Mem;
 
5672
                                                                        break;
 
5673
                                                                case 0x1400:
 
5674
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Mem;
 
5675
                                                                        break;
 
5676
                                                                case 0x1800:
 
5677
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Mem;
 
5678
                                                                        break;
 
5679
                                                                case 0x1C00:
 
5680
                                                                        fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem;
 
5681
                                                                        break;
 
5682
                                                        }
 
5683
                                                }
 
5684
                                        } else {
 
5685
                                                if ((opcode & 0x38) == 0x20) {
 
5686
                                                        switch( extra & 0x1C00 ) {
 
5687
                                                                case 0x0000:
 
5688
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_none_predecrement;
 
5689
                                                                        break;
 
5690
                                                                case 0x0400:
 
5691
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpiar_predecrement;
 
5692
                                                                        break;
 
5693
                                                                case 0x0800:
 
5694
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_predecrement;
 
5695
                                                                        break;
 
5696
                                                                case 0x0C00:
 
5697
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement;
 
5698
                                                                        break;
 
5699
                                                                case 0x1000:
 
5700
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_predecrement;
 
5701
                                                                        break;
 
5702
                                                                case 0x1400:
 
5703
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement;
 
5704
                                                                        break;
 
5705
                                                                case 0x1800:
 
5706
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement;
 
5707
                                                                        break;
 
5708
                                                                case 0x1C00:
 
5709
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement;
 
5710
                                                                        break;
 
5711
                                                        }
 
5712
                                                } else if ((opcode & 0x38) == 0x18) {
 
5713
                                                        switch( extra & 0x1C00 ) {
 
5714
                                                                case 0x0000:
 
5715
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_none_postincrement;
 
5716
                                                                        break;
 
5717
                                                                case 0x0400:
 
5718
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpiar_postincrement;
 
5719
                                                                        break;
 
5720
                                                                case 0x0800:
 
5721
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_postincrement;
 
5722
                                                                        break;
 
5723
                                                                case 0x0C00:
 
5724
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement;
 
5725
                                                                        break;
 
5726
                                                                case 0x1000:
 
5727
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_postincrement;
 
5728
                                                                        break;
 
5729
                                                                case 0x1400:
 
5730
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement;
 
5731
                                                                        break;
 
5732
                                                                case 0x1800:
 
5733
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement;
 
5734
                                                                        break;
 
5735
                                                                case 0x1C00:
 
5736
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement;
 
5737
                                                                        break;
 
5738
                                                        }
 
5739
                                                } else {
 
5740
                                                        switch( extra & 0x1C00 ) {
 
5741
                                                                case 0x0000:
 
5742
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_none_2_Mem;
 
5743
                                                                        break;
 
5744
                                                                case 0x0400:
 
5745
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpiar_2_Mem;
 
5746
                                                                        break;
 
5747
                                                                case 0x0800:
 
5748
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_2_Mem;
 
5749
                                                                        break;
 
5750
                                                                case 0x0C00:
 
5751
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem;
 
5752
                                                                        break;
 
5753
                                                                case 0x1000:
 
5754
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_2_Mem;
 
5755
                                                                        break;
 
5756
                                                                case 0x1400:
 
5757
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem;
 
5758
                                                                        break;
 
5759
                                                                case 0x1800:
 
5760
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem;
 
5761
                                                                        break;
 
5762
                                                                case 0x1C00:
 
5763
                                                                        fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem;
 
5764
                                                                        break;
 
5765
                                                        }
 
5766
                                                }
 
5767
                                        break;
 
5768
                                case 6:
 
5769
                                        switch ((extra >> 11) & 3) {
 
5770
                                                case 0: /* static pred */
 
5771
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5772
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_pred_postincrement;
 
5773
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5774
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_pred_predecrement;
 
5775
                                                        else
 
5776
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_pred;
 
5777
                                                        break;
 
5778
                                                case 1: /* dynamic pred */
 
5779
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5780
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement;
 
5781
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5782
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement;
 
5783
                                                        else
 
5784
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_pred;
 
5785
                                                        break;
 
5786
                                                case 2: /* static postinc */
 
5787
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5788
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement;
 
5789
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5790
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement;
 
5791
                                                        else
 
5792
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_postinc;
 
5793
                                                        break;
 
5794
                                                case 3: /* dynamic postinc */
 
5795
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5796
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement;
 
5797
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5798
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement;
 
5799
                                                        else
 
5800
                                                                fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_postinc;
 
5801
                                                        break;
 
5802
                                        }
 
5803
                                        break;
 
5804
                                case 7:
 
5805
                                        switch ((extra >> 11) & 3) {
 
5806
                                                case 0: /* static pred */
 
5807
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5808
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_pred_postincrement;
 
5809
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5810
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_pred_predecrement;
 
5811
                                                        else
 
5812
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_pred;
 
5813
                                                        break;
 
5814
                                                case 1: /* dynamic pred */
 
5815
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5816
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement;
 
5817
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5818
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement;
 
5819
                                                        else
 
5820
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_pred;
 
5821
                                                        break;
 
5822
                                                case 2: /* static postinc */
 
5823
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5824
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement;
 
5825
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5826
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement;
 
5827
                                                        else
 
5828
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_postinc;
 
5829
                                                        break;
 
5830
                                                case 3: /* dynamic postinc */
 
5831
                                                        if ((opcode & 0x38) == 0x18) // post-increment?
 
5832
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement;
 
5833
                                                        else if ((opcode & 0x38) == 0x20) // pre-decrement?
 
5834
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement;
 
5835
                                                        else
 
5836
                                                                fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_postinc;
 
5837
                                                        break;
 
5838
                                        }
 
5839
                                        break;
 
5840
                                case 0:
 
5841
                                case 2:
 
5842
                                        if ((extra & 0xfc00) == 0x5c00) {
 
5843
                                                switch (extra & 0x7f) {
 
5844
                                                        case 0x00:
 
5845
                                                                fpufunctbl[mask] = fpuop_do_fldpi;
 
5846
                                                                break;
 
5847
                                                        case 0x0b:
 
5848
                                                                fpufunctbl[mask] = fpuop_do_fldlg2;
 
5849
                                                                break;
 
5850
                                                        case 0x0c:
 
5851
                                                                fpufunctbl[mask] = fpuop_do_load_const_e;
 
5852
                                                                break;
 
5853
                                                        case 0x0d:
 
5854
                                                                fpufunctbl[mask] = fpuop_do_fldl2e;
 
5855
                                                                break;
 
5856
                                                        case 0x0e:
 
5857
                                                                fpufunctbl[mask] = fpuop_do_load_const_log_10_e;
 
5858
                                                                break;
 
5859
                                                        case 0x0f:
 
5860
                                                                fpufunctbl[mask] = fpuop_do_fldz;
 
5861
                                                                break;
 
5862
                                                        case 0x30:
 
5863
                                                                fpufunctbl[mask] = fpuop_do_fldln2;
 
5864
                                                                break;
 
5865
                                                        case 0x31:
 
5866
                                                                fpufunctbl[mask] = fpuop_do_load_const_ln_10;
 
5867
                                                                break;
 
5868
                                                        case 0x32:
 
5869
                                                                fpufunctbl[mask] = fpuop_do_fld1;
 
5870
                                                                break;
 
5871
                                                        case 0x33:
 
5872
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e1;
 
5873
                                                                break;
 
5874
                                                        case 0x34:
 
5875
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e2;
 
5876
                                                                break;
 
5877
                                                        case 0x35:
 
5878
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e4;
 
5879
                                                                break;
 
5880
                                                        case 0x36:
 
5881
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e8;
 
5882
                                                                break;
 
5883
                                                        case 0x37:
 
5884
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e16;
 
5885
                                                                break;
 
5886
                                                        case 0x38:
 
5887
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e32;
 
5888
                                                                break;
 
5889
                                                        case 0x39:
 
5890
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e64;
 
5891
                                                                break;
 
5892
                                                        case 0x3a:
 
5893
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e128;
 
5894
                                                                break;
 
5895
                                                        case 0x3b:
 
5896
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e256;
 
5897
                                                                break;
 
5898
                                                        case 0x3c:
 
5899
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e512;
 
5900
                                                                break;
 
5901
                                                        case 0x3d:
 
5902
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e1024;
 
5903
                                                                break;
 
5904
                                                        case 0x3e:
 
5905
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e2048;
 
5906
                                                                break;
 
5907
                                                        case 0x3f:
 
5908
                                                                fpufunctbl[mask] = fpuop_do_load_const_1e4096;
 
5909
                                                                break;
 
5910
                                                }
 
5911
                                                break;
 
5912
                                        }
 
5913
                                        
 
5914
                                        switch (extra & 0x7f) {
 
5915
                                                case 0x00:
 
5916
                                                        fpufunctbl[mask] = fpuop_do_fmove;
 
5917
                                                        break;
 
5918
                                                case 0x01:
 
5919
                                                        fpufunctbl[mask] = fpuop_do_fint;
 
5920
                                                        break;
 
5921
                                                case 0x02:
 
5922
                                                        fpufunctbl[mask] = fpuop_do_fsinh;
 
5923
                                                        break;
 
5924
                                                case 0x03:
 
5925
                                                        fpufunctbl[mask] = fpuop_do_fintrz;
 
5926
                                                        break;
 
5927
                                                case 0x04:
 
5928
                                                        fpufunctbl[mask] = fpuop_do_fsqrt;
 
5929
                                                        break;
 
5930
                                                case 0x06:
 
5931
                                                        fpufunctbl[mask] = fpuop_do_flognp1;
 
5932
                                                        break;
 
5933
                                                case 0x08:
 
5934
                                                        fpufunctbl[mask] = fpuop_do_fetoxm1;
 
5935
                                                        break;
 
5936
                                                case 0x09:
 
5937
                                                        fpufunctbl[mask] = fpuop_do_ftanh;
 
5938
                                                        break;
 
5939
                                                case 0x0a:
 
5940
                                                        fpufunctbl[mask] = fpuop_do_fatan;
 
5941
                                                        break;
 
5942
                                                case 0x0c:
 
5943
                                                        fpufunctbl[mask] = fpuop_do_fasin;
 
5944
                                                        break;
 
5945
                                                case 0x0d:
 
5946
                                                        fpufunctbl[mask] = fpuop_do_fatanh;
 
5947
                                                        break;
 
5948
                                                case 0x0e:
 
5949
                                                        fpufunctbl[mask] = fpuop_do_fsin;
 
5950
                                                        break;
 
5951
                                                case 0x0f:
 
5952
                                                        fpufunctbl[mask] = fpuop_do_ftan;
 
5953
                                                        break;
 
5954
                                                case 0x10:
 
5955
                                                        fpufunctbl[mask] = fpuop_do_fetox;
 
5956
                                                        break;
 
5957
                                                case 0x11:
 
5958
                                                        fpufunctbl[mask] = fpuop_do_ftwotox;
 
5959
                                                        break;
 
5960
                                                case 0x12:
 
5961
                                                        fpufunctbl[mask] = fpuop_do_ftentox;
 
5962
                                                        break;
 
5963
                                                case 0x14:
 
5964
                                                        fpufunctbl[mask] = fpuop_do_flogn;
 
5965
                                                        break;
 
5966
                                                case 0x15:
 
5967
                                                        fpufunctbl[mask] = fpuop_do_flog10;
 
5968
                                                        break;
 
5969
                                                case 0x16:
 
5970
                                                        fpufunctbl[mask] = fpuop_do_flog2;
 
5971
                                                        break;
 
5972
                                                case 0x18:
 
5973
                                                        fpufunctbl[mask] = fpuop_do_fabs;
 
5974
                                                        break;
 
5975
                                                case 0x19:
 
5976
                                                        fpufunctbl[mask] = fpuop_do_fcosh;
 
5977
                                                        break;
 
5978
                                                case 0x1a:
 
5979
                                                        fpufunctbl[mask] = fpuop_do_fneg;
 
5980
                                                        break;
 
5981
                                                case 0x1c:
 
5982
                                                        fpufunctbl[mask] = fpuop_do_facos;
 
5983
                                                        break;
 
5984
                                                case 0x1d:
 
5985
                                                        fpufunctbl[mask] = fpuop_do_fcos;
 
5986
                                                        break;
 
5987
                                                case 0x1e:
 
5988
                                                        fpufunctbl[mask] = fpuop_do_fgetexp;
 
5989
                                                        break;
 
5990
                                                case 0x1f:
 
5991
                                                        fpufunctbl[mask] = fpuop_do_fgetman;
 
5992
                                                        break;
 
5993
                                                case 0x20:
 
5994
                                                        fpufunctbl[mask] = fpuop_do_fdiv;
 
5995
                                                        break;
 
5996
                                                case 0x21:
 
5997
                                                        fpufunctbl[mask] = fpuop_do_fmod;
 
5998
                                                        break;
 
5999
                                                case 0x22:
 
6000
                                                        fpufunctbl[mask] = fpuop_do_fadd;
 
6001
                                                        break;
 
6002
                                                case 0x23:
 
6003
                                                        fpufunctbl[mask] = fpuop_do_fmul;
 
6004
                                                        break;
 
6005
                                                case 0x24:
 
6006
                                                        fpufunctbl[mask] = fpuop_do_fsgldiv;
 
6007
                                                        break;
 
6008
                                                case 0x25:
 
6009
                                                        fpufunctbl[mask] = fpuop_do_frem;
 
6010
                                                        break;
 
6011
                                                case 0x26:
 
6012
                                                        fpufunctbl[mask] = fpuop_do_fscale;
 
6013
                                                        break;
 
6014
                                                case 0x27:
 
6015
                                                        fpufunctbl[mask] = fpuop_do_fsglmul;
 
6016
                                                        break;
 
6017
                                                case 0x28:
 
6018
                                                        fpufunctbl[mask] = fpuop_do_fsub;
 
6019
                                                        break;
 
6020
                                                case 0x30:
 
6021
                                                case 0x31:
 
6022
                                                case 0x32:
 
6023
                                                case 0x33:
 
6024
                                                case 0x34:
 
6025
                                                case 0x35:
 
6026
                                                case 0x36:
 
6027
                                                case 0x37:
 
6028
                                                        fpufunctbl[mask] = fpuop_do_fsincos;
 
6029
                                                        break;
 
6030
                                                case 0x38:
 
6031
                                                        fpufunctbl[mask] = fpuop_do_fcmp;
 
6032
                                                        break;
 
6033
                                                case 0x3a:
 
6034
                                                        fpufunctbl[mask] = fpuop_do_ftst;
 
6035
                                                        break;
 
6036
                                        }
 
6037
                                }
 
6038
                        }
 
6039
                }
 
6040
        }
 
6041
}
 
6042
 
 
6043
static void build_fpsr_lookup_tables()
 
6044
{
 
6045
        uae_u32 i;
 
6046
 
 
6047
        // Mapping for "sw" -> fpsr condition code
 
6048
        for( i=0; i<0x48; i++ ) {
 
6049
                sw_cond_host2mac[i] = 0;
 
6050
                switch( (i << 8) & (SW_Z_I_NAN_MASK) ) {
 
6051
                        case SW_UNSUPPORTED:
 
6052
                        case SW_NAN:
 
6053
                        case SW_EMPTY_REGISTER:
 
6054
                                sw_cond_host2mac[i] |= 0x1000000;
 
6055
                                break;
 
6056
                        case SW_FINITE:
 
6057
                        case SW_DENORMAL:
 
6058
                                break;
 
6059
                        case SW_I:
 
6060
                                sw_cond_host2mac[i] |= 0x2000000;
 
6061
                                break;
 
6062
                        case SW_Z:
 
6063
                                sw_cond_host2mac[i] |= 0x4000000;
 
6064
                                break;
 
6065
                }
 
6066
                if( (i << 8) & SW_N ) {
 
6067
                        sw_cond_host2mac[i] |= 0x8000000;
 
6068
                }
 
6069
        }
 
6070
 
 
6071
        // Mapping for fpsr condition code -> "sw"
 
6072
        for( i=0; i<16; i++ ) {
 
6073
                if( (i << 24) & 0x1000000 ) {
 
6074
                        sw_cond_mac2host[i] = SW_NAN;
 
6075
                } else if( (i << 24) & 0x4000000 ) {
 
6076
                        sw_cond_mac2host[i] = SW_Z;
 
6077
                } else if( (i << 24) & 0x2000000 ) {
 
6078
                        sw_cond_mac2host[i] = SW_I;
 
6079
                } else {
 
6080
                        sw_cond_mac2host[i] = SW_FINITE;
 
6081
                }
 
6082
                if( (i << 24) & 0x8000000 ) {
 
6083
                        sw_cond_mac2host[i] |= SW_N;
 
6084
                }
 
6085
        }
 
6086
 
 
6087
        // Mapping for "sw" -> fpsr exception byte
 
6088
        for( i=0; i<0x80; i++ ) {
 
6089
                exception_host2mac[i] = 0;
 
6090
 
 
6091
                if(i & SW_FAKE_BSUN) {
 
6092
                        exception_host2mac[i] |= BSUN;
 
6093
                }
 
6094
                // precision exception
 
6095
                if(i & SW_PE) {
 
6096
                        exception_host2mac[i] |= INEX2;
 
6097
                }
 
6098
                // underflow exception
 
6099
                if(i & SW_UE) {
 
6100
                        exception_host2mac[i] |= UNFL;
 
6101
                }
 
6102
                // overflow exception
 
6103
                if(i & SW_OE) {
 
6104
                        exception_host2mac[i] |= OVFL;
 
6105
                }
 
6106
                // zero divide exception
 
6107
                if(i & SW_ZE) {
 
6108
                        exception_host2mac[i] |= DZ;
 
6109
                }
 
6110
                // denormalized operand exception.
 
6111
                // wrong, but should not get here, normalization is done in elsewhere
 
6112
                if(i & SW_DE) {
 
6113
                        exception_host2mac[i] |= SNAN;
 
6114
                }
 
6115
                // invalid operation exception
 
6116
                if(i & SW_IE) {
 
6117
                        exception_host2mac[i] |= OPERR;
 
6118
                }
 
6119
        }
 
6120
 
 
6121
        // Mapping for fpsr exception byte -> "sw"
 
6122
        for( i=0; i<0x100; i++ ) {
 
6123
                int fpsr = (i << 8);
 
6124
                exception_mac2host[i] = 0;
 
6125
 
 
6126
                // BSUN; make sure that you don't generate FPU stack faults.
 
6127
                if(fpsr & BSUN) {
 
6128
                        exception_mac2host[i] |= SW_FAKE_BSUN;
 
6129
                }
 
6130
                // precision exception
 
6131
                if(fpsr & INEX2) {
 
6132
                        exception_mac2host[i] |= SW_PE;
 
6133
                }
 
6134
                // underflow exception
 
6135
                if(fpsr & UNFL) {
 
6136
                        exception_mac2host[i] |= SW_UE;
 
6137
                }
 
6138
                // overflow exception
 
6139
                if(fpsr & OVFL) {
 
6140
                        exception_mac2host[i] |= SW_OE;
 
6141
                }
 
6142
                // zero divide exception
 
6143
                if(fpsr & DZ) {
 
6144
                        exception_mac2host[i] |= SW_ZE;
 
6145
                }
 
6146
                // denormalized operand exception
 
6147
                if(fpsr & SNAN) {
 
6148
                        exception_mac2host[i] |= SW_DE; //Wrong
 
6149
                }
 
6150
                // invalid operation exception
 
6151
                if(fpsr & OPERR) {
 
6152
                        exception_mac2host[i] |= SW_IE;
 
6153
                }
 
6154
        }
 
6155
 
 
6156
        /*
 
6157
                68881/68040 accrued exceptions accumulate as follows:
 
6158
                        Accrued.IOP             |= (Exception.SNAN | Exception.OPERR)
 
6159
                        Accrued.OVFL    |= (Exception.OVFL)
 
6160
                        Accrued.UNFL    |= (Exception.UNFL | Exception.INEX2)
 
6161
                        Accrued.DZ              |= (Exception.DZ)
 
6162
                        Accrued.INEX    |= (Exception.INEX1 | Exception.INEX2 | Exception.OVFL)
 
6163
        */
 
6164
 
 
6165
        // Mapping for "sw_accrued" -> fpsr accrued exception byte
 
6166
        for( i=0; i<0x40; i++ ) {
 
6167
                accrued_exception_host2mac[i] = 0;
 
6168
 
 
6169
                // precision exception
 
6170
                if(i & SW_PE) {
 
6171
                        accrued_exception_host2mac[i] |= ACCR_INEX;
 
6172
                }
 
6173
                // underflow exception
 
6174
                if(i & SW_UE) {
 
6175
                        accrued_exception_host2mac[i] |= ACCR_UNFL;
 
6176
                }
 
6177
                // overflow exception
 
6178
                if(i & SW_OE) {
 
6179
                        accrued_exception_host2mac[i] |= ACCR_OVFL;
 
6180
                }
 
6181
                // zero divide exception
 
6182
                if(i & SW_ZE) {
 
6183
                        accrued_exception_host2mac[i] |= ACCR_DZ;
 
6184
                }
 
6185
                // denormalized operand exception
 
6186
                if(i & SW_DE) {
 
6187
                        accrued_exception_host2mac[i] |= ACCR_IOP; //??????
 
6188
                }
 
6189
                // invalid operation exception
 
6190
                if(i & SW_IE) {
 
6191
                        accrued_exception_host2mac[i] |= ACCR_IOP;
 
6192
                }
 
6193
        }
 
6194
 
 
6195
        // Mapping for fpsr accrued exception byte -> "sw_accrued"
 
6196
        for( i=0; i<0x20; i++ ) {
 
6197
                int fpsr = (i << 3);
 
6198
                accrued_exception_mac2host[i] = 0;
 
6199
 
 
6200
                // precision exception
 
6201
                if(fpsr & ACCR_INEX) {
 
6202
                        accrued_exception_mac2host[i] |= SW_PE;
 
6203
                }
 
6204
                // underflow exception
 
6205
                if(fpsr & ACCR_UNFL) {
 
6206
                        accrued_exception_mac2host[i] |= SW_UE;
 
6207
                }
 
6208
                // overflow exception
 
6209
                if(fpsr & ACCR_OVFL) {
 
6210
                        accrued_exception_mac2host[i] |= SW_OE;
 
6211
                }
 
6212
                // zero divide exception
 
6213
                if(fpsr & ACCR_DZ) {
 
6214
                        accrued_exception_mac2host[i] |= SW_ZE;
 
6215
                }
 
6216
                // What about SW_DE; //??????
 
6217
                // invalid operation exception
 
6218
                if(fpsr & ACCR_IOP) {
 
6219
                        accrued_exception_mac2host[i] |= SW_IE;
 
6220
                }
 
6221
        }
 
6222
}
 
6223
 
 
6224
/* ---------------------------- CONSTANTS ---------------------------- */
 
6225
 
 
6226
static void set_constant( float80 f, char *name, double value, uae_s32 mult )
 
6227
{
 
6228
        FPU_CONSISTENCY_CHECK_START();
 
6229
        if(mult == 1) {
 
6230
/*              _asm {
 
6231
                        MOV                     ESI, [f]
 
6232
                        FLD     QWORD PTR [value]
 
6233
                        FSTP    TBYTE PTR [ESI]
 
6234
                } */
 
6235
                _ASM(   "fldl   %1\n"
 
6236
                                "fstpt  %0\n"
 
6237
                        :       "=m" (*f)
 
6238
                        :       "m" (value)
 
6239
                        );
 
6240
        } else {
 
6241
/*              _asm {
 
6242
                        MOV                     ESI, [f]
 
6243
                        FILD    DWORD PTR [mult]
 
6244
                        FLD     QWORD PTR [value]
 
6245
                        FMUL
 
6246
                        FSTP    TBYTE PTR [ESI]
 
6247
                } */
 
6248
                _ASM(   "fildl  %2\n"
 
6249
                                "fldl   %1\n"
 
6250
                                "fmul   \n"
 
6251
                                "fstpt  %0\n"
 
6252
                        :       "=m" (*f)
 
6253
                        :       "m" (value), "m" (mult)
 
6254
                        );
 
6255
        }
 
6256
        D(bug("set_constant (%s,%.04f) = %s\r\n",name,(float)value,etos(f)));
 
6257
        FPU_CONSISTENCY_CHECK_STOP( mult==1 ? "set_constant(mult==1)" : "set_constant(mult>1)" );
 
6258
}
 
6259
 
 
6260
static void do_fldpi( float80 dest ) REGPARAM;
 
6261
static void do_fldpi( float80 dest )
 
6262
{
 
6263
        FPU_CONSISTENCY_CHECK_START();
 
6264
/*      _asm {
 
6265
                FLDPI
 
6266
                FXAM
 
6267
    FNSTSW  sw
 
6268
                MOV                     EDI, [dest]
 
6269
                FSTP    TBYTE PTR [EDI]
 
6270
        } */
 
6271
        _ASM(   "fldpi  \n"
 
6272
                        "fxam   \n"
 
6273
                        "fnstsw %0\n"
 
6274
                        "fstpt  %1\n"
 
6275
                :       "=m" (sw), "=m" (*dest)
 
6276
                );
 
6277
        FPU_CONSISTENCY_CHECK_STOP("do_fldpi");
 
6278
}
 
6279
 
 
6280
static void do_fldlg2( float80 dest ) REGPARAM;
 
6281
static void do_fldlg2( float80 dest )
 
6282
{
 
6283
        FPU_CONSISTENCY_CHECK_START();
 
6284
/*      _asm {
 
6285
                FLDLG2
 
6286
                FXAM
 
6287
    FNSTSW  sw
 
6288
                MOV                     EDI, [dest]
 
6289
                FSTP    TBYTE PTR [EDI]
 
6290
        } */
 
6291
        _ASM(   "fldlg2 \n"
 
6292
                        "fxam   \n"
 
6293
                        "fnstsw %0\n"
 
6294
                        "fstpt  %1\n"
 
6295
                :       "=m" (sw), "=m" (*dest)
 
6296
                );
 
6297
        FPU_CONSISTENCY_CHECK_STOP("do_fldlg2");
 
6298
}
 
6299
 
 
6300
static void do_fldl2e( float80 dest ) REGPARAM;
 
6301
static void do_fldl2e( float80 dest )
 
6302
{
 
6303
        FPU_CONSISTENCY_CHECK_START();
 
6304
/*      _asm {
 
6305
                FLDL2E
 
6306
                FXAM
 
6307
    FNSTSW  sw
 
6308
                MOV                     EDI, [dest]
 
6309
                FSTP    TBYTE PTR [EDI]
 
6310
        } */
 
6311
        _ASM(   "fldl2e \n"
 
6312
                        "fxam   \n"
 
6313
                        "fnstsw %0\n"
 
6314
                        "fstpt  %1\n"
 
6315
                :       "=m" (sw), "=m" (*dest)
 
6316
                );
 
6317
        FPU_CONSISTENCY_CHECK_STOP("do_fldl2e");
 
6318
}
 
6319
 
 
6320
static void do_fldz( float80 dest ) REGPARAM;
 
6321
static void do_fldz( float80 dest )
 
6322
{
 
6323
        FPU_CONSISTENCY_CHECK_START();
 
6324
/*      _asm {
 
6325
                FLDZ
 
6326
                FXAM
 
6327
    FNSTSW  sw
 
6328
                MOV                     EDI, [dest]
 
6329
                FSTP    TBYTE PTR [EDI]
 
6330
        } */
 
6331
        _ASM(   "fldz   \n"
 
6332
                        "fxam   \n"
 
6333
                        "fnstsw %0\n"
 
6334
                        "fstpt  %1\n"
 
6335
                :       "=m" (sw), "=m" (*dest)
 
6336
                );
 
6337
        FPU_CONSISTENCY_CHECK_STOP("do_fldz");
 
6338
}
 
6339
 
 
6340
static void do_fldln2( float80 dest ) REGPARAM;
 
6341
static void do_fldln2( float80 dest )
 
6342
{
 
6343
        FPU_CONSISTENCY_CHECK_START();
 
6344
/*      _asm {
 
6345
                FLDLN2
 
6346
                FXAM
 
6347
    FNSTSW  sw
 
6348
                MOV                     EDI, [dest]
 
6349
                FSTP    TBYTE PTR [EDI]
 
6350
        } */
 
6351
        _ASM(   "fldln2 \n"
 
6352
                        "fxam   \n"
 
6353
                        "fnstsw %0\n"
 
6354
                        "fstpt  %1\n"
 
6355
                :       "=m" (sw), "=m" (*dest)
 
6356
                );
 
6357
        FPU_CONSISTENCY_CHECK_STOP("do_fldln2");
 
6358
}
 
6359
 
 
6360
static void do_fld1( float80 dest ) REGPARAM;
 
6361
static void do_fld1( float80 dest )
 
6362
{
 
6363
        FPU_CONSISTENCY_CHECK_START();
 
6364
/*      _asm {
 
6365
                FLD1
 
6366
                FXAM
 
6367
    FNSTSW  sw
 
6368
                MOV                     EDI, [dest]
 
6369
                FSTP    TBYTE PTR [EDI]
 
6370
        } */
 
6371
        _ASM(   "fld1   \n"
 
6372
                        "fxam   \n"
 
6373
                        "fnstsw %0\n"
 
6374
                        "fstpt  %1\n"
 
6375
                :       "=m" (sw), "=m" (*dest)
 
6376
                );
 
6377
        FPU_CONSISTENCY_CHECK_STOP("do_fld1");
 
6378
}
 
6379
 
 
6380
 
 
6381
/* ---------------------------- MAIN INIT ---------------------------- */
 
6382
 
 
6383
void fpu_init( void )
 
6384
{
 
6385
/*      _asm {
 
6386
    FSAVE   m_fpu_state_original
 
6387
        } */
 
6388
        _ASM("fsave %0" : "=m" (m_fpu_state_original));
 
6389
 
 
6390
        regs.fpiar = 0;
 
6391
        regs.fpcr = 0;
 
6392
        regs.fpsr = 0;
 
6393
 
 
6394
        cw = CW_INITIAL; 
 
6395
        sw = SW_INITIAL;
 
6396
        sw_accrued = 0;
 
6397
        sw_quotient = 0;
 
6398
 
 
6399
        for( int i=0; i<8; i++ ) {
 
6400
                MAKE_NAN( fp_reg[i] );
 
6401
        }
 
6402
        
 
6403
        build_fpsr_lookup_tables();
 
6404
        build_fpp_opp_lookup_table();
 
6405
 
 
6406
/*      _asm {
 
6407
                FNINIT
 
6408
                FLDCW   cw
 
6409
        } */
 
6410
        _ASM("fninit\nfldcw %0" : : "m" (cw));
 
6411
 
 
6412
        do_fldpi( const_pi );
 
6413
        do_fldlg2( const_lg2 );
 
6414
        do_fldl2e( const_l2e );
 
6415
        do_fldz( const_z );
 
6416
        do_fldln2( const_ln2 );
 
6417
        do_fld1( const_1 );
 
6418
 
 
6419
        set_constant( const_e,                  "e",                    exp (1.0), 1 );
 
6420
        set_constant( const_log_10_e,   "Log 10 (e)",   log (exp (1.0)) / log (10.0), 1 );
 
6421
        set_constant( const_ln_10,              "ln(10)",               log (10.0), 1 );
 
6422
        set_constant( const_1e1,                "1.0e1",                1.0e1, 1 );
 
6423
        set_constant( const_1e2,                "1.0e2",                1.0e2, 1 );
 
6424
        set_constant( const_1e4,                "1.0e4",                1.0e4, 1 );
 
6425
        set_constant( const_1e8,                "1.0e8",                1.0e8, 1 );
 
6426
        set_constant( const_1e16,               "1.0e16",               1.0e16, 1 );
 
6427
        set_constant( const_1e32,               "1.0e32",               1.0e32, 1 );
 
6428
        set_constant( const_1e64,               "1.0e64",               1.0e64, 1 ) ;
 
6429
        set_constant( const_1e128,              "1.0e128",              1.0e128, 1 );
 
6430
        set_constant( const_1e256,              "1.0e256",              1.0e256, 1 );
 
6431
        set_constant( const_1e512,              "1.0e512",              1.0e256, 10 );
 
6432
        set_constant( const_1e1024,             "1.0e1024",             1.0e256, 100 );
 
6433
        set_constant( const_1e2048,             "1.0e2048",             1.0e256, 1000 );
 
6434
        set_constant( const_1e4096,             "1.0e4096",             1.0e256, 10000 );
 
6435
        
 
6436
        // Just in case.
 
6437
/*      _asm {
 
6438
                FNINIT
 
6439
                FLDCW   cw
 
6440
        } */
 
6441
        _ASM("fninit\nfldcw %0" : : "m" (cw));
 
6442
}
 
6443
 
 
6444
void fpu_exit( void )
 
6445
{
 
6446
/*      _asm {
 
6447
    FRSTOR  m_fpu_state_original
 
6448
                // FNINIT
 
6449
        } */
 
6450
        _ASM("frstor %0" : : "m" (m_fpu_state_original));
 
6451
}
 
6452
 
 
6453
void fpu_reset( void )
 
6454
{
 
6455
        fpu_exit();
 
6456
        fpu_init();
 
6457
}
 
6458
 
 
6459
#if DEBUG
 
6460
#pragma optimize("",on)
 
6461
#endif