2
* fpu_x86.cpp - 68881/68040 fpu code for x86/Windows an Linux/x86.
4
* Basilisk II (C) 1997-1999 Christian Bauer
6
* MC68881/68040 fpu emulation
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.
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.
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.
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
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.
33
* The reason is not really speed, but to get infinities,
34
* NANs and flags finally working.
37
* How to maintain Mac and x86 FPU flags -- plan B
39
* regs.piar is not updated.
41
* regs.fpcr always contains the real 68881/68040 control word.
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.
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.
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.
68
* When "sw" and "sw_accrued" are stored, all pending x86 FPU
69
* exceptions are cleared, if there are any.
71
* Writing to "regs.fpsr" reverse-maps to x86 status/exception values
72
* and stores the values in "sw", "sw_accrued" and "sw_quotient".
74
* So, "sw" and "sw_accrued" are not in correct bit positions
75
* and have x86 values, but "sw_quotient" is at correct position.
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.
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.
85
* x86 co-processor initialization:
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
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
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()
138
#include "fpu_x86_asm.h"
140
/* ---------------------------- Compatibility ---------------------------- */
145
#define _ASM __asm__ __volatile__
146
#define min(a, b) (((a) < (b)) ? (a) : (b))
148
/* ---------------------------- Configuration ---------------------------- */
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.
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.
161
gb-- I only tested the following configurations:
162
USE_3_BIT_QUOTIENT 1 -- still changes to apply if no 3-bit quotient
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
168
#define USE_3_BIT_QUOTIENT 1
171
#define USE_CONSISTENCY_CHECKING 0
173
#define I3_ON_ILLEGAL_FPU_OP 0
174
#define I3_ON_FTRAPCC 0
177
/* ---------------------------- Registers ---------------------------- */
179
// "regs.fp" is not used. regs.fpcr, regs.fpsr and regs.fpiar are used.
181
typedef BYTE *float80;
182
typedef BYTE float80_s[10];
183
typedef BYTE float80_s_aligned[16];
185
static float80_s_aligned fp_reg[8];
188
/* ---------------------------- Debugging ---------------------------- */
191
//#pragma optimize("",off)
194
// extern "C" {int debugging_fpp = 0;}
202
//#define D(x) { if(debugging_fpp) { (x); } }
204
static void dump_first_bytes_buf( char *b, BYTE *buf, int32 actual )
207
int32 i, bytes = min(actual,100);
210
for (i=0; i<bytes; i++) {
211
sprintf( bb, "%02x ", (uint32)buf[i] );
214
strcat((char*)b,"\r\n");
217
static void dump_first_bytes( BYTE *buf, int32 actual )
220
dump_first_bytes_buf( msg, buf, actual );
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 )
228
static char _s[10][30];
244
if(++_ix >= 10) _ix = 0;
246
sprintf( _s[_ix], "%.04f", (float)f );
249
static void dump_fp_regs( char *s )
255
"%s: %s, %s, %s, %s, %s, %s, %s, %s\r\n",
270
#define CONDRET(s,x) return (x)
271
#define dump_fp_regs(s) {}
275
/* ---------------------------- FPU consistency ---------------------------- */
277
#if USE_CONSISTENCY_CHECKING
278
static uae_u16 checked_sw_atstart;
280
static void FPU_CONSISTENCY_CHECK_START()
283
FNSTSW checked_sw_atstart
285
_ASM("fnstsw %0" : "=m" (checked_sw_atstart));
288
static void FPU_CONSISTENCY_CHECK_STOP(char *name)
290
uae_u16 checked_sw_atend;
291
// _asm FNSTSW checked_sw_atend
292
_ASM("fnstsw %0" : "=m" (checked_sw_attend));
295
// Check for FPU stack overflows/underflows.
296
if( (checked_sw_atend & 0x3800) != (checked_sw_atstart & 0x3800) ) {
299
"FPU stack leak at %s, %X, %X\r\n",
301
(int)(checked_sw_atstart & 0x3800) >> 11,
302
(int)(checked_sw_atend & 0x3800) >> 11
304
OutputDebugString(msg);
307
// Observe status mapping.
309
if(checked_sw_atstart != 0x400 || checked_sw_atend != 0x400) {
311
msg, "Op %s, sw before=%X, sw after=%X\r\n",
312
name, (int)checked_sw_atstart, (int)checked_sw_atend
314
OutputDebugString(msg);
319
#define FPU_CONSISTENCY_CHECK_START()
320
#define FPU_CONSISTENCY_CHECK_STOP(name)
324
/* ---------------------------- FPU type ---------------------------- */
326
static uae_u32 is_integral_68040_fpu = 0;
329
/* ---------------------------- Status byte ---------------------------- */
331
// Extend the SW_* codes
332
#define SW_FAKE_BSUN SW_SF
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)
338
// Map x86 FXAM codes -> m68k fpu status byte
339
#define SW_Z_I_NAN_MASK (SW_C0|SW_C2|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)
349
// Initial state after boot, reset and frestore(null frame)
350
#define SW_INITIAL SW_FINITE
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;
358
/* ---------------------------- Control word ---------------------------- */
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)
363
static WORD cw = CW_INITIAL;
366
/* ---------------------------- FMOVECR constants ---------------------------- */
369
// Suported by x86 FPU
377
// Not suported by x86 FPU
396
/* ---------------------------- Saved host FPU state ---------------------------- */
398
static BYTE m_fpu_state_original[108]; // 90/94/108
401
/* ---------------------------- Map tables ---------------------------- */
403
typedef void REGPARAM2 fpuop_func( uae_u32, uae_u16 );
404
extern "C" { fpuop_func *fpufunctbl[65536]; }
406
// Control word -- need only one-way mapping
407
static const uae_u16 cw_rc_mac2host[] = {
413
static const uae_u16 cw_pc_mac2host[] = {
420
// Status word -- need two-way mapping
421
static uae_u32 sw_cond_host2mac[ 0x48 ];
422
static uae_u16 sw_cond_mac2host[ 16 ];
424
static uae_u32 exception_host2mac[ 0x80 ];
425
static uae_u32 exception_mac2host[ 0x100 ];
427
static uae_u32 accrued_exception_host2mac[ 0x40 ];
428
static uae_u32 accrued_exception_mac2host[ 0x20 ];
431
/* ---------------------------- Control functions ---------------------------- */
434
Exception enable byte is ignored, but the same value is returned
435
that was previously set.
437
static void __inline__ set_host_fpu_control_word()
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 ];
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).
448
_ASM("fldcw %0" : : "m" (cw));
452
/* ---------------------------- Status functions ---------------------------- */
454
static void __inline__ SET_BSUN_ON_NAN()
456
if( (sw & (SW_Z_I_NAN_MASK)) == SW_NAN ) {
462
static void __inline__ build_ex_status()
464
if(sw & SW_EXCEPTION_MASK) {
471
static void __inline__ to_fpsr()
474
sw_cond_host2mac[ (sw & 0x4700) >> 8 ] |
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) ]
481
static void __inline__ from_fpsr()
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 ];
491
// TODO_BIGENDIAN; all of these.
492
/* ---------------------------- Type functions ---------------------------- */
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.
499
static __inline__ void MAKE_NAN(float80 p)
501
// Make it non-signaling.
502
memset( p, 0xFF, sizeof(float80_s)-1 );
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.
511
static __inline__ uae_u32 IS_INFINITY(float80 p)
513
if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) {
514
if( *((uae_u32 *)p) == 0 &&
515
( *((uae_u32 *)&p[4]) & 0x7FFFFFFF ) == 0 )
523
static __inline__ uae_u32 IS_NAN(float80 p)
525
if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) {
526
if( *((uae_u32 *)p) != 0 ||
527
( *((uae_u32 *)&p[4]) & 0x7FFFFFFF ) != 0 )
535
static __inline__ uae_u32 IS_ZERO(float80 p)
537
return *((uae_u32 *)p) == 0 &&
538
*((uae_u32 *)&p[4]) == 0 &&
539
( *((uae_u16 *)&p[8]) & 0x7FFF ) == 0;
542
static __inline__ void MAKE_INF_POSITIVE(float80 p)
544
memset( p, 0, sizeof(float80_s)-2 );
545
*((uae_u16 *)&p[8]) = 0x7FFF;
548
static __inline__ void MAKE_INF_NEGATIVE(float80 p)
550
memset( p, 0, sizeof(float80_s)-2 );
551
*((uae_u16 *)&p[8]) = 0xFFFF;
554
static __inline__ void MAKE_ZERO_POSITIVE(float80 p)
556
memset( p, 0, sizeof(float80_s) );
559
static __inline__ void MAKE_ZERO_NEGATIVE(float80 *p)
561
memset( p, 0, sizeof(float80_s) );
562
*((uae_u32 *)&p[4]) = 0x80000000;
565
static __inline__ uae_u32 IS_NEGATIVE(float80 p)
567
return( (p[9] & 0x80) != 0 );
571
/* ---------------------------- Conversions ---------------------------- */
573
static void signed_to_extended( uae_s32 x, float80 f ) REGPARAM;
574
static void signed_to_extended( uae_s32 x, float80 f )
576
FPU_CONSISTENCY_CHECK_START();
590
D(bug("signed_to_extended (%X) = %s\r\n",(int)x,etos(f)));
591
FPU_CONSISTENCY_CHECK_STOP("signed_to_extended");
594
static uae_s32 extended_to_signed_32( float80 f ) REGPARAM;
595
static uae_s32 extended_to_signed_32( float80 f )
597
FPU_CONSISTENCY_CHECK_START();
611
: "=m" (tmp), "=m" (sw_temp)
615
if(sw_temp & SW_EXCEPTION_MASK) {
618
if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR.
621
// Setting the value to zero might not be the right way to go,
622
// but I'll leave it like this for now.
625
if(sw_temp & SW_PE) {
631
D(bug("extended_to_signed_32 (%s) = %X\r\n",etos(f),(int)tmp));
632
FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_32");
636
static uae_s16 extended_to_signed_16( float80 f ) REGPARAM;
637
static uae_s16 extended_to_signed_16( float80 f )
639
FPU_CONSISTENCY_CHECK_START();
653
: "=m" (tmp), "=m" (sw_temp)
657
if(sw_temp & SW_EXCEPTION_MASK) {
660
if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR.
665
if(sw_temp & SW_PE) {
671
D(bug("extended_to_signed_16 (%s) = %X\r\n",etos(f),(int)tmp));
672
FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_16");
676
static uae_s8 extended_to_signed_8( float80 f ) REGPARAM;
677
static uae_s8 extended_to_signed_8( float80 f )
679
FPU_CONSISTENCY_CHECK_START();
693
: "=m" (tmp), "=m" (sw_temp)
697
if(sw_temp & SW_EXCEPTION_MASK) {
700
if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR.
705
if(sw_temp & SW_PE) {
711
if(tmp > 127 || tmp < -128) { // OPERR
716
D(bug("extended_to_signed_8 (%s) = %X\r\n",etos(f),(int)tmp));
717
FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_8");
721
static void double_to_extended( double x, float80 f ) REGPARAM;
722
static void double_to_extended( double x, float80 f )
724
FPU_CONSISTENCY_CHECK_START();
738
FPU_CONSISTENCY_CHECK_STOP("double_to_extended");
741
static double extended_to_double( float80 f ) REGPARAM;
742
static double extended_to_double( float80 f )
744
FPU_CONSISTENCY_CHECK_START();
750
FSTP QWORD PTR result
759
FPU_CONSISTENCY_CHECK_STOP("extended_to_double");
763
static void to_single( uae_u32 src, float80 f ) REGPARAM;
764
static void to_single( uae_u32 src, float80 f )
766
FPU_CONSISTENCY_CHECK_START();
779
D(bug("to_single (%X) = %s\r\n",src,etos(f)));
780
FPU_CONSISTENCY_CHECK_STOP("to_single");
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 )
787
FPU_CONSISTENCY_CHECK_START();
788
uae_u32 *p = (uae_u32 *)f;
790
uae_u32 sign = (wrd1 & 0x80000000) >> 16;
791
uae_u32 exp = (wrd1 >> 16) & 0x7fff;
794
*((uae_u16 *)&p[2]) = (uae_u16)(sign | exp);
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");
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 )
803
FPU_CONSISTENCY_CHECK_START();
804
uae_u32 *p = (uae_u32 *)f;
806
uae_u32 sign = (wrd1 & 0x80000000) >> 16;
807
uae_u32 exp = (wrd1 >> 16) & 0x7fff;
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));
814
// mantissa, not fraction.
815
uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3;
816
while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) {
820
wrd2 = (uae_u32)( man >> 32 );
821
wrd3 = (uae_u32)( man & 0xFFFFFFFF );
822
if( exp == 0 || (wrd2 & 0x80000000) == 0 ) {
824
wrd2 = wrd3 = exp = 0;
828
if(exp != 0x7FFF && exp != 0) {
829
// Make a non-signaling nan.
839
*((uae_u16 *)&p[2]) = (uae_u16)(sign | exp);
841
D(bug("to_exten (%X,%X,%X) = %s\r\n",wrd1,wrd2,wrd3,etos(f)));
842
FPU_CONSISTENCY_CHECK_STOP("to_exten");
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 )
848
FPU_CONSISTENCY_CHECK_START();
850
// gb-- make GCC happy
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.
875
D(bug("to_double (%X,%X) = %s\r\n",wrd1,wrd2,etos(f)));
876
FPU_CONSISTENCY_CHECK_STOP("to_double");
879
static uae_u32 from_single( float80 f ) REGPARAM;
880
static uae_u32 from_single( float80 f )
882
FPU_CONSISTENCY_CHECK_START();
896
: "=m" (dest), "=m" (sw_temp)
900
sw_temp &= SW_EXCEPTION_MASK;
904
sw = (sw & ~SW_EXCEPTION_MASK) | sw_temp;
905
sw_accrued |= sw_temp;
908
D(bug("from_single (%s) = %X\r\n",etos(f),dest));
909
FPU_CONSISTENCY_CHECK_STOP("from_single");
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 )
917
FPU_CONSISTENCY_CHECK_START();
918
uae_u32 *p = (uae_u32 *)f;
921
*wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16;
923
D(bug("from_exten (%s) = %X,%X,%X\r\n",etos(f),*wrd1,*wrd2,*wrd3));
924
FPU_CONSISTENCY_CHECK_STOP("from_exten");
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 )
930
FPU_CONSISTENCY_CHECK_START();
944
: "=m" (dest), "=m" (sw_temp)
948
sw_temp &= SW_EXCEPTION_MASK;
952
sw = (sw & ~SW_EXCEPTION_MASK) | sw_temp;
953
sw_accrued |= sw_temp;
956
// TODO: There is a partial memory stall, nothing happens until FSTP retires.
957
// On PIII, could use MMX move w/o any penalty.
961
D(bug("from_double (%s) = %X,%X\r\n",etos(f),dest[1],dest[0]));
962
FPU_CONSISTENCY_CHECK_STOP("from_double");
965
static void do_fmove( float80 dest, float80 src ) REGPARAM;
966
static void do_fmove( float80 dest, float80 src )
968
FPU_CONSISTENCY_CHECK_START();
982
: "=m" (sw), "=m" (*dest)
985
FPU_CONSISTENCY_CHECK_STOP("do_fmove");
989
static void do_fmove_no_status( float80 dest, float80 src ) REGPARAM;
990
static void do_fmove_no_status( float80 dest, float80 src )
992
FPU_CONSISTENCY_CHECK_START();
999
FPU_CONSISTENCY_CHECK_STOP("do_fmove_no_status");
1004
/* ---------------------------- Operations ---------------------------- */
1006
static void do_fint( float80 dest, float80 src ) REGPARAM;
1007
static void do_fint( float80 dest, float80 src )
1009
FPU_CONSISTENCY_CHECK_START();
1017
FSTP TBYTE PTR [EDI]
1024
: "=m" (sw), "=m" (*dest)
1027
if(sw & SW_EXCEPTION_MASK) {
1030
sw &= ~(SW_EXCEPTION_MASK - SW_PE);
1033
FPU_CONSISTENCY_CHECK_STOP("do_fint");
1036
static void do_fintrz( float80 dest, float80 src ) REGPARAM;
1037
static void do_fintrz( float80 dest, float80 src )
1039
FPU_CONSISTENCY_CHECK_START();
1046
and cw_temp, ~X86_ROUND_CONTROL_MASK
1047
or cw_temp, CW_RC_ZERO
1054
FSTP TBYTE PTR [EDI]
1058
"andl $(~X86_ROUND_CONTROL_MASK), %0\n"
1059
"orl $CW_RC_ZERO, %0\n"
1067
: "+m" (cw_temp), "=m" (sw), "=m" (*dest)
1068
: "m" (*src), "m" (cw)
1071
if(sw & SW_EXCEPTION_MASK) {
1074
sw &= ~(SW_EXCEPTION_MASK - SW_PE);
1077
FPU_CONSISTENCY_CHECK_STOP("do_fintrz");
1080
static void do_fsqrt( float80 dest, float80 src ) REGPARAM;
1081
static void do_fsqrt( float80 dest, float80 src )
1083
FPU_CONSISTENCY_CHECK_START();
1091
FSTP TBYTE PTR [EDI]
1099
: "=m" (sw), "=m" (*dest)
1103
if(sw & SW_EXCEPTION_MASK) {
1106
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE);
1109
FPU_CONSISTENCY_CHECK_STOP("do_fsqrt");
1112
static void do_ftst( float80 src ) REGPARAM;
1113
static void do_ftst( float80 src )
1115
FPU_CONSISTENCY_CHECK_START();
1132
if(sw & SW_EXCEPTION_MASK) {
1135
sw &= ~SW_EXCEPTION_MASK;
1137
FPU_CONSISTENCY_CHECK_STOP("do_ftst");
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 )
1145
FPU_CONSISTENCY_CHECK_START();
1147
x = extended_to_double( src );
1149
double_to_extended( y, dest );
1151
FPU_CONSISTENCY_CHECK_STOP("do_fsinh");
1154
static void do_flognp1( float80 dest, float80 src ) REGPARAM;
1155
static void do_flognp1( float80 dest, float80 src )
1157
FPU_CONSISTENCY_CHECK_START();
1159
x = extended_to_double( src );
1161
double_to_extended( y, dest );
1163
FPU_CONSISTENCY_CHECK_STOP("do_flognp1");
1166
static void do_fetoxm1( float80 dest, float80 src ) REGPARAM;
1167
static void do_fetoxm1( float80 dest, float80 src )
1169
FPU_CONSISTENCY_CHECK_START();
1171
x = extended_to_double( src );
1173
double_to_extended( y, dest );
1175
FPU_CONSISTENCY_CHECK_STOP("do_fetoxm1");
1178
static void do_ftanh( float80 dest, float80 src ) REGPARAM;
1179
static void do_ftanh( float80 dest, float80 src )
1181
FPU_CONSISTENCY_CHECK_START();
1183
x = extended_to_double( src );
1185
double_to_extended( y, dest );
1187
FPU_CONSISTENCY_CHECK_STOP("do_ftanh");
1190
static void do_fatan( float80 dest, float80 src ) REGPARAM;
1191
static void do_fatan( float80 dest, float80 src )
1193
FPU_CONSISTENCY_CHECK_START();
1195
x = extended_to_double( src );
1197
double_to_extended( y, dest );
1199
FPU_CONSISTENCY_CHECK_STOP("do_fatan");
1202
static void do_fasin( float80 dest, float80 src ) REGPARAM;
1203
static void do_fasin( float80 dest, float80 src )
1205
FPU_CONSISTENCY_CHECK_START();
1207
x = extended_to_double( src );
1209
double_to_extended( y, dest );
1211
FPU_CONSISTENCY_CHECK_STOP("do_fasin");
1214
static void do_fatanh( float80 dest, float80 src ) REGPARAM;
1215
static void do_fatanh( float80 dest, float80 src )
1217
FPU_CONSISTENCY_CHECK_START();
1219
x = extended_to_double( src );
1220
y = log ((1 + x) / (1 - x)) / 2;
1221
double_to_extended( y, dest );
1223
FPU_CONSISTENCY_CHECK_STOP("do_fatanh");
1226
static void do_fetox( float80 dest, float80 src ) REGPARAM;
1227
static void do_fetox( float80 dest, float80 src )
1229
FPU_CONSISTENCY_CHECK_START();
1231
x = extended_to_double( src );
1233
double_to_extended( y, dest );
1235
FPU_CONSISTENCY_CHECK_STOP("do_fetox");
1238
static void do_ftwotox( float80 dest, float80 src ) REGPARAM;
1239
static void do_ftwotox( float80 dest, float80 src )
1241
FPU_CONSISTENCY_CHECK_START();
1243
x = extended_to_double( src );
1245
double_to_extended( y, dest );
1247
FPU_CONSISTENCY_CHECK_STOP("do_ftwotox");
1250
static void do_ftentox( float80 dest, float80 src ) REGPARAM;
1251
static void do_ftentox( float80 dest, float80 src )
1253
FPU_CONSISTENCY_CHECK_START();
1255
x = extended_to_double( src );
1257
double_to_extended( y, dest );
1259
FPU_CONSISTENCY_CHECK_STOP("do_ftentox");
1262
static void do_flogn( float80 dest, float80 src ) REGPARAM;
1263
static void do_flogn( float80 dest, float80 src )
1265
FPU_CONSISTENCY_CHECK_START();
1267
x = extended_to_double( src );
1269
double_to_extended( y, dest );
1271
FPU_CONSISTENCY_CHECK_STOP("do_flogn");
1274
static void do_flog10( float80 dest, float80 src ) REGPARAM;
1275
static void do_flog10( float80 dest, float80 src )
1277
FPU_CONSISTENCY_CHECK_START();
1279
x = extended_to_double( src );
1281
double_to_extended( y, dest );
1283
FPU_CONSISTENCY_CHECK_STOP("do_flog10");
1286
static void do_flog2( float80 dest, float80 src ) REGPARAM;
1287
static void do_flog2( float80 dest, float80 src )
1289
FPU_CONSISTENCY_CHECK_START();
1291
x = extended_to_double( src );
1292
y = log (x) / log (2.0);
1293
double_to_extended( y, dest );
1295
FPU_CONSISTENCY_CHECK_STOP("do_flog2");
1298
static void do_facos( float80 dest, float80 src ) REGPARAM;
1299
static void do_facos( float80 dest, float80 src )
1301
FPU_CONSISTENCY_CHECK_START();
1303
x = extended_to_double( src );
1305
double_to_extended( y, dest );
1307
FPU_CONSISTENCY_CHECK_STOP("do_facos");
1310
static void do_fcosh( float80 dest, float80 src ) REGPARAM;
1311
static void do_fcosh( float80 dest, float80 src )
1313
FPU_CONSISTENCY_CHECK_START();
1315
x = extended_to_double( src );
1317
double_to_extended( y, dest );
1319
FPU_CONSISTENCY_CHECK_STOP("do_fcosh");
1322
static void do_fsin( float80 dest, float80 src ) REGPARAM;
1323
static void do_fsin( float80 dest, float80 src )
1325
FPU_CONSISTENCY_CHECK_START();
1333
FSTP TBYTE PTR [EDI]
1340
: "=m" (sw), "=m" (*dest)
1343
if(sw & SW_EXCEPTION_MASK) {
1346
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE);
1349
FPU_CONSISTENCY_CHECK_STOP("do_fsin");
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 )
1356
FPU_CONSISTENCY_CHECK_START();
1362
FSTP ST(0) ; pop 1.0 (the 8087/287 compatibility thing)
1365
FSTP TBYTE PTR [EDI]
1373
: "=m" (sw), "=m" (*dest)
1376
if(sw & SW_EXCEPTION_MASK) {
1379
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE - SW_UE);
1382
FPU_CONSISTENCY_CHECK_STOP("do_ftan");
1385
static void do_fabs( float80 dest, float80 src ) REGPARAM;
1386
static void do_fabs( float80 dest, float80 src )
1388
FPU_CONSISTENCY_CHECK_START();
1396
FSTP TBYTE PTR [EDI]
1403
: "=m" (sw), "=m" (*dest)
1406
// x86 fabs should not rise any exceptions (except stack underflow)
1407
if(sw & SW_EXCEPTION_MASK) {
1410
sw &= ~SW_EXCEPTION_MASK;
1412
FPU_CONSISTENCY_CHECK_STOP("do_fabs");
1415
static void do_fneg( float80 dest, float80 src ) REGPARAM;
1416
static void do_fneg( float80 dest, float80 src )
1418
FPU_CONSISTENCY_CHECK_START();
1426
FSTP TBYTE PTR [EDI]
1433
: "=m" (sw), "=m" (*dest)
1436
// x86 fchs should not rise any exceptions (except stack underflow)
1437
if(sw & SW_EXCEPTION_MASK) {
1440
sw &= ~SW_EXCEPTION_MASK;
1442
FPU_CONSISTENCY_CHECK_STOP("do_fneg");
1445
static void do_fcos( float80 dest, float80 src ) REGPARAM;
1446
static void do_fcos( float80 dest, float80 src )
1448
FPU_CONSISTENCY_CHECK_START();
1456
FSTP TBYTE PTR [EDI]
1463
: "=m" (sw), "=m" (*dest)
1466
if(sw & SW_EXCEPTION_MASK) {
1469
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE);
1472
FPU_CONSISTENCY_CHECK_STOP("do_fcos");
1475
static void do_fgetexp( float80 dest, float80 src ) REGPARAM;
1476
static void do_fgetexp( float80 dest, float80 src )
1478
FPU_CONSISTENCY_CHECK_START();
1484
FSTP ST(0) ; pop mantissa
1487
FSTP TBYTE PTR [EDI]
1495
: "=m" (sw), "=m" (*dest)
1498
if(sw & SW_EXCEPTION_MASK) {
1501
sw &= ~SW_EXCEPTION_MASK;
1503
FPU_CONSISTENCY_CHECK_STOP("do_fgetexp");
1506
static void do_fgetman( float80 dest, float80 src ) REGPARAM;
1507
static void do_fgetman( float80 dest, float80 src )
1509
FPU_CONSISTENCY_CHECK_START();
1517
FSTP TBYTE PTR [EDI]
1518
FSTP ST(0) ; pop exponent
1526
: "=m" (sw), "=m" (*dest)
1529
if(sw & SW_EXCEPTION_MASK) {
1532
sw &= ~SW_EXCEPTION_MASK;
1534
FPU_CONSISTENCY_CHECK_STOP("do_fgetman");
1537
static void do_fdiv( float80 dest, float80 src ) REGPARAM;
1538
static void do_fdiv( float80 dest, float80 src )
1540
FPU_CONSISTENCY_CHECK_START();
1549
FSTP TBYTE PTR [EDI]
1554
"fdiv %%st(1), %%st(0)\n"
1559
: "=m" (sw), "+m" (*dest)
1562
if(sw & SW_EXCEPTION_MASK) {
1567
FPU_CONSISTENCY_CHECK_STOP("do_fdiv");
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.
1575
static void do_fmod( float80 dest, float80 src ) REGPARAM;
1576
static void do_fmod( float80 dest, float80 src )
1578
FPU_CONSISTENCY_CHECK_START();
1580
volatile uint16 status;
1582
#if !USE_3_BIT_QUOTIENT
1586
uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
1592
#if !USE_3_BIT_QUOTIENT
1594
AND CX, ~X86_ROUND_CONTROL_MASK
1603
FISTP DWORD PTR quot
1607
// Should clear any possible exceptions here
1613
// loop until the remainder is not partial any more.
1624
FSTP TBYTE PTR [EDI]
1628
#if !USE_3_BIT_QUOTIENT
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)
1637
"fdiv %%st(1), %%st(0)\n"
1639
"fistpl %1\n" // %1: quot (read/write)
1644
"0:\n" // partial_loop
1646
"fnstsw %2\n" // %2: status (read/write)
1647
"testl $SW_C2, %2\n"
1650
"fnstsw %3\n" // %3: sw (write)
1653
: "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (sw), "+m" (*dest)
1654
: "m" (*src), "m" (cw)
1662
"0:\n" // partial_loop
1664
"fnstsw %0\n" // %0: status (read/write)
1665
"testl $SW_C2, %0\n"
1668
"fnstsw %1\n" // %1: sw (write)
1671
: "+m" (status), "=m" (sw), "+m" (*dest)
1677
if(sw & SW_EXCEPTION_MASK) {
1680
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
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;
1691
sw_quotient = (sign | (quot&0x7F)) << 16;
1694
FPU_CONSISTENCY_CHECK_STOP("do_fmod");
1697
static void do_frem( float80 dest, float80 src ) REGPARAM;
1698
static void do_frem( float80 dest, float80 src )
1700
FPU_CONSISTENCY_CHECK_START();
1702
volatile uint16 status;
1704
#if !USE_3_BIT_QUOTIENT
1708
uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
1714
#if !USE_3_BIT_QUOTIENT
1716
AND CX, ~X86_ROUND_CONTROL_MASK
1725
FISTP DWORD PTR quot
1729
// Should clear any possible exceptions here
1735
// loop until the remainder is not partial any more.
1744
FSTP TBYTE PTR [EDI]
1748
#if !USE_3_BIT_QUOTIENT
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)
1757
"fdiv %%st(1), %%st(0)\n"
1759
"fistpl %1\n" // %1: quot (read/write)
1764
"0:\n" // partial_loop
1766
"fnstsw %2\n" // %2: status (read/write)
1767
"testl $SW_C2, %2\n"
1770
"fnstsw %3\n" // %3: sw (write)
1773
: "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (sw), "+m" (*dest)
1774
: "m" (*src), "m" (cw)
1782
"0:\n" // partial_loop
1784
"fnstsw %0\n" // %0: status (read/write)
1785
"testl $SW_C2, %0\n"
1788
"fnstsw %1\n" // %1: sw (write)
1791
: "+m" (status), "=m" (sw), "+m" (*dest)
1797
if(sw & SW_EXCEPTION_MASK) {
1800
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
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;
1811
sw_quotient = (sign | (quot&0x7F)) << 16;
1814
FPU_CONSISTENCY_CHECK_STOP("do_frem");
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 )
1822
FPU_CONSISTENCY_CHECK_START();
1824
volatile uint16 status;
1827
uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
1837
FISTP DWORD PTR quot
1840
// Should clear any possible exceptions here
1845
// loop until the remainder is not partial any more.
1855
FSTP TBYTE PTR [EDI]
1858
if(sw & SW_EXCEPTION_MASK) {
1860
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
1863
sw_quotient = (sign | (quot&0x7F)) << 16;
1864
FPU_CONSISTENCY_CHECK_STOP("do_fmod_dont_set_cw");
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 )
1870
FPU_CONSISTENCY_CHECK_START();
1872
volatile uint16 status;
1875
uae_u32 sign = (dest[9] ^ src[9]) & 0x80;
1885
FISTP DWORD PTR quot
1888
// Should clear any possible exceptions here
1893
// loop until the remainder is not partial any more.
1902
FSTP TBYTE PTR [EDI]
1905
if(sw & SW_EXCEPTION_MASK) {
1907
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE);
1910
sw_quotient = (sign | (quot&0x7F)) << 16;
1911
FPU_CONSISTENCY_CHECK_STOP("do_frem_dont_set_cw");
1913
#endif //USE_3_BIT_QUOTIENT
1915
static void do_fadd( float80 dest, float80 src ) REGPARAM;
1916
static void do_fadd( float80 dest, float80 src )
1918
FPU_CONSISTENCY_CHECK_START();
1927
FSTP TBYTE PTR [EDI]
1935
: "=m" (sw), "+m" (*dest)
1938
if(sw & SW_EXCEPTION_MASK) {
1941
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE);
1944
FPU_CONSISTENCY_CHECK_STOP("do_fadd");
1947
static void do_fmul( float80 dest, float80 src ) REGPARAM;
1948
static void do_fmul( float80 dest, float80 src )
1950
FPU_CONSISTENCY_CHECK_START();
1959
FSTP TBYTE PTR [EDI]
1967
: "=m" (sw), "+m" (*dest)
1970
if(sw & SW_EXCEPTION_MASK) {
1975
FPU_CONSISTENCY_CHECK_STOP("do_fmul");
1978
static void do_fsgldiv( float80 dest, float80 src ) REGPARAM;
1979
static void do_fsgldiv( float80 dest, float80 src )
1981
FPU_CONSISTENCY_CHECK_START();
1985
and cw_temp, ~X86_PRECISION_CONTROL_MASK
1986
or cw_temp, PRECISION_CONTROL_SINGLE
1996
FSTP TBYTE PTR [EDI]
2001
"andl $(~X86_PRECISION_CONTROL_MASK), %0\n"
2002
"orl $PRECISION_CONTROL_SINGLE, %0\n"
2006
"fdiv %%st(1), %%st(0)\n"
2012
: "+m" (cw_temp), "=m" (sw), "+m" (*dest)
2013
: "m" (*src), "m" (cw)
2015
if(sw & SW_EXCEPTION_MASK) {
2020
FPU_CONSISTENCY_CHECK_STOP("do_fsgldiv");
2023
static void do_fscale( float80 dest, float80 src ) REGPARAM;
2024
static void do_fscale( float80 dest, float80 src )
2026
FPU_CONSISTENCY_CHECK_START();
2035
FSTP TBYTE PTR [EDI]
2045
: "=m" (sw), "+m" (*dest)
2048
if(sw & SW_EXCEPTION_MASK) {
2051
sw &= ~(SW_EXCEPTION_MASK - SW_UE - SW_OE);
2054
FPU_CONSISTENCY_CHECK_STOP("do_fscale");
2057
static void do_fsglmul( float80 dest, float80 src ) REGPARAM;
2058
static void do_fsglmul( float80 dest, float80 src )
2060
FPU_CONSISTENCY_CHECK_START();
2065
and cw_temp, ~X86_PRECISION_CONTROL_MASK
2066
or cw_temp, PRECISION_CONTROL_SINGLE
2076
FSTP TBYTE PTR [EDI]
2081
"andl $(~X86_PRECISION_CONTROL_MASK), %0\n"
2082
"orl $PRECISION_CONTROL_SINGLE, %0\n"
2091
: "+m" (cw_temp), "=m" (sw), "+m" (*dest)
2092
: "m" (*src), "m" (sw)
2094
if(sw & SW_EXCEPTION_MASK) {
2099
FPU_CONSISTENCY_CHECK_STOP("do_fsglmul");
2102
static void do_fsub( float80 dest, float80 src ) REGPARAM;
2103
static void do_fsub( float80 dest, float80 src )
2105
FPU_CONSISTENCY_CHECK_START();
2114
FSTP TBYTE PTR [EDI]
2119
"fsub %%st(1), %%st(0)\n"
2124
: "=m" (sw), "+m" (*dest)
2127
if(sw & SW_EXCEPTION_MASK) {
2130
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE);
2133
FPU_CONSISTENCY_CHECK_STOP("do_fsub");
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 )
2139
FPU_CONSISTENCY_CHECK_START();
2145
FSTP TBYTE PTR [EDI]
2149
FSTP TBYTE PTR [EDI]
2159
: "=m" (sw), "=m" (*dest_cos), "=m" (*dest_sin)
2162
if(sw & SW_EXCEPTION_MASK) {
2165
sw &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_PE);
2168
FPU_CONSISTENCY_CHECK_STOP("do_fsincos");
2171
static void do_fcmp( float80 dest, float80 src ) REGPARAM;
2172
static void do_fcmp( float80 dest, float80 src )
2174
FPU_CONSISTENCY_CHECK_START();
2188
"fsub %%st(1), %%st(0)\n"
2194
: "m" (*dest), "m" (*src)
2196
if(sw & SW_EXCEPTION_MASK) {
2199
sw &= ~SW_EXCEPTION_MASK;
2201
FPU_CONSISTENCY_CHECK_STOP("do_fcmp");
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)
2208
FPU_CONSISTENCY_CHECK_START();
2215
if (wrd1 & 0x80000000)
2217
*cp++ = (char)((wrd1 & 0xf) + '0');
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');
2236
if (wrd1 & 0x40000000)
2238
*cp++ = (char)(((wrd1 >> 24) & 0xf) + '0');
2239
*cp++ = (char)(((wrd1 >> 20) & 0xf) + '0');
2240
*cp++ = (char)(((wrd1 >> 16) & 0xf) + '0');
2242
sscanf(str, "%le", &d);
2244
D(bug("to_pack str = %s\r\n",str));
2246
D(bug("to_pack(%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)d));
2248
FPU_CONSISTENCY_CHECK_STOP("to_pack");
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)
2257
FPU_CONSISTENCY_CHECK_START();
2263
int exponent_digit_count = 0;
2265
sprintf(str, "%.16e", src);
2267
D(bug("from_pack(%.04f,%s)\r\n",(float)src,str));
2270
*wrd1 = *wrd2 = *wrd3 = 0;
2277
*wrd1 |= (*cp++ - '0');
2280
for (i = 0; i < 8; i++) {
2282
if (*cp >= '0' && *cp <= '9')
2283
*wrd2 |= *cp++ - '0';
2285
for (i = 0; i < 8; i++) {
2287
if (*cp >= '0' && *cp <= '9')
2288
*wrd3 |= *cp++ - '0';
2290
if (*cp == 'e' || *cp == 'E') {
2294
*wrd1 |= 0x40000000;
2299
for (i = 0; i < 3; i++) {
2300
if (*cp >= '0' && *cp <= '9') {
2301
t = (t << 4) | (*cp++ - '0');
2302
exponent_digit_count++;
2308
D(bug("from_pack(%.04f) = %X,%X,%X\r\n",(float)src,*wrd1,*wrd2,*wrd3));
2311
// _asm FNSTSW sw_temp
2312
_ASM("fnstsw %0" : "=m" (sw_temp));
2313
if(sw_temp & SW_EXCEPTION_MASK) {
2316
if(sw_temp & SW_PE) {
2318
sw_accrued |= SW_PE;
2323
OPERR is set if the k-factor > + 17 or the magnitude of
2324
the decimal exponent exceeds three digits;
2327
if(exponent_digit_count > 3) {
2329
sw_accrued |= SW_IE;
2332
FPU_CONSISTENCY_CHECK_STOP("from_pack");
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};
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)
2341
// D(bug("get_fp_value(%X,%X)\r\n",(int)opcode,(int)extra));
2342
// dump_first_bytes( regs.pc_p-4, 16 );
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] );
2350
int mode = (opcode >> 3) & 7;
2351
int reg = opcode & 7;
2352
int size = (extra >> 10) & 7;
2355
// D(bug("get_fp_value mode=%d, reg=%d, size=%d\r\n",(int)mode,(int)reg,(int)size));
2357
switch ((uae_u8)mode) {
2359
switch ((uae_u8)size) {
2361
signed_to_extended( (uae_s32)(uae_s8) m68k_dreg (regs, reg), src );
2364
signed_to_extended( (uae_s32)(uae_s16) m68k_dreg (regs, reg), src );
2367
signed_to_extended( (uae_s32) m68k_dreg (regs, reg), src );
2370
to_single( m68k_dreg (regs, reg), src );
2379
ad = m68k_areg (regs, reg);
2382
ad = m68k_areg (regs, reg);
2383
m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
2386
m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
2387
ad = m68k_areg (regs, reg);
2390
ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
2393
ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
2396
switch ((uae_u8)reg) {
2398
ad = (uae_s32) (uae_s16) next_iword();
2405
ad += (uae_s32) (uae_s16) next_iword();
2408
uaecptr tmppc = m68k_getpc ();
2409
uae_u16 tmp = (uae_u16)next_iword();
2410
ad = get_disp_ea_020 (tmppc, tmp);
2415
m68k_setpc (ad + sz2[size]);
2418
+0000 000004 FSCALE.B #$01,FP2 | F23C 5926 0001
2419
F23C 1111001000111100
2420
5926 0101100100100110
2421
0001 0000000000000001
2426
// Immediate addressing mode && Operation Length == Byte ->
2427
// Use the low-order byte of the extension word.
2431
// May be faster on a PII(I), sz2[size] is already in register
2432
// ad += sz2[size] - sz1[size];
2440
switch ((uae_u8)size) {
2442
signed_to_extended( (uae_s32) get_long (ad), src );
2445
to_single( get_long (ad), src );
2449
uae_u32 wrd1, wrd2, wrd3;
2450
wrd1 = get_long (ad);
2452
wrd2 = get_long (ad);
2454
wrd3 = get_long (ad);
2455
to_exten( wrd1, wrd2, wrd3, src );
2459
uae_u32 wrd1, wrd2, wrd3;
2460
wrd1 = get_long (ad);
2462
wrd2 = get_long (ad);
2464
wrd3 = get_long (ad);
2465
double_to_extended( to_pack(wrd1, wrd2, wrd3), src );
2469
signed_to_extended( (uae_s32)(uae_s16) get_word(ad), src );
2473
wrd1 = get_long (ad);
2475
wrd2 = get_long (ad);
2476
to_double(wrd1, wrd2, src);
2480
signed_to_extended( (uae_s32)(uae_s8) get_byte(ad), src );
2486
// D(bug("get_fp_value result = %.04f\r\n",(float)*src));
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)
2494
// D(bug("put_fp_value(%.04f,%X,%X)\r\n",(float)value,(int)opcode,(int)extra));
2496
if ((extra & 0x4000) == 0) {
2497
int dest_reg = (extra >> 10) & 7;
2498
do_fmove( fp_reg[dest_reg], value );
2503
int mode = (opcode >> 3) & 7;
2504
int reg = opcode & 7;
2505
int size = (extra >> 10) & 7;
2506
uae_u32 ad = 0xffffffff;
2508
// Clear exception status
2509
sw &= ~SW_EXCEPTION_MASK;
2511
switch ((uae_u8)mode) {
2513
switch ((uae_u8)size) {
2515
*((uae_u8 *)&m68k_dreg(regs, reg)) = extended_to_signed_8(value);
2519
*((uae_u16 *)&m68k_dreg(regs, reg)) = extended_to_signed_16(value);
2522
m68k_dreg (regs, reg) = extended_to_signed_32(value);
2525
m68k_dreg (regs, reg) = from_single(value);
2534
ad = m68k_areg (regs, reg);
2537
ad = m68k_areg (regs, reg);
2538
m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
2541
m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
2542
ad = m68k_areg (regs, reg);
2545
ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
2548
ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
2551
switch ((uae_u8)reg) {
2553
ad = (uae_s32) (uae_s16) next_iword();
2560
ad += (uae_s32) (uae_s16) next_iword();
2563
uaecptr tmppc = m68k_getpc ();
2564
uae_u16 tmp = (uae_u16)next_iword();
2565
ad = get_disp_ea_020 (tmppc, tmp);
2570
m68k_setpc (ad + sz2[size]);
2576
switch ((uae_u8)size) {
2578
put_long (ad, (uae_s32) extended_to_signed_32(value));
2581
put_long (ad, from_single(value));
2584
uae_u32 wrd1, wrd2, wrd3;
2585
from_exten(value, &wrd1, &wrd2, &wrd3);
2587
sw &= ~SW_EXCEPTION_MASK;
2588
if(wrd3) { // TODO: not correct! Just a "smart" guess.
2590
sw_accrued |= SW_PE;
2593
put_long (ad, wrd1);
2595
put_long (ad, wrd2);
2597
put_long (ad, wrd3);
2601
uae_u32 wrd1, wrd2, wrd3;
2602
from_pack(extended_to_double(value), &wrd1, &wrd2, &wrd3);
2603
put_long (ad, wrd1);
2605
put_long (ad, wrd2);
2607
put_long (ad, wrd3);
2611
put_word(ad, extended_to_signed_16(value));
2615
from_double(value, &wrd1, &wrd2);
2616
put_long (ad, wrd1);
2618
put_long (ad, wrd2);
2622
put_byte(ad, extended_to_signed_8(value));
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)
2634
int mode = (opcode >> 3) & 7;
2635
int reg = opcode & 7;
2636
switch ( (uae_u8)mode ) {
2639
if( (opcode & 0xFF00) == 0xF300 ) {
2641
m68k_setpc (m68k_getpc () - 2);
2643
m68k_setpc (m68k_getpc () - 4);
2646
dump_fp_regs( "END ");
2649
*ad = m68k_areg (regs, reg);
2652
*ad = m68k_areg (regs, reg);
2655
*ad = m68k_areg (regs, reg);
2658
*ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword();
2661
*ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword());
2664
switch ( (uae_u8)reg ) {
2666
*ad = (uae_s32) (uae_s16) next_iword();
2672
*ad = m68k_getpc ();
2673
*ad += (uae_s32) (uae_s16) next_iword();
2676
uaecptr tmppc = m68k_getpc ();
2677
uae_u16 tmp = (uae_u16)next_iword();
2678
*ad = get_disp_ea_020 (tmppc, tmp);
2682
if( (opcode & 0xFF00) == 0xF300 ) {
2684
m68k_setpc (m68k_getpc () - 2);
2686
m68k_setpc (m68k_getpc () - 4);
2689
dump_fp_regs( "END ");
2696
static int fpp_cond(uae_u32 opcode, int condition) REGPARAM;
2697
static int fpp_cond(uae_u32 opcode, int condition)
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)
2705
switch (condition) {
2706
// Common Tests, no BSUN
2710
CONDRET("Not Equal",!Z);
2712
// IEEE Nonaware Tests, BSUN
2715
CONDRET("Greater Than",!(NotANumber || Z || N));
2718
CONDRET("Not Greater Than",NotANumber || Z || N);
2721
CONDRET("Greater Than or Equal",Z || !(NotANumber || N));
2724
CONDRET("Not Greater Than or Equal",!Z && (NotANumber || N));
2727
CONDRET("Less Than",N && !(NotANumber || Z));
2730
CONDRET("Not Less Than",NotANumber || Z || !N);
2733
CONDRET("Less Than or Equal",Z || (N && !NotANumber));
2736
CONDRET("Not Less Than or Equal",NotANumber || !(N || Z));
2739
CONDRET("Greater or Less Than",!(NotANumber || Z));
2742
CONDRET("Not Greater or Less Than",NotANumber || Z);
2744
CONDRET("Greater, Less or Equal",!NotANumber);
2747
CONDRET("Not Greater, Less or Equal",NotANumber);
2749
// IEEE Aware Tests, no BSUN
2751
CONDRET("Ordered Greater Than",!(NotANumber || Z || N));
2753
CONDRET("Unordered or Less or Equal",NotANumber || Z || N);
2755
CONDRET("Ordered Greater Than or Equal",Z || !(NotANumber || N));
2757
CONDRET("Unordered or Less Than",NotANumber || (N && !Z));
2759
CONDRET("Ordered Less Than",N && !(NotANumber || Z));
2761
CONDRET("Unordered or Greater or Equal",NotANumber || Z || !N);
2763
CONDRET("Ordered Less Than or Equal",Z || (N && !NotANumber));
2765
CONDRET("Unordered or Greater Than",NotANumber || !(N || Z));
2767
CONDRET("Ordered Greater or Less Than",!(NotANumber || Z));
2769
CONDRET("Unordered or Equal",NotANumber || Z);
2771
CONDRET("Ordered",!NotANumber);
2773
CONDRET("Unordered",NotANumber);
2775
// Miscellaneous Tests, no BSUN
2781
// Miscellaneous Tests, BSUN
2784
CONDRET("Signaling False",0);
2787
CONDRET("Signaling True",1);
2790
CONDRET("Signaling Equal",Z);
2793
CONDRET("Signaling Not Equal",!Z);
2804
void REGPARAM2 fdbcc_opp(uae_u32 opcode, uae_u16 extra)
2806
uaecptr pc = (uae_u32) m68k_getpc ();
2807
uae_s32 disp = (uae_s32) (uae_s16) next_iword();
2810
D(bug("fdbcc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ()));
2812
cc = fpp_cond(opcode, extra & 0x3f);
2814
m68k_setpc (pc - 4);
2817
int reg = opcode & 0x7;
2820
uae_u16 newv = (uae_u16)(m68k_dreg (regs, reg) & 0xffff) - 1;
2821
*((uae_u16 *)&m68k_dreg(regs, reg)) = newv;
2824
m68k_setpc (pc + disp);
2828
void REGPARAM2 fscc_opp(uae_u32 opcode, uae_u16 extra)
2833
D(bug("fscc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ()));
2835
cc = fpp_cond(opcode, extra & 0x3f);
2837
m68k_setpc (m68k_getpc () - 4);
2839
} else if ((opcode & 0x38) == 0) {
2841
m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) |
2844
if (get_fp_ad(opcode, &ad)) {
2845
put_byte(ad, cc ? 0xff : 0x00);
2850
void REGPARAM2 ftrapcc_opp(uae_u32 opcode, uaecptr oldpc)
2854
D(bug("ftrapcc_opp %X at %08lx\r\n", (uae_u32)opcode, m68k_getpc ()));
2857
#error "FIXME: _asm int 3"
2861
// This must be broken.
2862
cc = fpp_cond(opcode, opcode & 0x3f);
2868
Exception(7, oldpc - 2);
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)
2876
D(bug("fbcc_opp %X, %X at %08lx, jumpto=%X\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc (), extra ));
2878
cc = fpp_cond(opcode, opcode & 0x3f);
2883
if ((opcode & 0x40) == 0)
2884
extra = (uae_s32) (uae_s16) extra;
2885
m68k_setpc (pc + extra);
2889
// FSAVE has no post-increment
2890
// 0x1f180000 == IDLE state frame, coprocessor version number 1F
2891
void REGPARAM2 fsave_opp(uae_u32 opcode)
2894
int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
2897
D(bug("fsave_opp at %08lx\r\n", m68k_getpc ()));
2899
if (get_fp_ad(opcode, &ad)) {
2900
if (is_integral_68040_fpu) {
2901
// Put 4 byte 68040 IDLE frame.
2904
put_long (ad, 0x41000000);
2906
put_long (ad, 0x41000000);
2910
// Put 28 byte 68881 IDLE frame.
2912
D(bug("fsave_opp pre-decrement\r\n"));
2914
// What's this? Some BIU flags, or (incorrectly placed) command/condition?
2915
put_long (ad, 0x70000000);
2916
for (i = 0; i < 5; i++) {
2918
put_long (ad, 0x00000000);
2921
put_long (ad, 0x1f180000); // IDLE, vers 1f
2923
put_long (ad, 0x1f180000); // IDLE, vers 1f
2925
for (i = 0; i < 5; i++) {
2926
put_long (ad, 0x00000000);
2929
// What's this? Some BIU flags, or (incorrectly placed) command/condition?
2930
put_long (ad, 0x70000000);
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"));
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));
2945
static void do_null_frestore()
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] );
2963
_ASM("fldcw %0\n\tfnclex" : : "m" (cw));
2966
// FSAVE has no pre-decrement
2967
void REGPARAM2 frestore_opp(uae_u32 opcode)
2971
int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
2973
D(bug("frestore_opp at %08lx\r\n", m68k_getpc ()));
2975
if (get_fp_ad(opcode, &ad)) {
2976
if (is_integral_68040_fpu) {
2979
D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
2980
// this may be wrong, but it's never called.
2983
if ((d & 0xff000000) == 0) { // NULL
2984
D(bug("frestore_opp found NULL frame at %X\r\n",ad-4));
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));
2991
} else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
2992
D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
2995
D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d));
2999
D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
3001
if ((d & 0xff000000) == 0) { // NULL
3002
D(bug("frestore_opp found NULL frame at %X\r\n",ad-4));
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));
3009
} else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
3010
D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
3013
D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d));
3019
D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
3020
// this may be wrong, but it's never called.
3023
if ((d & 0xff000000) == 0) { // NULL
3025
} else if ((d & 0x00ff0000) == 0x00180000) {
3027
} else if ((d & 0x00ff0000) == 0x00380000) {
3029
} else if ((d & 0x00ff0000) == 0x00b40000) {
3034
D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
3036
if ((d & 0xff000000) == 0) { // NULL
3037
D(bug("frestore_opp found NULL frame at %X\r\n",ad-4));
3039
} else if ((d & 0x00ff0000) == 0x00180000) { // IDLE
3040
D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
3042
} else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
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));
3049
D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d));
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));
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"));
3066
/* ---------------------------- Old-style interface ---------------------------- */
3068
// #ifndef OPTIMIZED_8BIT_MEMORY_ACCESS
3069
void REGPARAM2 fpp_opp(uae_u32 opcode, uae_u16 extra)
3071
uae_u32 mask = (extra & 0xFC7F) | ((opcode & 0x0038) << 4);
3072
(*fpufunctbl[mask])(opcode,extra);
3077
/* ---------------------------- Illegal ---------------------------- */
3079
void REGPARAM2 fpuop_illg( uae_u32 opcode, uae_u16 extra )
3081
D(bug("ILLEGAL F OP 2 %X\r\n",opcode));
3083
#if I3_ON_ILLEGAL_FPU_OP
3084
#error "FIXME: asm int 3"
3088
m68k_setpc (m68k_getpc () - 4);
3090
dump_fp_regs( "END ");
3094
/* ---------------------------- FPP -> <ea> ---------------------------- */
3096
void REGPARAM2 fpuop_fmove_2_ea( uae_u32 opcode, uae_u16 extra )
3098
D(bug("FMOVE -> <ea>\r\n"));
3100
if (put_fp_value (fp_reg[(extra >> 7) & 7], opcode, extra) == 0) {
3101
m68k_setpc (m68k_getpc () - 4);
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.
3115
if(sw_temp & SW_PE) {
3118
sw_accrued |= SW_PE;
3122
dump_fp_regs( "END ");
3126
/* ---------------------------- CONTROL REGS -> Dreg ---------------------------- */
3128
void REGPARAM2 fpuop_fmovem_none_2_Dreg( uae_u32 opcode, uae_u16 extra )
3130
D(bug("FMOVEM control(none) -> D%d\r\n", opcode & 7));
3131
dump_fp_regs( "END ");
3134
void REGPARAM2 fpuop_fmovem_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
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 ");
3141
void REGPARAM2 fpuop_fmovem_fpsr_2_Dreg( uae_u32 opcode, uae_u16 extra )
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 ");
3149
void REGPARAM2 fpuop_fmovem_fpcr_2_Dreg( uae_u32 opcode, uae_u16 extra )
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 ");
3156
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
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 ");
3166
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
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 ");
3175
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Dreg( uae_u32 opcode, uae_u16 extra )
3177
D(bug("FMOVEM regs.fpcr (%X) -> D%d\r\n", regs.fpcr, opcode & 7));
3178
m68k_dreg (regs, opcode & 7) = regs.fpcr;
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 ");
3185
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u16 extra )
3187
D(bug("FMOVEM regs.fpcr (%X) -> D%d\r\n", regs.fpcr, opcode & 7));
3188
m68k_dreg (regs, opcode & 7) = regs.fpcr;
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 ");
3198
/* ---------------------------- Dreg -> CONTROL REGS ---------------------------- */
3200
void REGPARAM2 fpuop_fmovem_Dreg_2_none( uae_u32 opcode, uae_u16 extra )
3202
D(bug("FMOVEM D%d -> control(none)\r\n", opcode & 7));
3203
dump_fp_regs( "END ");
3206
void REGPARAM2 fpuop_fmovem_Dreg_2_fpiar( uae_u32 opcode, uae_u16 extra )
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 ");
3213
void REGPARAM2 fpuop_fmovem_Dreg_2_fpsr( uae_u32 opcode, uae_u16 extra )
3215
regs.fpsr = m68k_dreg (regs, opcode & 7);
3217
D(bug("FMOVEM D%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
3218
dump_fp_regs( "END ");
3221
void REGPARAM2 fpuop_fmovem_Dreg_2_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
3223
regs.fpsr = m68k_dreg (regs, opcode & 7);
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 ");
3231
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr( uae_u32 opcode, uae_u16 extra )
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 ");
3239
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr_fpiar( uae_u32 opcode, uae_u16 extra )
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 ");
3249
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr_fpsr( uae_u32 opcode, uae_u16 extra )
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);
3256
D(bug("FMOVEM D%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
3257
dump_fp_regs( "END ");
3260
void REGPARAM2 fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
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);
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 ");
3274
/* ---------------------------- CONTROL REGS -> Areg ---------------------------- */
3276
void REGPARAM2 fpuop_fmovem_none_2_Areg( uae_u32 opcode, uae_u16 extra )
3278
D(bug("FMOVEM control(none) -> A%d\r\n", opcode & 7));
3279
dump_fp_regs( "END ");
3282
void REGPARAM2 fpuop_fmovem_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
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 ");
3289
void REGPARAM2 fpuop_fmovem_fpsr_2_Areg( uae_u32 opcode, uae_u16 extra )
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 ");
3297
void REGPARAM2 fpuop_fmovem_fpcr_2_Areg( uae_u32 opcode, uae_u16 extra )
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 ");
3304
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
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 ");
3314
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
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 ");
3323
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Areg( uae_u32 opcode, uae_u16 extra )
3325
D(bug("FMOVEM regs.fpcr (%X) -> A%d\r\n", regs.fpcr, opcode & 7));
3326
m68k_areg (regs, opcode & 7) = regs.fpcr;
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 ");
3333
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u16 extra )
3335
D(bug("FMOVEM regs.fpcr (%X) -> A%d\r\n", regs.fpcr, opcode & 7));
3336
m68k_areg (regs, opcode & 7) = regs.fpcr;
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 ");
3346
/* ---------------------------- Areg -> CONTROL REGS ---------------------------- */
3348
void REGPARAM2 fpuop_fmovem_Areg_2_none( uae_u32 opcode, uae_u16 extra )
3350
D(bug("FMOVEM A%d -> control(none)\r\n", opcode & 7));
3351
dump_fp_regs( "END ");
3354
void REGPARAM2 fpuop_fmovem_Areg_2_fpiar( uae_u32 opcode, uae_u16 extra )
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 ");
3361
void REGPARAM2 fpuop_fmovem_Areg_2_fpsr( uae_u32 opcode, uae_u16 extra )
3363
regs.fpsr = m68k_areg (regs, opcode & 7);
3365
D(bug("FMOVEM A%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
3366
dump_fp_regs( "END ");
3369
void REGPARAM2 fpuop_fmovem_Areg_2_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
3371
regs.fpsr = m68k_areg (regs, opcode & 7);
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 ");
3379
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr( uae_u32 opcode, uae_u16 extra )
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 ");
3387
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr_fpiar( uae_u32 opcode, uae_u16 extra )
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 ");
3397
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr_fpsr( uae_u32 opcode, uae_u16 extra )
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);
3404
D(bug("FMOVEM A%d (%X) -> regs.fpsr\r\n", opcode & 7, regs.fpsr));
3405
dump_fp_regs( "END ");
3408
void REGPARAM2 fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u16 extra )
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);
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 ");
3422
/* ---------------------------- CONTROL REGS -> --MEMORY---------------------------- */
3424
void REGPARAM2 fpuop_fmovem_none_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3426
D(bug("FMOVEM Control regs (none) -> mem\r\n" ));
3427
dump_fp_regs( "END ");
3430
void REGPARAM2 fpuop_fmovem_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3433
if (get_fp_ad(opcode, &ad)) {
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 ");
3442
void REGPARAM2 fpuop_fmovem_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3445
if (get_fp_ad(opcode, &ad)) {
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 ");
3455
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3458
if (get_fp_ad(opcode, &ad)) {
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 ");
3470
void REGPARAM2 fpuop_fmovem_fpcr_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3473
if (get_fp_ad(opcode, &ad)) {
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 ");
3482
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3485
if (get_fp_ad(opcode, &ad)) {
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 ");
3496
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3499
if (get_fp_ad(opcode, &ad)) {
3501
put_long (ad, regs.fpcr);
3502
D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
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 ");
3511
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u16 extra )
3514
if (get_fp_ad(opcode, &ad)) {
3516
put_long (ad, regs.fpcr);
3517
D(bug("FMOVEM regs.fpcr (%X) -> mem %X\r\n", regs.fpcr, ad ));
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 ");
3529
/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */
3531
void REGPARAM2 fpuop_fmovem_none_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
3533
D(bug("FMOVEM Control regs (none) -> mem\r\n" ));
3534
dump_fp_regs( "END ");
3537
void REGPARAM2 fpuop_fmovem_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
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 ");
3548
void REGPARAM2 fpuop_fmovem_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
3551
if (get_fp_ad(opcode, &ad)) {
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 ");
3560
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
3563
if (get_fp_ad(opcode, &ad)) {
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 ");
3574
void REGPARAM2 fpuop_fmovem_fpcr_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
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 ");
3585
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
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 ");
3598
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
3600
dump_fp_regs( "END ");
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 ));
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;
3612
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u16 extra )
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 ));
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 ");
3629
/* ---------------------------- CONTROL REGS -> MEMORY ---------------------------- */
3631
void REGPARAM2 fpuop_fmovem_none_2_Mem( uae_u32 opcode, uae_u16 extra )
3633
D(bug("FMOVEM Control regs (none) -> mem\r\n" ));
3634
dump_fp_regs( "END ");
3637
void REGPARAM2 fpuop_fmovem_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
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 ");
3647
void REGPARAM2 fpuop_fmovem_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
3650
if (get_fp_ad(opcode, &ad)) {
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 ");
3658
void REGPARAM2 fpuop_fmovem_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
3661
if (get_fp_ad(opcode, &ad)) {
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 ");
3671
void REGPARAM2 fpuop_fmovem_fpcr_2_Mem( uae_u32 opcode, uae_u16 extra )
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 ");
3681
void REGPARAM2 fpuop_fmovem_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
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 ");
3693
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
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 ));
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 ");
3706
void REGPARAM2 fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
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 ));
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 ");
3722
/* ---------------------------- --MEMORY -> CONTROL REGS ---------------------------- */
3724
void REGPARAM2 fpuop_fmovem_Mem_2_none_predecrement( uae_u32 opcode, uae_u16 extra )
3726
D(bug("FMOVEM --Mem -> control(none)\r\n"));
3727
dump_fp_regs( "END ");
3730
void REGPARAM2 fpuop_fmovem_Mem_2_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
3733
if (get_fp_ad(opcode, &ad)) {
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 ");
3742
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_predecrement( uae_u32 opcode, uae_u16 extra )
3745
if (get_fp_ad(opcode, &ad)) {
3747
regs.fpsr = get_long (ad);
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 ");
3755
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
3758
if (get_fp_ad(opcode, &ad)) {
3760
regs.fpsr = get_long (ad);
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 ");
3770
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_predecrement( uae_u32 opcode, uae_u16 extra )
3773
if (get_fp_ad(opcode, &ad)) {
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 ");
3783
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
3786
if (get_fp_ad(opcode, &ad)) {
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 ");
3798
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement( uae_u32 opcode, uae_u16 extra )
3801
if (get_fp_ad(opcode, &ad)) {
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);
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 ");
3814
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u16 extra )
3817
if (get_fp_ad(opcode, &ad)) {
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);
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 ");
3833
/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */
3835
void REGPARAM2 fpuop_fmovem_Mem_2_none_postincrement( uae_u32 opcode, uae_u16 extra )
3837
D(bug("FMOVEM Mem++ -> control(none)\r\n"));
3838
dump_fp_regs( "END ");
3841
void REGPARAM2 fpuop_fmovem_Mem_2_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
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 ");
3852
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_postincrement( uae_u32 opcode, uae_u16 extra )
3855
if (get_fp_ad(opcode, &ad)) {
3856
regs.fpsr = get_long (ad);
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 ");
3864
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
3867
if (get_fp_ad(opcode, &ad)) {
3868
regs.fpsr = get_long (ad);
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 ");
3878
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_postincrement( uae_u32 opcode, uae_u16 extra )
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 ");
3890
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
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 ");
3904
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement( uae_u32 opcode, uae_u16 extra )
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);
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 ");
3919
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u16 extra )
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);
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 ");
3937
/* ---------------------------- MEMORY -> CONTROL REGS ---------------------------- */
3938
/* ---------------------------- and ---------------------------- */
3939
/* ---------------------------- IMMEDIATE -> CONTROL REGS ---------------------------- */
3941
void REGPARAM2 fpuop_fmovem_Mem_2_none_2_Mem( uae_u32 opcode, uae_u16 extra )
3943
D(bug("FMOVEM Mem -> control(none)\r\n"));
3944
dump_fp_regs( "END ");
3947
void REGPARAM2 fpuop_fmovem_Mem_2_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
3949
if ((opcode & 0x3f) == 0x3c) {
3950
regs.fpiar = next_ilong();
3951
D(bug("FMOVEM #<%X> -> regs.fpiar\r\n", regs.fpiar));
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 ));
3959
dump_fp_regs( "END ");
3962
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
3964
if ((opcode & 0x3f) == 0x3c) {
3965
regs.fpsr = next_ilong();
3967
D(bug("FMOVEM #<%X> -> regs.fpsr\r\n", regs.fpsr));
3970
if (get_fp_ad(opcode, &ad)) {
3971
regs.fpsr = get_long (ad);
3973
D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad, regs.fpsr ));
3976
dump_fp_regs( "END ");
3979
void REGPARAM2 fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
3981
if ((opcode & 0x3f) == 0x3c) {
3982
regs.fpsr = next_ilong();
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));
3989
if (get_fp_ad(opcode, &ad)) {
3990
regs.fpsr = get_long (ad);
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 ));
3997
dump_fp_regs( "END ");
4000
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_2_Mem( uae_u32 opcode, uae_u16 extra )
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));
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 ));
4014
dump_fp_regs( "END ");
4017
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
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));
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 ));
4035
dump_fp_regs( "END ");
4038
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u16 extra )
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();
4046
D(bug("FMOVEM #<%X> -> regs.fpsr\r\n", regs.fpsr));
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);
4055
D(bug("FMOVEM mem %X (%X) -> regs.fpsr\r\n", ad+4, regs.fpsr ));
4058
dump_fp_regs( "END ");
4061
void REGPARAM2 fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u16 extra )
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();
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));
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);
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 ));
4085
dump_fp_regs( "END ");
4089
/* ---------------------------- FMOVEM MEMORY -> FPP ---------------------------- */
4091
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_pred_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4100
wrd3 = get_long (ad);
4102
wrd2 = get_long (ad);
4104
wrd1 = get_long (ad);
4105
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4109
m68k_areg (regs, opcode & 7) = ad;
4110
dump_fp_regs( "END ");
4114
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_pred_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4123
wrd3 = get_long (ad);
4125
wrd2 = get_long (ad);
4127
wrd1 = get_long (ad);
4128
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4132
m68k_areg (regs, opcode & 7) = ad;
4133
dump_fp_regs( "END ");
4137
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_pred( uae_u32 opcode, uae_u16 extra )
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;
4146
wrd3 = get_long (ad);
4148
wrd2 = get_long (ad);
4150
wrd1 = get_long (ad);
4151
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4155
dump_fp_regs( "END ");
4159
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4168
wrd3 = get_long (ad);
4170
wrd2 = get_long (ad);
4172
wrd1 = get_long (ad);
4173
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4177
m68k_areg (regs, opcode & 7) = ad;
4178
dump_fp_regs( "END ");
4182
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4191
wrd3 = get_long (ad);
4193
wrd2 = get_long (ad);
4195
wrd1 = get_long (ad);
4196
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4200
m68k_areg (regs, opcode & 7) = ad;
4201
dump_fp_regs( "END ");
4205
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_pred( uae_u32 opcode, uae_u16 extra )
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;
4214
wrd3 = get_long (ad);
4216
wrd2 = get_long (ad);
4218
wrd1 = get_long (ad);
4219
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4223
dump_fp_regs( "END ");
4227
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4235
wrd1 = get_long (ad);
4237
wrd2 = get_long (ad);
4239
wrd3 = get_long (ad);
4241
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4245
m68k_areg (regs, opcode & 7) = ad;
4246
dump_fp_regs( "END ");
4250
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4258
wrd1 = get_long (ad);
4260
wrd2 = get_long (ad);
4262
wrd3 = get_long (ad);
4264
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4268
m68k_areg (regs, opcode & 7) = ad;
4269
dump_fp_regs( "END ");
4273
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_static_postinc( uae_u32 opcode, uae_u16 extra )
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;
4281
wrd1 = get_long (ad);
4283
wrd2 = get_long (ad);
4285
wrd3 = get_long (ad);
4287
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4291
dump_fp_regs( "END ");
4295
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4303
wrd1 = get_long (ad);
4305
wrd2 = get_long (ad);
4307
wrd3 = get_long (ad);
4309
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4313
m68k_areg (regs, opcode & 7) = ad;
4314
dump_fp_regs( "END ");
4318
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4326
wrd1 = get_long (ad);
4328
wrd2 = get_long (ad);
4330
wrd3 = get_long (ad);
4332
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4336
m68k_areg (regs, opcode & 7) = ad;
4337
dump_fp_regs( "END ");
4341
void REGPARAM2 fpuop_fmovem_Mem_2_fpp_dynamic_postinc( uae_u32 opcode, uae_u16 extra )
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;
4349
wrd1 = get_long (ad);
4351
wrd2 = get_long (ad);
4353
wrd3 = get_long (ad);
4355
to_exten_no_normalize (wrd1, wrd2, wrd3,fp_reg[reg]);
4359
dump_fp_regs( "END ");
4364
/* ---------------------------- FPP -> FMOVEM MEMORY ---------------------------- */
4366
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_pred_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4374
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4376
put_long (ad, wrd3);
4378
put_long (ad, wrd2);
4380
put_long (ad, wrd1);
4384
m68k_areg (regs, opcode & 7) = ad;
4385
dump_fp_regs( "END ");
4388
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_pred_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4396
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4398
put_long (ad, wrd3);
4400
put_long (ad, wrd2);
4402
put_long (ad, wrd1);
4406
m68k_areg (regs, opcode & 7) = ad;
4407
dump_fp_regs( "END ");
4410
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_pred( uae_u32 opcode, uae_u16 extra )
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;
4418
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4420
put_long (ad, wrd3);
4422
put_long (ad, wrd2);
4424
put_long (ad, wrd1);
4428
dump_fp_regs( "END ");
4431
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4439
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4441
put_long (ad, wrd3);
4443
put_long (ad, wrd2);
4445
put_long (ad, wrd1);
4449
m68k_areg (regs, opcode & 7) = ad;
4450
dump_fp_regs( "END ");
4453
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4461
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4463
put_long (ad, wrd3);
4465
put_long (ad, wrd2);
4467
put_long (ad, wrd1);
4471
m68k_areg (regs, opcode & 7) = ad;
4472
dump_fp_regs( "END ");
4475
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_pred( uae_u32 opcode, uae_u16 extra )
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;
4483
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4485
put_long (ad, wrd3);
4487
put_long (ad, wrd2);
4489
put_long (ad, wrd1);
4493
dump_fp_regs( "END ");
4496
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4504
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4505
put_long (ad, wrd1);
4507
put_long (ad, wrd2);
4509
put_long (ad, wrd3);
4514
m68k_areg (regs, opcode & 7) = ad;
4515
dump_fp_regs( "END ");
4518
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4526
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4527
put_long (ad, wrd1);
4529
put_long (ad, wrd2);
4531
put_long (ad, wrd3);
4536
m68k_areg (regs, opcode & 7) = ad;
4537
dump_fp_regs( "END ");
4540
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_static_postinc( uae_u32 opcode, uae_u16 extra )
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;
4548
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4549
put_long (ad, wrd1);
4551
put_long (ad, wrd2);
4553
put_long (ad, wrd3);
4558
dump_fp_regs( "END ");
4561
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement( uae_u32 opcode, uae_u16 extra )
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;
4569
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4570
put_long (ad, wrd1);
4572
put_long (ad, wrd2);
4574
put_long (ad, wrd3);
4579
m68k_areg (regs, opcode & 7) = ad;
4580
dump_fp_regs( "END ");
4583
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement( uae_u32 opcode, uae_u16 extra )
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;
4591
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4592
put_long (ad, wrd1);
4594
put_long (ad, wrd2);
4596
put_long (ad, wrd3);
4601
m68k_areg (regs, opcode & 7) = ad;
4602
dump_fp_regs( "END ");
4605
void REGPARAM2 fpuop_fmovem_fpp_2_Mem_dynamic_postinc( uae_u32 opcode, uae_u16 extra )
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;
4613
from_exten(fp_reg[reg],&wrd1, &wrd2, &wrd3);
4614
put_long (ad, wrd1);
4616
put_long (ad, wrd2);
4618
put_long (ad, wrd3);
4623
dump_fp_regs( "END ");
4628
/* ---------------------------- FMOVEM CONSTANT ROM -> FPP ---------------------------- */
4630
void REGPARAM2 fpuop_do_fldpi( uae_u32 opcode, uae_u16 extra )
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 ");
4638
void REGPARAM2 fpuop_do_fldlg2( uae_u32 opcode, uae_u16 extra )
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 ");
4646
void REGPARAM2 fpuop_do_load_const_e( uae_u32 opcode, uae_u16 extra )
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 ");
4654
void REGPARAM2 fpuop_do_fldl2e( uae_u32 opcode, uae_u16 extra )
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 ");
4662
void REGPARAM2 fpuop_do_load_const_log_10_e( uae_u32 opcode, uae_u16 extra )
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 ");
4670
void REGPARAM2 fpuop_do_fldz( uae_u32 opcode, uae_u16 extra )
4672
D(bug("FMOVECR memory->FPP FP const: zero\r\n"));
4673
memcpy( fp_reg[(extra>>7) & 7], const_z, sizeof(float80_s) );
4675
dump_fp_regs( "END ");
4678
void REGPARAM2 fpuop_do_fldln2( uae_u32 opcode, uae_u16 extra )
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 ");
4686
void REGPARAM2 fpuop_do_load_const_ln_10( uae_u32 opcode, uae_u16 extra )
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 ");
4694
void REGPARAM2 fpuop_do_fld1( uae_u32 opcode, uae_u16 extra )
4696
D(bug("FMOVECR memory->FPP FP const: 1.0e0\r\n"));
4697
memcpy( fp_reg[(extra>>7) & 7], const_1, sizeof(float80_s) );
4699
dump_fp_regs( "END ");
4702
void REGPARAM2 fpuop_do_load_const_1e1( uae_u32 opcode, uae_u16 extra )
4704
D(bug("FMOVECR memory->FPP FP const: 1.0e1\r\n"));
4705
memcpy( fp_reg[(extra>>7) & 7], const_1e1, sizeof(float80_s) );
4707
dump_fp_regs( "END ");
4710
void REGPARAM2 fpuop_do_load_const_1e2( uae_u32 opcode, uae_u16 extra )
4712
D(bug("FMOVECR memory->FPP FP const: 1.0e2\r\n"));
4713
memcpy( fp_reg[(extra>>7) & 7], const_1e2, sizeof(float80_s) );
4715
dump_fp_regs( "END ");
4718
void REGPARAM2 fpuop_do_load_const_1e4( uae_u32 opcode, uae_u16 extra )
4720
D(bug("FMOVECR memory->FPP FP const: 1.0e4\r\n"));
4721
memcpy( fp_reg[(extra>>7) & 7], const_1e4, sizeof(float80_s) );
4723
dump_fp_regs( "END ");
4726
void REGPARAM2 fpuop_do_load_const_1e8( uae_u32 opcode, uae_u16 extra )
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 ");
4734
void REGPARAM2 fpuop_do_load_const_1e16( uae_u32 opcode, uae_u16 extra )
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 ");
4742
void REGPARAM2 fpuop_do_load_const_1e32( uae_u32 opcode, uae_u16 extra )
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 ");
4750
void REGPARAM2 fpuop_do_load_const_1e64( uae_u32 opcode, uae_u16 extra )
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 ");
4758
void REGPARAM2 fpuop_do_load_const_1e128( uae_u32 opcode, uae_u16 extra )
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 ");
4766
void REGPARAM2 fpuop_do_load_const_1e256( uae_u32 opcode, uae_u16 extra )
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 ");
4774
void REGPARAM2 fpuop_do_load_const_1e512( uae_u32 opcode, uae_u16 extra )
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 ");
4782
void REGPARAM2 fpuop_do_load_const_1e1024( uae_u32 opcode, uae_u16 extra )
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 ");
4790
void REGPARAM2 fpuop_do_load_const_1e2048( uae_u32 opcode, uae_u16 extra )
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 ");
4798
void REGPARAM2 fpuop_do_load_const_1e4096( uae_u32 opcode, uae_u16 extra )
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 ");
4807
/* ---------------------------- ALU ---------------------------- */
4809
void REGPARAM2 fpuop_do_fmove( uae_u32 opcode, uae_u16 extra )
4811
int reg = (extra >> 7) & 7;
4813
if (get_fp_value (opcode, extra, src) == 0) {
4814
m68k_setpc (m68k_getpc () - 4);
4816
dump_fp_regs( "END ");
4819
D(bug("FMOVE %s\r\n",etos(src)));
4820
do_fmove( fp_reg[reg], src );
4822
dump_fp_regs( "END ");
4825
void REGPARAM2 fpuop_do_fint( uae_u32 opcode, uae_u16 extra )
4827
int reg = (extra >> 7) & 7;
4829
if (get_fp_value (opcode, extra, src) == 0) {
4830
m68k_setpc (m68k_getpc () - 4);
4832
dump_fp_regs( "END ");
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 ");
4840
void REGPARAM2 fpuop_do_fsinh( uae_u32 opcode, uae_u16 extra )
4842
int reg = (extra >> 7) & 7;
4844
if (get_fp_value (opcode, extra, src) == 0) {
4845
m68k_setpc (m68k_getpc () - 4);
4847
dump_fp_regs( "END ");
4850
D(bug("FSINH %s\r\n",etos(src)));
4851
do_fsinh( fp_reg[reg], src );
4853
dump_fp_regs( "END ");
4856
void REGPARAM2 fpuop_do_fintrz( uae_u32 opcode, uae_u16 extra )
4858
int reg = (extra >> 7) & 7;
4860
if (get_fp_value (opcode, extra, src) == 0) {
4861
m68k_setpc (m68k_getpc () - 4);
4863
dump_fp_regs( "END ");
4866
D(bug("FINTRZ %s\r\n",etos(src)));
4867
do_fintrz( fp_reg[reg], src );
4868
dump_fp_regs( "END ");
4871
void REGPARAM2 fpuop_do_fsqrt( uae_u32 opcode, uae_u16 extra )
4873
int reg = (extra >> 7) & 7;
4875
if (get_fp_value (opcode, extra, src) == 0) {
4876
m68k_setpc (m68k_getpc () - 4);
4878
dump_fp_regs( "END ");
4881
D(bug("FSQRT %s\r\n",etos(src)));
4882
do_fsqrt( fp_reg[reg], src );
4883
dump_fp_regs( "END ");
4886
void REGPARAM2 fpuop_do_flognp1( uae_u32 opcode, uae_u16 extra )
4888
int reg = (extra >> 7) & 7;
4890
if (get_fp_value (opcode, extra, src) == 0) {
4891
m68k_setpc (m68k_getpc () - 4);
4893
dump_fp_regs( "END ");
4896
D(bug("FLOGNP1 %s\r\n",etos(src)));
4897
do_flognp1( fp_reg[reg], src );
4899
dump_fp_regs( "END ");
4902
void REGPARAM2 fpuop_do_fetoxm1( uae_u32 opcode, uae_u16 extra )
4904
int reg = (extra >> 7) & 7;
4906
if (get_fp_value (opcode, extra, src) == 0) {
4907
m68k_setpc (m68k_getpc () - 4);
4909
dump_fp_regs( "END ");
4912
D(bug("FETOXM1 %s\r\n",etos(src)));
4913
do_fetoxm1( fp_reg[reg], src );
4915
dump_fp_regs( "END ");
4918
void REGPARAM2 fpuop_do_ftanh( uae_u32 opcode, uae_u16 extra )
4920
int reg = (extra >> 7) & 7;
4922
if (get_fp_value (opcode, extra, src) == 0) {
4923
m68k_setpc (m68k_getpc () - 4);
4925
dump_fp_regs( "END ");
4928
D(bug("FTANH %s\r\n",etos(src)));
4929
do_ftanh( fp_reg[reg], src );
4931
dump_fp_regs( "END ");
4934
void REGPARAM2 fpuop_do_fatan( uae_u32 opcode, uae_u16 extra )
4936
int reg = (extra >> 7) & 7;
4938
if (get_fp_value (opcode, extra, src) == 0) {
4939
m68k_setpc (m68k_getpc () - 4);
4941
dump_fp_regs( "END ");
4944
D(bug("FATAN %s\r\n",etos(src)));
4945
do_fatan( fp_reg[reg], src );
4947
dump_fp_regs( "END ");
4950
void REGPARAM2 fpuop_do_fasin( uae_u32 opcode, uae_u16 extra )
4952
int reg = (extra >> 7) & 7;
4954
if (get_fp_value (opcode, extra, src) == 0) {
4955
m68k_setpc (m68k_getpc () - 4);
4957
dump_fp_regs( "END ");
4960
D(bug("FASIN %s\r\n",etos(src)));
4961
do_fasin( fp_reg[reg], src );
4963
dump_fp_regs( "END ");
4966
void REGPARAM2 fpuop_do_fatanh( uae_u32 opcode, uae_u16 extra )
4968
int reg = (extra >> 7) & 7;
4970
if (get_fp_value (opcode, extra, src) == 0) {
4971
m68k_setpc (m68k_getpc () - 4);
4973
dump_fp_regs( "END ");
4976
D(bug("FATANH %s\r\n",etos(src)));
4977
do_fatanh( fp_reg[reg], src );
4979
dump_fp_regs( "END ");
4982
void REGPARAM2 fpuop_do_fsin( uae_u32 opcode, uae_u16 extra )
4984
int reg = (extra >> 7) & 7;
4986
if (get_fp_value (opcode, extra, src) == 0) {
4987
m68k_setpc (m68k_getpc () - 4);
4989
dump_fp_regs( "END ");
4992
D(bug("FSIN %s\r\n",etos(src)));
4993
do_fsin( fp_reg[reg], src );
4994
dump_fp_regs( "END ");
4997
void REGPARAM2 fpuop_do_ftan( uae_u32 opcode, uae_u16 extra )
4999
int reg = (extra >> 7) & 7;
5001
if (get_fp_value (opcode, extra, src) == 0) {
5002
m68k_setpc (m68k_getpc () - 4);
5004
dump_fp_regs( "END ");
5007
D(bug("FTAN %s\r\n",etos(src)));
5008
do_ftan( fp_reg[reg], src );
5009
dump_fp_regs( "END ");
5012
void REGPARAM2 fpuop_do_fetox( uae_u32 opcode, uae_u16 extra )
5014
int reg = (extra >> 7) & 7;
5016
if (get_fp_value (opcode, extra, src) == 0) {
5017
m68k_setpc (m68k_getpc () - 4);
5019
dump_fp_regs( "END ");
5022
D(bug("FETOX %s\r\n",etos(src)));
5023
do_fetox( fp_reg[reg], src );
5025
dump_fp_regs( "END ");
5028
void REGPARAM2 fpuop_do_ftwotox( uae_u32 opcode, uae_u16 extra )
5030
int reg = (extra >> 7) & 7;
5032
if (get_fp_value (opcode, extra, src) == 0) {
5033
m68k_setpc (m68k_getpc () - 4);
5035
dump_fp_regs( "END ");
5038
D(bug("FTWOTOX %s\r\n",etos(src)));
5039
do_ftwotox( fp_reg[reg], src );
5041
dump_fp_regs( "END ");
5044
void REGPARAM2 fpuop_do_ftentox( uae_u32 opcode, uae_u16 extra )
5046
int reg = (extra >> 7) & 7;
5048
if (get_fp_value (opcode, extra, src) == 0) {
5049
m68k_setpc (m68k_getpc () - 4);
5051
dump_fp_regs( "END ");
5054
D(bug("FTENTOX %s\r\n",etos(src)));
5055
do_ftentox( fp_reg[reg], src );
5057
dump_fp_regs( "END ");
5060
void REGPARAM2 fpuop_do_flogn( uae_u32 opcode, uae_u16 extra )
5062
int reg = (extra >> 7) & 7;
5064
if (get_fp_value (opcode, extra, src) == 0) {
5065
m68k_setpc (m68k_getpc () - 4);
5067
dump_fp_regs( "END ");
5070
D(bug("FLOGN %s\r\n",etos(src)));
5071
do_flogn( fp_reg[reg], src );
5073
dump_fp_regs( "END ");
5076
void REGPARAM2 fpuop_do_flog10( uae_u32 opcode, uae_u16 extra )
5078
int reg = (extra >> 7) & 7;
5080
if (get_fp_value (opcode, extra, src) == 0) {
5081
m68k_setpc (m68k_getpc () - 4);
5083
dump_fp_regs( "END ");
5086
D(bug("FLOG10 %s\r\n",etos(src)));
5087
do_flog10( fp_reg[reg], src );
5089
dump_fp_regs( "END ");
5092
void REGPARAM2 fpuop_do_flog2( uae_u32 opcode, uae_u16 extra )
5094
int reg = (extra >> 7) & 7;
5096
if (get_fp_value (opcode, extra, src) == 0) {
5097
m68k_setpc (m68k_getpc () - 4);
5099
dump_fp_regs( "END ");
5102
D(bug("FLOG2 %s\r\n",etos(src)));
5103
do_flog2( fp_reg[reg], src );
5105
dump_fp_regs( "END ");
5108
void REGPARAM2 fpuop_do_fabs( uae_u32 opcode, uae_u16 extra )
5110
int reg = (extra >> 7) & 7;
5112
if (get_fp_value (opcode, extra, src) == 0) {
5113
m68k_setpc (m68k_getpc () - 4);
5115
dump_fp_regs( "END ");
5118
D(bug("FABS %s\r\n",etos(src)));
5119
do_fabs( fp_reg[reg], src );
5120
dump_fp_regs( "END ");
5123
void REGPARAM2 fpuop_do_fcosh( uae_u32 opcode, uae_u16 extra )
5125
int reg = (extra >> 7) & 7;
5127
if (get_fp_value (opcode, extra, src) == 0) {
5128
m68k_setpc (m68k_getpc () - 4);
5130
dump_fp_regs( "END ");
5133
D(bug("FCOSH %s\r\n",etos(src)));
5134
do_fcosh( fp_reg[reg], src );
5136
dump_fp_regs( "END ");
5139
void REGPARAM2 fpuop_do_fneg( uae_u32 opcode, uae_u16 extra )
5141
int reg = (extra >> 7) & 7;
5143
if (get_fp_value (opcode, extra, src) == 0) {
5144
m68k_setpc (m68k_getpc () - 4);
5146
dump_fp_regs( "END ");
5149
D(bug("FNEG %s\r\n",etos(src)));
5150
do_fneg( fp_reg[reg], src );
5151
dump_fp_regs( "END ");
5154
void REGPARAM2 fpuop_do_facos( uae_u32 opcode, uae_u16 extra )
5156
int reg = (extra >> 7) & 7;
5158
if (get_fp_value (opcode, extra, src) == 0) {
5159
m68k_setpc (m68k_getpc () - 4);
5161
dump_fp_regs( "END ");
5164
D(bug("FACOS %s\r\n",etos(src)));
5165
do_facos( fp_reg[reg], src );
5167
dump_fp_regs( "END ");
5170
void REGPARAM2 fpuop_do_fcos( uae_u32 opcode, uae_u16 extra )
5172
int reg = (extra >> 7) & 7;
5174
if (get_fp_value (opcode, extra, src) == 0) {
5175
m68k_setpc (m68k_getpc () - 4);
5177
dump_fp_regs( "END ");
5180
D(bug("FCOS %s\r\n",etos(src)));
5181
do_fcos( fp_reg[reg], src );
5182
dump_fp_regs( "END ");
5185
void REGPARAM2 fpuop_do_fgetexp( uae_u32 opcode, uae_u16 extra )
5187
int reg = (extra >> 7) & 7;
5189
if (get_fp_value (opcode, extra, src) == 0) {
5190
m68k_setpc (m68k_getpc () - 4);
5192
dump_fp_regs( "END ");
5195
D(bug("FGETEXP %s\r\n",etos(src)));
5197
if( IS_INFINITY(src) ) {
5198
MAKE_NAN( fp_reg[reg] );
5199
do_ftst( fp_reg[reg] );
5202
do_fgetexp( fp_reg[reg], src );
5204
dump_fp_regs( "END ");
5207
void REGPARAM2 fpuop_do_fgetman( uae_u32 opcode, uae_u16 extra )
5209
int reg = (extra >> 7) & 7;
5211
if (get_fp_value (opcode, extra, src) == 0) {
5212
m68k_setpc (m68k_getpc () - 4);
5214
dump_fp_regs( "END ");
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] );
5223
do_fgetman( fp_reg[reg], src );
5225
dump_fp_regs( "END ");
5228
void REGPARAM2 fpuop_do_fdiv( uae_u32 opcode, uae_u16 extra )
5230
int reg = (extra >> 7) & 7;
5232
if (get_fp_value (opcode, extra, src) == 0) {
5233
m68k_setpc (m68k_getpc () - 4);
5235
dump_fp_regs( "END ");
5238
D(bug("FDIV %s\r\n",etos(src)));
5239
do_fdiv( fp_reg[reg], src );
5240
dump_fp_regs( "END ");
5243
void REGPARAM2 fpuop_do_fmod( uae_u32 opcode, uae_u16 extra )
5245
int reg = (extra >> 7) & 7;
5247
if (get_fp_value (opcode, extra, src) == 0) {
5248
m68k_setpc (m68k_getpc () - 4);
5250
dump_fp_regs( "END ");
5253
D(bug("FMOD %s\r\n",etos(src)));
5255
#if USE_3_BIT_QUOTIENT
5256
do_fmod( fp_reg[reg], src );
5258
if( (cw & X86_ROUND_CONTROL_MASK) == CW_RC_ZERO ) {
5259
do_fmod_dont_set_cw( fp_reg[reg], src );
5261
do_fmod( fp_reg[reg], src );
5264
dump_fp_regs( "END ");
5267
void REGPARAM2 fpuop_do_frem( uae_u32 opcode, uae_u16 extra )
5269
int reg = (extra >> 7) & 7;
5271
if (get_fp_value (opcode, extra, src) == 0) {
5272
m68k_setpc (m68k_getpc () - 4);
5274
dump_fp_regs( "END ");
5277
D(bug("FREM %s\r\n",etos(src)));
5278
#if USE_3_BIT_QUOTIENT
5279
do_frem( fp_reg[reg], src );
5281
if( (cw & X86_ROUND_CONTROL_MASK) == CW_RC_NEAR ) {
5282
do_frem_dont_set_cw( fp_reg[reg], src );
5284
do_frem( fp_reg[reg], src );
5287
dump_fp_regs( "END ");
5290
void REGPARAM2 fpuop_do_fadd( uae_u32 opcode, uae_u16 extra )
5292
int reg = (extra >> 7) & 7;
5294
if (get_fp_value (opcode, extra, src) == 0) {
5295
m68k_setpc (m68k_getpc () - 4);
5297
dump_fp_regs( "END ");
5300
D(bug("FADD %s\r\n",etos(src)));
5301
do_fadd( fp_reg[reg], src );
5302
dump_fp_regs( "END ");
5305
void REGPARAM2 fpuop_do_fmul( uae_u32 opcode, uae_u16 extra )
5307
int reg = (extra >> 7) & 7;
5309
if (get_fp_value (opcode, extra, src) == 0) {
5310
m68k_setpc (m68k_getpc () - 4);
5312
dump_fp_regs( "END ");
5315
D(bug("FMUL %s\r\n",etos(src)));
5316
do_fmul( fp_reg[reg], src );
5317
dump_fp_regs( "END ");
5320
void REGPARAM2 fpuop_do_fsgldiv( uae_u32 opcode, uae_u16 extra )
5322
int reg = (extra >> 7) & 7;
5324
if (get_fp_value (opcode, extra, src) == 0) {
5325
m68k_setpc (m68k_getpc () - 4);
5327
dump_fp_regs( "END ");
5330
D(bug("FSGLDIV %s\r\n",etos(src)));
5331
do_fsgldiv( fp_reg[reg], src );
5332
dump_fp_regs( "END ");
5335
void REGPARAM2 fpuop_do_fscale( uae_u32 opcode, uae_u16 extra )
5337
int reg = (extra >> 7) & 7;
5339
if (get_fp_value (opcode, extra, src) == 0) {
5340
m68k_setpc (m68k_getpc () - 4);
5342
dump_fp_regs( "END ");
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] );
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 );
5355
dump_fp_regs( "END ");
5358
void REGPARAM2 fpuop_do_fsglmul( uae_u32 opcode, uae_u16 extra )
5360
int reg = (extra >> 7) & 7;
5362
if (get_fp_value (opcode, extra, src) == 0) {
5363
m68k_setpc (m68k_getpc () - 4);
5365
dump_fp_regs( "END ");
5368
D(bug("FSGLMUL %s\r\n",etos(src)));
5369
do_fsglmul( fp_reg[reg], src );
5370
dump_fp_regs( "END ");
5373
void REGPARAM2 fpuop_do_fsub( uae_u32 opcode, uae_u16 extra )
5375
int reg = (extra >> 7) & 7;
5377
if (get_fp_value (opcode, extra, src) == 0) {
5378
m68k_setpc (m68k_getpc () - 4);
5380
dump_fp_regs( "END ");
5383
D(bug("FSUB %s\r\n",etos(src)));
5384
do_fsub( fp_reg[reg], src );
5385
dump_fp_regs( "END ");
5388
void REGPARAM2 fpuop_do_fsincos( uae_u32 opcode, uae_u16 extra )
5390
int reg = (extra >> 7) & 7;
5392
if (get_fp_value (opcode, extra, src) == 0) {
5393
m68k_setpc (m68k_getpc () - 4);
5395
dump_fp_regs( "END ");
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 ");
5403
void REGPARAM2 fpuop_do_fcmp( uae_u32 opcode, uae_u16 extra )
5405
int reg = (extra >> 7) & 7;
5407
if (get_fp_value (opcode, extra, src) == 0) {
5408
m68k_setpc (m68k_getpc () - 4);
5410
dump_fp_regs( "END ");
5413
D(bug("FCMP %s\r\n",etos(src)));
5415
if( IS_INFINITY(src) ) {
5416
if( IS_NEGATIVE(src) ) {
5417
if( IS_INFINITY(fp_reg[reg]) && IS_NEGATIVE(fp_reg[reg]) ) {
5419
D(bug("-INF FCMP -INF -> NZ\r\n"));
5422
D(bug("X FCMP -INF -> None\r\n"));
5425
if( IS_INFINITY(fp_reg[reg]) && !IS_NEGATIVE(fp_reg[reg]) ) {
5427
D(bug("+INF FCMP +INF -> Z\r\n"));
5430
D(bug("X FCMP +INF -> N\r\n"));
5433
} else if( IS_INFINITY(fp_reg[reg]) ) {
5434
if( IS_NEGATIVE(fp_reg[reg]) ) {
5436
D(bug("-INF FCMP X -> Negative\r\n"));
5439
D(bug("+INF FCMP X -> None\r\n"));
5442
do_fcmp( fp_reg[reg], src );
5445
dump_fp_regs( "END ");
5448
void REGPARAM2 fpuop_do_ftst( uae_u32 opcode, uae_u16 extra )
5450
int reg = (extra >> 7) & 7;
5452
if (get_fp_value (opcode, extra, src) == 0) {
5453
m68k_setpc (m68k_getpc () - 4);
5455
dump_fp_regs( "END ");
5458
D(bug("FTST %s\r\n",etos(src)));
5461
dump_fp_regs( "END ");
5466
/* ---------------------------- SET FPU MODE ---------------------------- */
5468
void fpu_set_integral_fpu( bool is_integral )
5470
is_integral_68040_fpu = (uae_u32)is_integral;
5474
/* ---------------------------- SETUP TABLES ---------------------------- */
5476
static void build_fpp_opp_lookup_table()
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;
5483
switch ((extra >> 13) & 0x7) {
5485
fpufunctbl[mask] = fpuop_fmove_2_ea;
5489
if ((opcode & 0x38) == 0) {
5490
if (extra & 0x2000) { // dr bit
5491
switch( extra & 0x1C00 ) {
5493
fpufunctbl[mask] = fpuop_fmovem_none_2_Dreg;
5496
fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Dreg;
5499
fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Dreg;
5502
fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Dreg;
5505
fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Dreg;
5508
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Dreg;
5511
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Dreg;
5514
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg;
5518
switch( extra & 0x1C00 ) {
5520
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_none;
5523
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpiar;
5526
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpsr;
5529
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpsr_fpiar;
5532
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr;
5535
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr_fpiar;
5538
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr_fpsr;
5541
fpufunctbl[mask] = fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar;
5545
} else if ((opcode & 0x38) == 8) {
5546
if (extra & 0x2000) { // dr bit
5547
switch( extra & 0x1C00 ) {
5549
fpufunctbl[mask] = fpuop_fmovem_none_2_Areg;
5552
fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Areg;
5555
fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Areg;
5558
fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Areg;
5561
fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Areg;
5564
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Areg;
5567
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Areg;
5570
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg;
5574
switch( extra & 0x1C00 ) {
5576
fpufunctbl[mask] = fpuop_fmovem_Areg_2_none;
5579
fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpiar;
5582
fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpsr;
5585
fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpsr_fpiar;
5588
fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr;
5591
fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr_fpiar;
5594
fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr_fpsr;
5597
fpufunctbl[mask] = fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar;
5601
} else if (extra & 0x2000) {
5602
if ((opcode & 0x38) == 0x20) {
5603
switch( extra & 0x1C00 ) {
5605
fpufunctbl[mask] = fpuop_fmovem_none_2_Mem_predecrement;
5608
fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Mem_predecrement;
5611
fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Mem_predecrement;
5614
fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement;
5617
fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Mem_predecrement;
5620
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement;
5623
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement;
5626
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement;
5629
} else if ((opcode & 0x38) == 0x18) {
5630
switch( extra & 0x1C00 ) {
5632
fpufunctbl[mask] = fpuop_fmovem_none_2_Mem_postincrement;
5635
fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Mem_postincrement;
5638
fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Mem_postincrement;
5641
fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement;
5644
fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Mem_postincrement;
5647
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement;
5650
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement;
5653
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement;
5657
switch( extra & 0x1C00 ) {
5659
fpufunctbl[mask] = fpuop_fmovem_none_2_Mem;
5662
fpufunctbl[mask] = fpuop_fmovem_fpiar_2_Mem;
5665
fpufunctbl[mask] = fpuop_fmovem_fpsr_2_Mem;
5668
fpufunctbl[mask] = fpuop_fmovem_fpsr_fpiar_2_Mem;
5671
fpufunctbl[mask] = fpuop_fmovem_fpcr_2_Mem;
5674
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpiar_2_Mem;
5677
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_2_Mem;
5680
fpufunctbl[mask] = fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem;
5685
if ((opcode & 0x38) == 0x20) {
5686
switch( extra & 0x1C00 ) {
5688
fpufunctbl[mask] = fpuop_fmovem_Mem_2_none_predecrement;
5691
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpiar_predecrement;
5694
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_predecrement;
5697
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement;
5700
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_predecrement;
5703
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement;
5706
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement;
5709
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement;
5712
} else if ((opcode & 0x38) == 0x18) {
5713
switch( extra & 0x1C00 ) {
5715
fpufunctbl[mask] = fpuop_fmovem_Mem_2_none_postincrement;
5718
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpiar_postincrement;
5721
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_postincrement;
5724
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement;
5727
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_postincrement;
5730
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement;
5733
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement;
5736
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement;
5740
switch( extra & 0x1C00 ) {
5742
fpufunctbl[mask] = fpuop_fmovem_Mem_2_none_2_Mem;
5745
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpiar_2_Mem;
5748
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_2_Mem;
5751
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem;
5754
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_2_Mem;
5757
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem;
5760
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem;
5763
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem;
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;
5776
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_pred;
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;
5784
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_pred;
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;
5792
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_static_postinc;
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;
5800
fpufunctbl[mask] = fpuop_fmovem_Mem_2_fpp_dynamic_postinc;
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;
5812
fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_pred;
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;
5820
fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_pred;
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;
5828
fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_static_postinc;
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;
5836
fpufunctbl[mask] = fpuop_fmovem_fpp_2_Mem_dynamic_postinc;
5842
if ((extra & 0xfc00) == 0x5c00) {
5843
switch (extra & 0x7f) {
5845
fpufunctbl[mask] = fpuop_do_fldpi;
5848
fpufunctbl[mask] = fpuop_do_fldlg2;
5851
fpufunctbl[mask] = fpuop_do_load_const_e;
5854
fpufunctbl[mask] = fpuop_do_fldl2e;
5857
fpufunctbl[mask] = fpuop_do_load_const_log_10_e;
5860
fpufunctbl[mask] = fpuop_do_fldz;
5863
fpufunctbl[mask] = fpuop_do_fldln2;
5866
fpufunctbl[mask] = fpuop_do_load_const_ln_10;
5869
fpufunctbl[mask] = fpuop_do_fld1;
5872
fpufunctbl[mask] = fpuop_do_load_const_1e1;
5875
fpufunctbl[mask] = fpuop_do_load_const_1e2;
5878
fpufunctbl[mask] = fpuop_do_load_const_1e4;
5881
fpufunctbl[mask] = fpuop_do_load_const_1e8;
5884
fpufunctbl[mask] = fpuop_do_load_const_1e16;
5887
fpufunctbl[mask] = fpuop_do_load_const_1e32;
5890
fpufunctbl[mask] = fpuop_do_load_const_1e64;
5893
fpufunctbl[mask] = fpuop_do_load_const_1e128;
5896
fpufunctbl[mask] = fpuop_do_load_const_1e256;
5899
fpufunctbl[mask] = fpuop_do_load_const_1e512;
5902
fpufunctbl[mask] = fpuop_do_load_const_1e1024;
5905
fpufunctbl[mask] = fpuop_do_load_const_1e2048;
5908
fpufunctbl[mask] = fpuop_do_load_const_1e4096;
5914
switch (extra & 0x7f) {
5916
fpufunctbl[mask] = fpuop_do_fmove;
5919
fpufunctbl[mask] = fpuop_do_fint;
5922
fpufunctbl[mask] = fpuop_do_fsinh;
5925
fpufunctbl[mask] = fpuop_do_fintrz;
5928
fpufunctbl[mask] = fpuop_do_fsqrt;
5931
fpufunctbl[mask] = fpuop_do_flognp1;
5934
fpufunctbl[mask] = fpuop_do_fetoxm1;
5937
fpufunctbl[mask] = fpuop_do_ftanh;
5940
fpufunctbl[mask] = fpuop_do_fatan;
5943
fpufunctbl[mask] = fpuop_do_fasin;
5946
fpufunctbl[mask] = fpuop_do_fatanh;
5949
fpufunctbl[mask] = fpuop_do_fsin;
5952
fpufunctbl[mask] = fpuop_do_ftan;
5955
fpufunctbl[mask] = fpuop_do_fetox;
5958
fpufunctbl[mask] = fpuop_do_ftwotox;
5961
fpufunctbl[mask] = fpuop_do_ftentox;
5964
fpufunctbl[mask] = fpuop_do_flogn;
5967
fpufunctbl[mask] = fpuop_do_flog10;
5970
fpufunctbl[mask] = fpuop_do_flog2;
5973
fpufunctbl[mask] = fpuop_do_fabs;
5976
fpufunctbl[mask] = fpuop_do_fcosh;
5979
fpufunctbl[mask] = fpuop_do_fneg;
5982
fpufunctbl[mask] = fpuop_do_facos;
5985
fpufunctbl[mask] = fpuop_do_fcos;
5988
fpufunctbl[mask] = fpuop_do_fgetexp;
5991
fpufunctbl[mask] = fpuop_do_fgetman;
5994
fpufunctbl[mask] = fpuop_do_fdiv;
5997
fpufunctbl[mask] = fpuop_do_fmod;
6000
fpufunctbl[mask] = fpuop_do_fadd;
6003
fpufunctbl[mask] = fpuop_do_fmul;
6006
fpufunctbl[mask] = fpuop_do_fsgldiv;
6009
fpufunctbl[mask] = fpuop_do_frem;
6012
fpufunctbl[mask] = fpuop_do_fscale;
6015
fpufunctbl[mask] = fpuop_do_fsglmul;
6018
fpufunctbl[mask] = fpuop_do_fsub;
6028
fpufunctbl[mask] = fpuop_do_fsincos;
6031
fpufunctbl[mask] = fpuop_do_fcmp;
6034
fpufunctbl[mask] = fpuop_do_ftst;
6043
static void build_fpsr_lookup_tables()
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:
6053
case SW_EMPTY_REGISTER:
6054
sw_cond_host2mac[i] |= 0x1000000;
6060
sw_cond_host2mac[i] |= 0x2000000;
6063
sw_cond_host2mac[i] |= 0x4000000;
6066
if( (i << 8) & SW_N ) {
6067
sw_cond_host2mac[i] |= 0x8000000;
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;
6080
sw_cond_mac2host[i] = SW_FINITE;
6082
if( (i << 24) & 0x8000000 ) {
6083
sw_cond_mac2host[i] |= SW_N;
6087
// Mapping for "sw" -> fpsr exception byte
6088
for( i=0; i<0x80; i++ ) {
6089
exception_host2mac[i] = 0;
6091
if(i & SW_FAKE_BSUN) {
6092
exception_host2mac[i] |= BSUN;
6094
// precision exception
6096
exception_host2mac[i] |= INEX2;
6098
// underflow exception
6100
exception_host2mac[i] |= UNFL;
6102
// overflow exception
6104
exception_host2mac[i] |= OVFL;
6106
// zero divide exception
6108
exception_host2mac[i] |= DZ;
6110
// denormalized operand exception.
6111
// wrong, but should not get here, normalization is done in elsewhere
6113
exception_host2mac[i] |= SNAN;
6115
// invalid operation exception
6117
exception_host2mac[i] |= OPERR;
6121
// Mapping for fpsr exception byte -> "sw"
6122
for( i=0; i<0x100; i++ ) {
6123
int fpsr = (i << 8);
6124
exception_mac2host[i] = 0;
6126
// BSUN; make sure that you don't generate FPU stack faults.
6128
exception_mac2host[i] |= SW_FAKE_BSUN;
6130
// precision exception
6132
exception_mac2host[i] |= SW_PE;
6134
// underflow exception
6136
exception_mac2host[i] |= SW_UE;
6138
// overflow exception
6140
exception_mac2host[i] |= SW_OE;
6142
// zero divide exception
6144
exception_mac2host[i] |= SW_ZE;
6146
// denormalized operand exception
6148
exception_mac2host[i] |= SW_DE; //Wrong
6150
// invalid operation exception
6152
exception_mac2host[i] |= SW_IE;
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)
6165
// Mapping for "sw_accrued" -> fpsr accrued exception byte
6166
for( i=0; i<0x40; i++ ) {
6167
accrued_exception_host2mac[i] = 0;
6169
// precision exception
6171
accrued_exception_host2mac[i] |= ACCR_INEX;
6173
// underflow exception
6175
accrued_exception_host2mac[i] |= ACCR_UNFL;
6177
// overflow exception
6179
accrued_exception_host2mac[i] |= ACCR_OVFL;
6181
// zero divide exception
6183
accrued_exception_host2mac[i] |= ACCR_DZ;
6185
// denormalized operand exception
6187
accrued_exception_host2mac[i] |= ACCR_IOP; //??????
6189
// invalid operation exception
6191
accrued_exception_host2mac[i] |= ACCR_IOP;
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;
6200
// precision exception
6201
if(fpsr & ACCR_INEX) {
6202
accrued_exception_mac2host[i] |= SW_PE;
6204
// underflow exception
6205
if(fpsr & ACCR_UNFL) {
6206
accrued_exception_mac2host[i] |= SW_UE;
6208
// overflow exception
6209
if(fpsr & ACCR_OVFL) {
6210
accrued_exception_mac2host[i] |= SW_OE;
6212
// zero divide exception
6213
if(fpsr & ACCR_DZ) {
6214
accrued_exception_mac2host[i] |= SW_ZE;
6216
// What about SW_DE; //??????
6217
// invalid operation exception
6218
if(fpsr & ACCR_IOP) {
6219
accrued_exception_mac2host[i] |= SW_IE;
6224
/* ---------------------------- CONSTANTS ---------------------------- */
6226
static void set_constant( float80 f, char *name, double value, uae_s32 mult )
6228
FPU_CONSISTENCY_CHECK_START();
6232
FLD QWORD PTR [value]
6233
FSTP TBYTE PTR [ESI]
6243
FILD DWORD PTR [mult]
6244
FLD QWORD PTR [value]
6246
FSTP TBYTE PTR [ESI]
6253
: "m" (value), "m" (mult)
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)" );
6260
static void do_fldpi( float80 dest ) REGPARAM;
6261
static void do_fldpi( float80 dest )
6263
FPU_CONSISTENCY_CHECK_START();
6269
FSTP TBYTE PTR [EDI]
6275
: "=m" (sw), "=m" (*dest)
6277
FPU_CONSISTENCY_CHECK_STOP("do_fldpi");
6280
static void do_fldlg2( float80 dest ) REGPARAM;
6281
static void do_fldlg2( float80 dest )
6283
FPU_CONSISTENCY_CHECK_START();
6289
FSTP TBYTE PTR [EDI]
6295
: "=m" (sw), "=m" (*dest)
6297
FPU_CONSISTENCY_CHECK_STOP("do_fldlg2");
6300
static void do_fldl2e( float80 dest ) REGPARAM;
6301
static void do_fldl2e( float80 dest )
6303
FPU_CONSISTENCY_CHECK_START();
6309
FSTP TBYTE PTR [EDI]
6315
: "=m" (sw), "=m" (*dest)
6317
FPU_CONSISTENCY_CHECK_STOP("do_fldl2e");
6320
static void do_fldz( float80 dest ) REGPARAM;
6321
static void do_fldz( float80 dest )
6323
FPU_CONSISTENCY_CHECK_START();
6329
FSTP TBYTE PTR [EDI]
6335
: "=m" (sw), "=m" (*dest)
6337
FPU_CONSISTENCY_CHECK_STOP("do_fldz");
6340
static void do_fldln2( float80 dest ) REGPARAM;
6341
static void do_fldln2( float80 dest )
6343
FPU_CONSISTENCY_CHECK_START();
6349
FSTP TBYTE PTR [EDI]
6355
: "=m" (sw), "=m" (*dest)
6357
FPU_CONSISTENCY_CHECK_STOP("do_fldln2");
6360
static void do_fld1( float80 dest ) REGPARAM;
6361
static void do_fld1( float80 dest )
6363
FPU_CONSISTENCY_CHECK_START();
6369
FSTP TBYTE PTR [EDI]
6375
: "=m" (sw), "=m" (*dest)
6377
FPU_CONSISTENCY_CHECK_STOP("do_fld1");
6381
/* ---------------------------- MAIN INIT ---------------------------- */
6383
void fpu_init( void )
6386
FSAVE m_fpu_state_original
6388
_ASM("fsave %0" : "=m" (m_fpu_state_original));
6399
for( int i=0; i<8; i++ ) {
6400
MAKE_NAN( fp_reg[i] );
6403
build_fpsr_lookup_tables();
6404
build_fpp_opp_lookup_table();
6410
_ASM("fninit\nfldcw %0" : : "m" (cw));
6412
do_fldpi( const_pi );
6413
do_fldlg2( const_lg2 );
6414
do_fldl2e( const_l2e );
6416
do_fldln2( const_ln2 );
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 );
6441
_ASM("fninit\nfldcw %0" : : "m" (cw));
6444
void fpu_exit( void )
6447
FRSTOR m_fpu_state_original
6450
_ASM("frstor %0" : : "m" (m_fpu_state_original));
6453
void fpu_reset( void )
6460
#pragma optimize("",on)