|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68881 emulation
5: *
6: * Copyright 1996 Herman ten Brugge
7: */
8:
9: #include <math.h>
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include "config.h"
15: #include "options.h"
16: #include "memory.h"
17: #include "custom.h"
18: #include "newcpu.h"
19: #include "ersatz.h"
1.1.1.4 root 20: #include "md-fpp.h"
1.1 root 21:
1.1.1.3 root 22: #if 1
1.1 root 23:
24: #define DEBUG_FPP 0
25:
1.1.1.5 root 26: #define MAKE_FPSR(fpsr,r) (fpsr) = ((fpsr) & 0x00FFFFFF) | ((r) == 0 ? 0x4000000 : 0) | ((r) < 0 ? 0x8000000 : 0)
27:
1.1 root 28: /* single : S 8*E 23*F */
29: /* double : S 11*E 52*F */
30: /* extended : S 15*E 64*F */
31: /* E = 0 & F = 0 -> 0 */
32: /* E = MAX & F = 0 -> Infin */
33: /* E = MAX & F # 0 -> NotANumber */
34: /* E = biased by 127 (single) ,1023 (double) ,16383 (extended) */
35:
1.1.1.5 root 36: STATIC_INLINE double to_pack (uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
1.1 root 37: {
1.1.1.3 root 38: double d;
39: char *cp;
40: char str[100];
41:
42: cp = str;
43: if (wrd1 & 0x80000000)
44: *cp++ = '-';
45: *cp++ = (wrd1 & 0xf) + '0';
46: *cp++ = '.';
47: *cp++ = ((wrd2 >> 28) & 0xf) + '0';
48: *cp++ = ((wrd2 >> 24) & 0xf) + '0';
49: *cp++ = ((wrd2 >> 20) & 0xf) + '0';
50: *cp++ = ((wrd2 >> 16) & 0xf) + '0';
51: *cp++ = ((wrd2 >> 12) & 0xf) + '0';
52: *cp++ = ((wrd2 >> 8) & 0xf) + '0';
53: *cp++ = ((wrd2 >> 4) & 0xf) + '0';
54: *cp++ = ((wrd2 >> 0) & 0xf) + '0';
55: *cp++ = ((wrd3 >> 28) & 0xf) + '0';
56: *cp++ = ((wrd3 >> 24) & 0xf) + '0';
57: *cp++ = ((wrd3 >> 20) & 0xf) + '0';
58: *cp++ = ((wrd3 >> 16) & 0xf) + '0';
59: *cp++ = ((wrd3 >> 12) & 0xf) + '0';
60: *cp++ = ((wrd3 >> 8) & 0xf) + '0';
61: *cp++ = ((wrd3 >> 4) & 0xf) + '0';
62: *cp++ = ((wrd3 >> 0) & 0xf) + '0';
63: *cp++ = 'E';
64: if (wrd1 & 0x40000000)
65: *cp++ = '-';
66: *cp++ = ((wrd1 >> 24) & 0xf) + '0';
67: *cp++ = ((wrd1 >> 20) & 0xf) + '0';
68: *cp++ = ((wrd1 >> 16) & 0xf) + '0';
69: *cp = 0;
1.1.1.5 root 70: sscanf (str, "%le", &d);
1.1.1.3 root 71: return d;
1.1 root 72: }
73:
1.1.1.5 root 74: STATIC_INLINE void from_pack (double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
1.1 root 75: {
1.1.1.3 root 76: int i;
77: int t;
78: char *cp;
79: char str[100];
80:
1.1.1.5 root 81: sprintf (str, "%.16e", src);
1.1.1.3 root 82: cp = str;
83: *wrd1 = *wrd2 = *wrd3 = 0;
84: if (*cp == '-') {
85: cp++;
86: *wrd1 = 0x80000000;
87: }
88: if (*cp == '+')
89: cp++;
90: *wrd1 |= (*cp++ - '0');
91: if (*cp == '.')
92: cp++;
93: for (i = 0; i < 8; i++) {
94: *wrd2 <<= 4;
95: if (*cp >= '0' && *cp <= '9')
96: *wrd2 |= *cp++ - '0';
97: }
98: for (i = 0; i < 8; i++) {
99: *wrd3 <<= 4;
100: if (*cp >= '0' && *cp <= '9')
101: *wrd3 |= *cp++ - '0';
102: }
103: if (*cp == 'e' || *cp == 'E') {
104: cp++;
105: if (*cp == '-') {
106: cp++;
107: *wrd1 |= 0x40000000;
108: }
109: if (*cp == '+')
110: cp++;
111: t = 0;
112: for (i = 0; i < 3; i++) {
113: if (*cp >= '0' && *cp <= '9')
114: t = (t << 4) | (*cp++ - '0');
1.1 root 115: }
1.1.1.3 root 116: *wrd1 |= t << 16;
117: }
1.1 root 118: }
119:
1.1.1.4 root 120: STATIC_INLINE int get_fp_value (uae_u32 opcode, uae_u16 extra, double *src)
1.1 root 121: {
1.1.1.3 root 122: uaecptr tmppc;
123: uae_u16 tmp;
124: int size;
125: int mode;
126: int reg;
127: uae_u32 ad = 0;
1.1.1.5 root 128: static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
129: static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
1.1.1.3 root 130:
131: if ((extra & 0x4000) == 0) {
132: *src = regs.fp[(extra >> 10) & 7];
133: return 1;
134: }
135: mode = (opcode >> 3) & 7;
136: reg = opcode & 7;
137: size = (extra >> 10) & 7;
138: switch (mode) {
139: case 0:
140: switch (size) {
141: case 6:
142: *src = (double) (uae_s8) m68k_dreg (regs, reg);
143: break;
144: case 4:
145: *src = (double) (uae_s16) m68k_dreg (regs, reg);
146: break;
1.1 root 147: case 0:
1.1.1.3 root 148: *src = (double) (uae_s32) m68k_dreg (regs, reg);
149: break;
150: case 1:
1.1.1.5 root 151: *src = to_single (m68k_dreg (regs, reg));
1.1.1.3 root 152: break;
153: default:
154: return 0;
155: }
156: return 1;
157: case 1:
158: return 0;
159: case 2:
160: ad = m68k_areg (regs, reg);
161: break;
162: case 3:
163: ad = m68k_areg (regs, reg);
164: m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
165: break;
166: case 4:
167: m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
168: ad = m68k_areg (regs, reg);
169: break;
170: case 5:
1.1.1.5 root 171: ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 172: break;
173: case 6:
1.1.1.5 root 174: ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword ());
1.1.1.3 root 175: break;
176: case 7:
177: switch (reg) {
178: case 0:
1.1.1.5 root 179: ad = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 180: break;
1.1 root 181: case 1:
1.1.1.5 root 182: ad = next_ilong ();
1.1.1.3 root 183: break;
1.1 root 184: case 2:
1.1.1.3 root 185: ad = m68k_getpc ();
1.1.1.5 root 186: ad += (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 187: break;
1.1 root 188: case 3:
1.1.1.3 root 189: tmppc = m68k_getpc ();
1.1.1.5 root 190: tmp = next_iword ();
1.1.1.3 root 191: ad = get_disp_ea_020 (tmppc, tmp);
192: break;
1.1 root 193: case 4:
1.1.1.3 root 194: ad = m68k_getpc ();
195: m68k_setpc (ad + sz2[size]);
196: break;
1.1 root 197: default:
1.1.1.3 root 198: return 0;
1.1 root 199: }
1.1.1.3 root 200: }
201: switch (size) {
202: case 0:
203: *src = (double) (uae_s32) get_long (ad);
204: break;
205: case 1:
1.1.1.5 root 206: *src = to_single (get_long (ad));
1.1.1.3 root 207: break;
208: case 2:{
209: uae_u32 wrd1, wrd2, wrd3;
210: wrd1 = get_long (ad);
211: ad += 4;
212: wrd2 = get_long (ad);
213: ad += 4;
214: wrd3 = get_long (ad);
1.1.1.5 root 215: *src = to_exten (wrd1, wrd2, wrd3);
1.1.1.3 root 216: }
217: break;
218: case 3:{
219: uae_u32 wrd1, wrd2, wrd3;
220: wrd1 = get_long (ad);
221: ad += 4;
222: wrd2 = get_long (ad);
223: ad += 4;
224: wrd3 = get_long (ad);
1.1.1.5 root 225: *src = to_pack (wrd1, wrd2, wrd3);
1.1.1.3 root 226: }
227: break;
228: case 4:
1.1.1.5 root 229: *src = (double) (uae_s16) get_word (ad);
1.1.1.3 root 230: break;
231: case 5:{
232: uae_u32 wrd1, wrd2;
233: wrd1 = get_long (ad);
234: ad += 4;
235: wrd2 = get_long (ad);
1.1.1.5 root 236: *src = to_double (wrd1, wrd2);
1.1.1.3 root 237: }
238: break;
239: case 6:
1.1.1.5 root 240: *src = (double) (uae_s8) get_byte (ad);
1.1.1.3 root 241: break;
242: default:
243: return 0;
244: }
245: return 1;
1.1 root 246: }
247:
1.1.1.4 root 248: STATIC_INLINE int put_fp_value (double value, uae_u32 opcode, uae_u16 extra)
1.1 root 249: {
1.1.1.3 root 250: uae_u16 tmp;
251: uaecptr tmppc;
252: int size;
253: int mode;
254: int reg;
255: uae_u32 ad;
1.1.1.5 root 256: static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 };
257: static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 };
1.1.1.3 root 258:
259: if ((extra & 0x4000) == 0) {
260: regs.fp[(extra >> 10) & 7] = value;
261: return 1;
262: }
263: mode = (opcode >> 3) & 7;
264: reg = opcode & 7;
265: size = (extra >> 10) & 7;
266: ad = -1;
267: switch (mode) {
268: case 0:
269: switch (size) {
270: case 6:
271: m68k_dreg (regs, reg) = (((int) value & 0xff)
1.1.1.4 root 272: | (m68k_dreg (regs, reg) & ~0xff));
1.1.1.3 root 273: break;
274: case 4:
275: m68k_dreg (regs, reg) = (((int) value & 0xffff)
1.1.1.4 root 276: | (m68k_dreg (regs, reg) & ~0xffff));
1.1.1.3 root 277: break;
1.1 root 278: case 0:
1.1.1.3 root 279: m68k_dreg (regs, reg) = (int) value;
280: break;
1.1 root 281: case 1:
1.1.1.5 root 282: m68k_dreg (regs, reg) = from_single (value);
1.1.1.3 root 283: break;
284: default:
285: return 0;
286: }
287: return 1;
288: case 1:
289: return 0;
290: case 2:
291: ad = m68k_areg (regs, reg);
292: break;
293: case 3:
294: ad = m68k_areg (regs, reg);
295: m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
296: break;
297: case 4:
298: m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size];
299: ad = m68k_areg (regs, reg);
300: break;
301: case 5:
1.1.1.5 root 302: ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 303: break;
304: case 6:
1.1.1.5 root 305: ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword ());
1.1.1.3 root 306: break;
307: case 7:
308: switch (reg) {
309: case 0:
1.1.1.5 root 310: ad = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 311: break;
312: case 1:
1.1.1.5 root 313: ad = next_ilong ();
1.1.1.3 root 314: break;
1.1 root 315: case 2:
1.1.1.3 root 316: ad = m68k_getpc ();
1.1.1.5 root 317: ad += (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 318: break;
1.1 root 319: case 3:
1.1.1.3 root 320: tmppc = m68k_getpc ();
1.1.1.5 root 321: tmp = next_iword ();
1.1.1.3 root 322: ad = get_disp_ea_020 (tmppc, tmp);
323: break;
1.1 root 324: case 4:
1.1.1.3 root 325: ad = m68k_getpc ();
326: m68k_setpc (ad + sz2[size]);
327: break;
1.1 root 328: default:
1.1.1.3 root 329: return 0;
1.1 root 330: }
1.1.1.3 root 331: }
332: switch (size) {
333: case 0:
334: put_long (ad, (uae_s32) value);
335: break;
336: case 1:
1.1.1.5 root 337: put_long (ad, from_single (value));
1.1.1.3 root 338: break;
339: case 2:
340: {
341: uae_u32 wrd1, wrd2, wrd3;
1.1.1.5 root 342: from_exten (value, &wrd1, &wrd2, &wrd3);
1.1.1.3 root 343: put_long (ad, wrd1);
344: ad += 4;
345: put_long (ad, wrd2);
346: ad += 4;
347: put_long (ad, wrd3);
348: }
349: break;
350: case 3:
351: {
352: uae_u32 wrd1, wrd2, wrd3;
1.1.1.5 root 353: from_pack (value, &wrd1, &wrd2, &wrd3);
1.1.1.3 root 354: put_long (ad, wrd1);
355: ad += 4;
356: put_long (ad, wrd2);
357: ad += 4;
358: put_long (ad, wrd3);
359: }
360: break;
361: case 4:
1.1.1.5 root 362: put_word (ad, (uae_s16) value);
1.1.1.3 root 363: break;
364: case 5:{
365: uae_u32 wrd1, wrd2;
1.1.1.5 root 366: from_double (value, &wrd1, &wrd2);
1.1.1.3 root 367: put_long (ad, wrd1);
368: ad += 4;
369: put_long (ad, wrd2);
370: }
371: break;
372: case 6:
1.1.1.5 root 373: put_byte (ad, (uae_s8) value);
1.1.1.3 root 374: break;
375: default:
376: return 0;
377: }
378: return 1;
1.1 root 379: }
380:
1.1.1.5 root 381: STATIC_INLINE int get_fp_ad (uae_u32 opcode, uae_u32 * ad)
1.1 root 382: {
1.1.1.3 root 383: uae_u16 tmp;
384: uaecptr tmppc;
385: int mode;
386: int reg;
387:
388: mode = (opcode >> 3) & 7;
389: reg = opcode & 7;
390: switch (mode) {
391: case 0:
392: case 1:
393: return 0;
394: case 2:
395: *ad = m68k_areg (regs, reg);
396: break;
397: case 3:
398: *ad = m68k_areg (regs, reg);
399: break;
400: case 4:
401: *ad = m68k_areg (regs, reg);
402: break;
403: case 5:
1.1.1.5 root 404: *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 405: break;
406: case 6:
1.1.1.5 root 407: *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword ());
1.1.1.3 root 408: break;
409: case 7:
410: switch (reg) {
1.1 root 411: case 0:
1.1.1.5 root 412: *ad = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 413: break;
1.1 root 414: case 1:
1.1.1.5 root 415: *ad = next_ilong ();
1.1.1.3 root 416: break;
1.1 root 417: case 2:
1.1.1.3 root 418: *ad = m68k_getpc ();
1.1.1.5 root 419: *ad += (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 420: break;
1.1 root 421: case 3:
1.1.1.3 root 422: tmppc = m68k_getpc ();
1.1.1.5 root 423: tmp = next_iword ();
1.1.1.3 root 424: *ad = get_disp_ea_020 (tmppc, tmp);
425: break;
426: default:
427: return 0;
1.1 root 428: }
1.1.1.3 root 429: }
430: return 1;
1.1 root 431: }
432:
1.1.1.5 root 433: STATIC_INLINE int fpp_cond (uae_u32 opcode, int contition)
1.1 root 434: {
1.1.1.3 root 435: int N = (regs.fpsr & 0x8000000) != 0;
436: int Z = (regs.fpsr & 0x4000000) != 0;
437: /* int I = (regs.fpsr & 0x2000000) != 0; */
438: int NotANumber = (regs.fpsr & 0x1000000) != 0;
439:
440: switch (contition) {
441: case 0x00:
442: return 0;
443: case 0x01:
444: return Z;
445: case 0x02:
446: return !(NotANumber || Z || N);
447: case 0x03:
448: return Z || !(NotANumber || N);
449: case 0x04:
450: return N && !(NotANumber || Z);
451: case 0x05:
452: return Z || (N && !NotANumber);
453: case 0x06:
454: return !(NotANumber || Z);
455: case 0x07:
456: return !NotANumber;
457: case 0x08:
458: return NotANumber;
459: case 0x09:
460: return NotANumber || Z;
461: case 0x0a:
462: return NotANumber || !(N || Z);
463: case 0x0b:
464: return NotANumber || Z || !N;
465: case 0x0c:
466: return NotANumber || (N && !Z);
467: case 0x0d:
468: return NotANumber || Z || N;
469: case 0x0e:
470: return !Z;
471: case 0x0f:
472: return 1;
473: case 0x10:
474: return 0;
475: case 0x11:
476: return Z;
477: case 0x12:
478: return !(NotANumber || Z || N);
479: case 0x13:
480: return Z || !(NotANumber || N);
481: case 0x14:
482: return N && !(NotANumber || Z);
483: case 0x15:
484: return Z || (N && !NotANumber);
485: case 0x16:
486: return !(NotANumber || Z);
487: case 0x17:
488: return !NotANumber;
489: case 0x18:
490: return NotANumber;
491: case 0x19:
492: return NotANumber || Z;
493: case 0x1a:
494: return NotANumber || !(N || Z);
495: case 0x1b:
496: return NotANumber || Z || !N;
497: case 0x1c:
498: return NotANumber || (Z && N);
499: case 0x1d:
500: return NotANumber || Z || N;
501: case 0x1e:
502: return !Z;
503: case 0x1f:
504: return 1;
505: }
506: return -1;
1.1 root 507: }
508:
1.1.1.5 root 509: void fdbcc_opp (uae_u32 opcode, uae_u16 extra)
1.1 root 510: {
1.1.1.3 root 511: uaecptr pc = (uae_u32) m68k_getpc ();
1.1.1.5 root 512: uae_s32 disp = (uae_s32) (uae_s16) next_iword ();
1.1.1.3 root 513: int cc;
1.1 root 514:
515: #if DEBUG_FPP
1.1.1.5 root 516: printf ("fdbcc_opp at %08lx\n", m68k_getpc ());
517: fflush (stdout);
1.1 root 518: #endif
1.1.1.5 root 519: cc = fpp_cond (opcode, extra & 0x3f);
1.1.1.3 root 520: if (cc == -1) {
521: m68k_setpc (pc - 4);
522: op_illg (opcode);
523: } else if (!cc) {
524: int reg = opcode & 0x7;
525:
526: m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & ~0xffff)
1.1.1.5 root 527: | ((m68k_dreg (regs, reg) - 1) & 0xffff));
1.1.1.3 root 528: if ((m68k_dreg (regs, reg) & 0xffff) == 0xffff)
529: m68k_setpc (pc + disp);
530: }
1.1 root 531: }
532:
1.1.1.5 root 533: void fscc_opp (uae_u32 opcode, uae_u16 extra)
1.1 root 534: {
1.1.1.3 root 535: uae_u32 ad;
536: int cc;
1.1 root 537:
538: #if DEBUG_FPP
1.1.1.5 root 539: printf ("fscc_opp at %08lx\n", m68k_getpc ());
540: fflush (stdout);
1.1 root 541: #endif
1.1.1.5 root 542: cc = fpp_cond (opcode, extra & 0x3f);
1.1.1.3 root 543: if (cc == -1) {
544: m68k_setpc (m68k_getpc () - 4);
545: op_illg (opcode);
546: } else if ((opcode & 0x38) == 0) {
1.1.1.5 root 547: m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | (cc ? 0xff : 0x00);
1.1.1.3 root 548: } else {
1.1.1.5 root 549: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 550: m68k_setpc (m68k_getpc () - 4);
551: op_illg (opcode);
552: } else
1.1.1.5 root 553: put_byte (ad, cc ? 0xff : 0x00);
1.1.1.3 root 554: }
1.1 root 555: }
556:
1.1.1.5 root 557: void ftrapcc_opp (uae_u32 opcode, uaecptr oldpc)
1.1 root 558: {
1.1.1.3 root 559: int cc;
1.1 root 560:
561: #if DEBUG_FPP
1.1.1.5 root 562: printf ("ftrapcc_opp at %08lx\n", m68k_getpc ());
563: fflush (stdout);
1.1 root 564: #endif
1.1.1.5 root 565: cc = fpp_cond (opcode, opcode & 0x3f);
1.1.1.3 root 566: if (cc == -1) {
567: m68k_setpc (oldpc);
568: op_illg (opcode);
569: }
570: if (cc)
1.1.1.5 root 571: Exception (7, oldpc - 2);
1.1 root 572: }
573:
1.1.1.5 root 574: void fbcc_opp (uae_u32 opcode, uaecptr pc, uae_u32 extra)
1.1 root 575: {
1.1.1.3 root 576: int cc;
1.1 root 577:
578: #if DEBUG_FPP
1.1.1.5 root 579: printf ("fbcc_opp at %08lx\n", m68k_getpc ());
580: fflush (stdout);
1.1 root 581: #endif
1.1.1.5 root 582: cc = fpp_cond (opcode, opcode & 0x3f);
1.1.1.3 root 583: if (cc == -1) {
584: m68k_setpc (pc);
585: op_illg (opcode);
586: } else if (cc) {
587: if ((opcode & 0x40) == 0)
588: extra = (uae_s32) (uae_s16) extra;
589: m68k_setpc (pc + extra);
590: }
1.1 root 591: }
592:
1.1.1.5 root 593: void fsave_opp (uae_u32 opcode)
1.1 root 594: {
1.1.1.3 root 595: uae_u32 ad;
596: int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
597: int i;
598:
1.1 root 599: #if DEBUG_FPP
1.1.1.5 root 600: printf ("fsave_opp at %08lx\n", m68k_getpc ());
601: fflush (stdout);
1.1 root 602: #endif
1.1.1.5 root 603: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 604: m68k_setpc (m68k_getpc () - 2);
605: op_illg (opcode);
606: return;
607: }
1.1.1.5 root 608:
609: if (currprefs.cpu_level == 4) {
1.1.1.6 ! root 610: /* 4 byte 68040 IDLE frame. */
! 611: if (incr < 0) {
! 612: ad -= 4;
! 613: put_long (ad, 0x41000000);
! 614: } else {
! 615: put_long (ad, 0x41000000);
! 616: ad += 4;
! 617: }
1.1.1.3 root 618: } else {
1.1.1.5 root 619: if (incr < 0) {
620: ad -= 4;
621: put_long (ad, 0x70000000);
622: for (i = 0; i < 5; i++) {
623: ad -= 4;
624: put_long (ad, 0x00000000);
625: }
626: ad -= 4;
627: put_long (ad, 0x1f180000);
628: } else {
629: put_long (ad, 0x1f180000);
630: ad += 4;
631: for (i = 0; i < 5; i++) {
632: put_long (ad, 0x00000000);
633: ad += 4;
634: }
635: put_long (ad, 0x70000000);
1.1.1.3 root 636: ad += 4;
637: }
638: }
639: if ((opcode & 0x38) == 0x18)
640: m68k_areg (regs, opcode & 7) = ad;
641: if ((opcode & 0x38) == 0x20)
642: m68k_areg (regs, opcode & 7) = ad;
1.1 root 643: }
644:
1.1.1.5 root 645: void frestore_opp (uae_u32 opcode)
1.1 root 646: {
1.1.1.3 root 647: uae_u32 ad;
648: uae_u32 d;
649: int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
650:
1.1 root 651: #if DEBUG_FPP
1.1.1.5 root 652: printf ("frestore_opp at %08lx\n", m68k_getpc ());
653: fflush (stdout);
1.1 root 654: #endif
1.1.1.5 root 655: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 656: m68k_setpc (m68k_getpc () - 2);
657: op_illg (opcode);
658: return;
659: }
1.1.1.5 root 660: if (currprefs.cpu_level == 4) {
1.1.1.6 ! root 661: /* 68040 */
! 662: if (incr < 0) {
! 663: /* @@@ This may be wrong. */
! 664: ad -= 4;
! 665: d = get_long (ad);
! 666: if ((d & 0xff000000) != 0) { /* Not a NULL frame? */
! 667: if ((d & 0x00ff0000) == 0) { /* IDLE */
! 668: } else if ((d & 0x00ff0000) == 0x00300000) { /* UNIMP */
! 669: ad -= 44;
! 670: } else if ((d & 0x00ff0000) == 0x00600000) { /* BUSY */
! 671: ad -= 92;
! 672: }
! 673: }
! 674: } else {
! 675: d = get_long (ad);
! 676: ad += 4;
! 677: if ((d & 0xff000000) != 0) { /* Not a NULL frame? */
! 678: if ((d & 0x00ff0000) == 0) { /* IDLE */
! 679: } else if ((d & 0x00ff0000) == 0x00300000) { /* UNIMP */
! 680: ad += 44;
! 681: } else if ((d & 0x00ff0000) == 0x00600000) { /* BUSY */
! 682: ad += 92;
! 683: }
! 684: }
! 685: }
1.1.1.3 root 686: } else {
1.1.1.5 root 687: if (incr < 0) {
688: ad -= 4;
689: d = get_long (ad);
690: if ((d & 0xff000000) != 0) {
691: if ((d & 0x00ff0000) == 0x00180000)
692: ad -= 6 * 4;
693: else if ((d & 0x00ff0000) == 0x00380000)
694: ad -= 14 * 4;
695: else if ((d & 0x00ff0000) == 0x00b40000)
696: ad -= 45 * 4;
697: }
698: } else {
699: d = get_long (ad);
700: ad += 4;
701: if ((d & 0xff000000) != 0) {
702: if ((d & 0x00ff0000) == 0x00180000)
703: ad += 6 * 4;
704: else if ((d & 0x00ff0000) == 0x00380000)
705: ad += 14 * 4;
706: else if ((d & 0x00ff0000) == 0x00b40000)
707: ad += 45 * 4;
708: }
1.1.1.3 root 709: }
710: }
711: if ((opcode & 0x38) == 0x18)
712: m68k_areg (regs, opcode & 7) = ad;
713: if ((opcode & 0x38) == 0x20)
714: m68k_areg (regs, opcode & 7) = ad;
1.1 root 715: }
716:
1.1.1.5 root 717: void fpp_opp (uae_u32 opcode, uae_u16 extra)
1.1 root 718: {
1.1.1.3 root 719: int reg;
720: double src;
1.1 root 721:
722: #if DEBUG_FPP
1.1.1.5 root 723: printf ("FPP %04lx %04x at %08lx\n", opcode & 0xffff, extra & 0xffff, m68k_getpc () - 4);
724: fflush (stdout);
1.1 root 725: #endif
1.1.1.3 root 726: switch ((extra >> 13) & 0x7) {
727: case 3:
728: if (put_fp_value (regs.fp[(extra >> 7) & 7], opcode, extra) == 0) {
729: m68k_setpc (m68k_getpc () - 4);
730: op_illg (opcode);
731: }
732: return;
733: case 4:
734: case 5:
735: if ((opcode & 0x38) == 0) {
736: if (extra & 0x2000) {
737: if (extra & 0x1000)
738: m68k_dreg (regs, opcode & 7) = regs.fpcr;
739: if (extra & 0x0800)
740: m68k_dreg (regs, opcode & 7) = regs.fpsr;
741: if (extra & 0x0400)
742: m68k_dreg (regs, opcode & 7) = regs.fpiar;
743: } else {
744: if (extra & 0x1000)
745: regs.fpcr = m68k_dreg (regs, opcode & 7);
746: if (extra & 0x0800)
747: regs.fpsr = m68k_dreg (regs, opcode & 7);
748: if (extra & 0x0400)
749: regs.fpiar = m68k_dreg (regs, opcode & 7);
750: }
751: } else if ((opcode & 0x38) == 1) {
752: if (extra & 0x2000) {
753: if (extra & 0x1000)
754: m68k_areg (regs, opcode & 7) = regs.fpcr;
755: if (extra & 0x0800)
756: m68k_areg (regs, opcode & 7) = regs.fpsr;
757: if (extra & 0x0400)
758: m68k_areg (regs, opcode & 7) = regs.fpiar;
759: } else {
760: if (extra & 0x1000)
761: regs.fpcr = m68k_areg (regs, opcode & 7);
762: if (extra & 0x0800)
763: regs.fpsr = m68k_areg (regs, opcode & 7);
764: if (extra & 0x0400)
765: regs.fpiar = m68k_areg (regs, opcode & 7);
766: }
767: } else if ((opcode & 0x3f) == 0x3c) {
768: if ((extra & 0x2000) == 0) {
769: if (extra & 0x1000)
1.1.1.5 root 770: regs.fpcr = next_ilong ();
1.1.1.3 root 771: if (extra & 0x0800)
1.1.1.5 root 772: regs.fpsr = next_ilong ();
1.1.1.3 root 773: if (extra & 0x0400)
1.1.1.5 root 774: regs.fpiar = next_ilong ();
1.1.1.3 root 775: }
776: } else if (extra & 0x2000) {
777: /* FMOVEM FPP->memory */
778: uae_u32 ad;
779: int incr = 0;
780:
1.1.1.5 root 781: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 782: m68k_setpc (m68k_getpc () - 4);
783: op_illg (opcode);
1.1 root 784: return;
1.1.1.3 root 785: }
786: if ((opcode & 0x38) == 0x20) {
787: if (extra & 0x1000)
788: incr += 4;
789: if (extra & 0x0800)
790: incr += 4;
791: if (extra & 0x0400)
792: incr += 4;
793: }
794: ad -= incr;
795: if (extra & 0x1000) {
796: put_long (ad, regs.fpcr);
797: ad += 4;
798: }
799: if (extra & 0x0800) {
800: put_long (ad, regs.fpsr);
801: ad += 4;
802: }
803: if (extra & 0x0400) {
804: put_long (ad, regs.fpiar);
805: ad += 4;
806: }
807: ad -= incr;
808: if ((opcode & 0x38) == 0x18)
809: m68k_areg (regs, opcode & 7) = ad;
810: if ((opcode & 0x38) == 0x20)
811: m68k_areg (regs, opcode & 7) = ad;
812: } else {
813: /* FMOVEM memory->FPP */
814: uae_u32 ad;
815:
1.1.1.5 root 816: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 817: m68k_setpc (m68k_getpc () - 4);
818: op_illg (opcode);
1.1 root 819: return;
1.1.1.3 root 820: }
821: ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad;
822: if (extra & 0x1000) {
823: regs.fpcr = get_long (ad);
824: ad += 4;
825: }
826: if (extra & 0x0800) {
827: regs.fpsr = get_long (ad);
828: ad += 4;
829: }
830: if (extra & 0x0400) {
831: regs.fpiar = get_long (ad);
832: ad += 4;
833: }
834: if ((opcode & 0x38) == 0x18)
835: m68k_areg (regs, opcode & 7) = ad;
836: if ((opcode & 0x38) == 0x20)
837: m68k_areg (regs, opcode & 7) = ad - 12;
838: }
839: return;
840: case 6:
841: case 7:
842: {
843: uae_u32 ad, list = 0;
844: int incr = 0;
845: if (extra & 0x2000) {
846: /* FMOVEM FPP->memory */
1.1.1.5 root 847: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 848: m68k_setpc (m68k_getpc () - 4);
849: op_illg (opcode);
850: return;
851: }
852: switch ((extra >> 11) & 3) {
853: case 0: /* static pred */
854: list = extra & 0xff;
855: incr = -1;
856: break;
857: case 1: /* dynamic pred */
858: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
859: incr = -1;
860: break;
861: case 2: /* static postinc */
862: list = extra & 0xff;
863: incr = 1;
864: break;
865: case 3: /* dynamic postinc */
866: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
867: incr = 1;
868: break;
869: }
870: while (list) {
871: uae_u32 wrd1, wrd2, wrd3;
872: if (incr < 0) {
1.1.1.5 root 873: from_exten (regs.fp[fpp_movem_index2[list]], &wrd1, &wrd2, &wrd3);
1.1.1.3 root 874: ad -= 4;
875: put_long (ad, wrd3);
876: ad -= 4;
877: put_long (ad, wrd2);
878: ad -= 4;
879: put_long (ad, wrd1);
880: } else {
1.1.1.5 root 881: from_exten (regs.fp[fpp_movem_index1[list]], &wrd1, &wrd2, &wrd3);
1.1.1.3 root 882: put_long (ad, wrd1);
883: ad += 4;
884: put_long (ad, wrd2);
885: ad += 4;
886: put_long (ad, wrd3);
887: ad += 4;
1.1 root 888: }
1.1.1.3 root 889: list = fpp_movem_next[list];
890: }
891: if ((opcode & 0x38) == 0x18)
892: m68k_areg (regs, opcode & 7) = ad;
893: if ((opcode & 0x38) == 0x20)
894: m68k_areg (regs, opcode & 7) = ad;
895: } else {
896: /* FMOVEM memory->FPP */
1.1.1.5 root 897: if (get_fp_ad (opcode, &ad) == 0) {
1.1.1.3 root 898: m68k_setpc (m68k_getpc () - 4);
899: op_illg (opcode);
900: return;
901: }
902: switch ((extra >> 11) & 3) {
903: case 0: /* static pred */
904: list = extra & 0xff;
905: incr = -1;
906: break;
907: case 1: /* dynamic pred */
908: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
909: incr = -1;
910: break;
911: case 2: /* static postinc */
912: list = extra & 0xff;
913: incr = 1;
914: break;
915: case 3: /* dynamic postinc */
916: list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff;
917: incr = 1;
918: break;
919: }
920: while (list) {
921: uae_u32 wrd1, wrd2, wrd3;
922: if (incr < 0) {
923: ad -= 4;
924: wrd3 = get_long (ad);
925: ad -= 4;
926: wrd2 = get_long (ad);
927: ad -= 4;
928: wrd1 = get_long (ad);
929: regs.fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3);
930: } else {
931: wrd1 = get_long (ad);
932: ad += 4;
933: wrd2 = get_long (ad);
934: ad += 4;
935: wrd3 = get_long (ad);
936: ad += 4;
937: regs.fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3);
1.1 root 938: }
1.1.1.3 root 939: list = fpp_movem_next[list];
1.1 root 940: }
1.1.1.3 root 941: if ((opcode & 0x38) == 0x18)
942: m68k_areg (regs, opcode & 7) = ad;
943: if ((opcode & 0x38) == 0x20)
944: m68k_areg (regs, opcode & 7) = ad;
945: }
946: }
947: return;
948: case 0:
949: case 2:
950: reg = (extra >> 7) & 7;
951: if ((extra & 0xfc00) == 0x5c00) {
952: switch (extra & 0x7f) {
953: case 0x00:
1.1.1.5 root 954: regs.fp[reg] = 4.0 * atan (1.0);
1.1.1.3 root 955: break;
956: case 0x0b:
957: regs.fp[reg] = log10 (2.0);
958: break;
959: case 0x0c:
960: regs.fp[reg] = exp (1.0);
961: break;
962: case 0x0d:
963: regs.fp[reg] = log (exp (1.0)) / log (2.0);
964: break;
965: case 0x0e:
966: regs.fp[reg] = log (exp (1.0)) / log (10.0);
967: break;
968: case 0x0f:
969: regs.fp[reg] = 0.0;
970: break;
971: case 0x30:
972: regs.fp[reg] = log (2.0);
973: break;
974: case 0x31:
975: regs.fp[reg] = log (10.0);
976: break;
977: case 0x32:
978: regs.fp[reg] = 1.0e0;
979: break;
980: case 0x33:
981: regs.fp[reg] = 1.0e1;
982: break;
983: case 0x34:
984: regs.fp[reg] = 1.0e2;
985: break;
986: case 0x35:
987: regs.fp[reg] = 1.0e4;
988: break;
989: case 0x36:
990: regs.fp[reg] = 1.0e8;
991: break;
992: case 0x37:
993: regs.fp[reg] = 1.0e16;
994: break;
995: case 0x38:
996: regs.fp[reg] = 1.0e32;
997: break;
998: case 0x39:
999: regs.fp[reg] = 1.0e64;
1000: break;
1001: case 0x3a:
1002: regs.fp[reg] = 1.0e128;
1003: break;
1004: case 0x3b:
1005: regs.fp[reg] = 1.0e256;
1006: break;
1.1 root 1007: #if 0
1.1.1.3 root 1008: case 0x3c:
1009: regs.fp[reg] = 1.0e512;
1010: break;
1011: case 0x3d:
1012: regs.fp[reg] = 1.0e1024;
1013: break;
1014: case 0x3e:
1015: regs.fp[reg] = 1.0e2048;
1016: break;
1017: case 0x3f:
1018: regs.fp[reg] = 1.0e4096;
1019: break;
1.1 root 1020: #endif
1.1.1.3 root 1021: default:
1022: m68k_setpc (m68k_getpc () - 4);
1023: op_illg (opcode);
1024: break;
1025: }
1026: return;
1027: }
1028: if (get_fp_value (opcode, extra, &src) == 0) {
1029: m68k_setpc (m68k_getpc () - 4);
1030: op_illg (opcode);
1031: return;
1032: }
1033: switch (extra & 0x7f) {
1034: case 0x00: /* FMOVE */
1035: regs.fp[reg] = src;
1.1.1.5 root 1036: /* Brian King was here. <ea> to register needs FPSR updated.
1037: * See page 3-73 in Motorola 68K programmers reference manual.
1038: * %%%FPU */
1039: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1040: break;
1.1.1.4 root 1041: case 0x01: /* FINT */
1.1.1.5 root 1042: /* need to take the current rounding mode into account */
1043: switch ((regs.fpcr >> 4) & 0x3) {
1.1.1.4 root 1044: case 0:
1.1.1.5 root 1045: regs.fp[reg] = (int) (src + 0.5);
1046: break;
1.1.1.4 root 1047: case 1:
1.1.1.5 root 1048: regs.fp[reg] = (int) src;
1049: break;
1.1.1.4 root 1050: case 2:
1.1.1.5 root 1051: regs.fp[reg] = floor (src);
1052: break;
1.1.1.4 root 1053: case 3:
1.1.1.5 root 1054: regs.fp[reg] = ceil (src);
1055: break;
1056: }
1.1.1.4 root 1057: break;
1.1.1.3 root 1058: case 0x02: /* FSINH */
1059: regs.fp[reg] = sinh (src);
1.1.1.5 root 1060: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1061: break;
1062: case 0x03: /* FINTRZ */
1063: regs.fp[reg] = (int) src;
1.1.1.5 root 1064: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1065: break;
1066: case 0x04: /* FSQRT */
1067: regs.fp[reg] = sqrt (src);
1.1.1.5 root 1068: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1069: break;
1070: case 0x06: /* FLOGNP1 */
1071: regs.fp[reg] = log (src + 1.0);
1.1.1.5 root 1072: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1073: break;
1074: case 0x08: /* FETOXM1 */
1075: regs.fp[reg] = exp (src) - 1.0;
1.1.1.5 root 1076: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1077: break;
1078: case 0x09: /* FTANH */
1079: regs.fp[reg] = tanh (src);
1.1.1.5 root 1080: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1081: break;
1082: case 0x0a: /* FATAN */
1083: regs.fp[reg] = atan (src);
1.1.1.5 root 1084: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1085: break;
1086: case 0x0c: /* FASIN */
1087: regs.fp[reg] = asin (src);
1.1.1.5 root 1088: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1089: break;
1090: case 0x0d: /* FATANH */
1091: #if 1 /* The BeBox doesn't have atanh, and it isn't in the HPUX libm either */
1092: regs.fp[reg] = log ((1 + src) / (1 - src)) / 2;
1.1 root 1093: #else
1.1.1.3 root 1094: regs.fp[reg] = atanh (src);
1.1 root 1095: #endif
1.1.1.5 root 1096: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1097: break;
1098: case 0x0e: /* FSIN */
1099: regs.fp[reg] = sin (src);
1.1.1.5 root 1100: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1101: break;
1102: case 0x0f: /* FTAN */
1103: regs.fp[reg] = tan (src);
1.1.1.5 root 1104: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1105: break;
1106: case 0x10: /* FETOX */
1107: regs.fp[reg] = exp (src);
1.1.1.5 root 1108: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1109: break;
1110: case 0x11: /* FTWOTOX */
1.1.1.5 root 1111: regs.fp[reg] = pow (2.0, src);
1112: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1113: break;
1114: case 0x12: /* FTENTOX */
1.1.1.5 root 1115: regs.fp[reg] = pow (10.0, src);
1116: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1117: break;
1118: case 0x14: /* FLOGN */
1119: regs.fp[reg] = log (src);
1.1.1.5 root 1120: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1121: break;
1122: case 0x15: /* FLOG10 */
1123: regs.fp[reg] = log10 (src);
1.1.1.5 root 1124: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1125: break;
1126: case 0x16: /* FLOG2 */
1127: regs.fp[reg] = log (src) / log (2.0);
1.1.1.5 root 1128: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1129: break;
1130: case 0x18: /* FABS */
1131: regs.fp[reg] = src < 0 ? -src : src;
1.1.1.5 root 1132: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1133: break;
1134: case 0x19: /* FCOSH */
1.1.1.5 root 1135: regs.fp[reg] = cosh (src);
1136: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1137: break;
1138: case 0x1a: /* FNEG */
1139: regs.fp[reg] = -src;
1.1.1.5 root 1140: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1141: break;
1142: case 0x1c: /* FACOS */
1.1.1.5 root 1143: regs.fp[reg] = acos (src);
1144: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1145: break;
1146: case 0x1d: /* FCOS */
1.1.1.5 root 1147: regs.fp[reg] = cos (src);
1148: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1149: break;
1150: case 0x1e: /* FGETEXP */
1151: {
1152: int expon;
1153: frexp (src, &expon);
1154: regs.fp[reg] = (double) (expon - 1);
1.1.1.5 root 1155: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1156: }
1157: break;
1158: case 0x1f: /* FGETMAN */
1159: {
1160: int expon;
1161: regs.fp[reg] = frexp (src, &expon) * 2.0;
1.1.1.5 root 1162: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1163: }
1164: break;
1165: case 0x20: /* FDIV */
1166: regs.fp[reg] /= src;
1.1.1.5 root 1167: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1168: break;
1169: case 0x21: /* FMOD */
1.1.1.5 root 1170: regs.fp[reg] = regs.fp[reg] - (double) ((int) (regs.fp[reg] / src)) * src;
1171: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1172: break;
1173: case 0x22: /* FADD */
1174: regs.fp[reg] += src;
1.1.1.5 root 1175: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1176: break;
1177: case 0x23: /* FMUL */
1178: regs.fp[reg] *= src;
1.1.1.5 root 1179: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1180: break;
1181: case 0x24: /* FSGLDIV */
1182: regs.fp[reg] /= src;
1.1.1.5 root 1183: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1184: break;
1185: case 0x25: /* FREM */
1.1.1.5 root 1186: regs.fp[reg] = regs.fp[reg] - (double) ((int) (regs.fp[reg] / src + 0.5)) * src;
1187: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1188: break;
1189: case 0x26: /* FSCALE */
1190: regs.fp[reg] *= exp (log (2.0) * src);
1.1.1.5 root 1191: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1192: break;
1193: case 0x27: /* FSGLMUL */
1194: regs.fp[reg] *= src;
1.1.1.5 root 1195: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1196: break;
1197: case 0x28: /* FSUB */
1198: regs.fp[reg] -= src;
1.1.1.5 root 1199: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1200: break;
1201: case 0x30: /* FSINCOS */
1202: case 0x31:
1203: case 0x32:
1204: case 0x33:
1205: case 0x34:
1206: case 0x35:
1207: case 0x36:
1208: case 0x37:
1209: regs.fp[reg] = sin (src);
1.1.1.5 root 1210: regs.fp[extra & 7] = cos (src);
1211: MAKE_FPSR (regs.fpsr, regs.fp[reg]);
1.1.1.3 root 1212: break;
1213: case 0x38: /* FCMP */
1214: {
1215: double tmp = regs.fp[reg] - src;
1.1.1.5 root 1216: regs.fpsr = (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
1.1.1.3 root 1217: }
1218: break;
1219: case 0x3a: /* FTST */
1.1.1.5 root 1220: regs.fpsr = (src == 0 ? 0x4000000 : 0) | (src < 0 ? 0x8000000 : 0);
1.1.1.3 root 1221: break;
1222: default:
1223: m68k_setpc (m68k_getpc () - 4);
1224: op_illg (opcode);
1225: break;
1226: }
1227: return;
1228: }
1229: m68k_setpc (m68k_getpc () - 4);
1230: op_illg (opcode);
1.1 root 1231: }
1232:
1233: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.