2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // MACH.C - Code Generation
4 // Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source utilised with the kind permission of Landon Dyer
23 int movep = 0; // Global flag to indicate we're generating a movep instruction
25 // Common error messages
26 char range_error[] = "expression out of range";
27 char abs_error[] = "illegal absolute expression";
28 char seg_error[] = "bad (section) expression";
29 char rel_error[] = "illegal relative address";
30 char siz_error[] = "bad size specified";
31 char undef_error[] = "undefined expression";
32 char fwd_error[] = "forward or undefined expression";
33 char unsupport[] = "unsupported for selected CPU";
35 extern int ea0gen(WORD);
36 extern int ea1gen(WORD);
39 // Include code tables
41 // { (WORD)-1, (unsigned long)-1L, (unsigned long)-1L, 0x0000, 0, m_badmode }, // 0
42 { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0
44 { 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry
47 // Register number << 9
49 0, 1 << 9, 2 << 9, 3 << 9, 4 << 9, 5 << 9, 6 << 9, 7 << 9
52 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
56 1<<6, (WORD)-1, // SIZW, n/a
57 2<<6, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
61 // Byte/word/long size for MOVE instrs
65 0x3000, (WORD)-1, // Word
66 0x2000, (WORD)-1, (WORD)-1, (WORD)-1, // Long
70 // Word/long size (0=.w, 1=.l) in bit 8
74 0, (WORD)-1, // SIZW, n/a
75 1<<8, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
79 // Byte/Word/long size (0=.w, 1=.l) in bit 9
83 1<<9, (WORD)-1, // Word
84 1<<10, (WORD)-1, (WORD)-1, (WORD)-1, // Long
88 // Addressing mode in bits 6..11 (register/mode fields are reversed)
90 00000, 01000, 02000, 03000, 04000, 05000, 06000, 07000,
91 00100, 01100, 02100, 03100, 04100, 05100, 06100, 07100,
92 00200, 01200, 02200, 03200, 04200, 05200, 06200, 07200,
93 00300, 01300, 02300, 03300, 04300, 05300, 06300, 07300,
94 00400, 01400, 02400, 03400, 04400, 05400, 06400, 07400,
95 00500, 01500, 02500, 03500, 04500, 05500, 06500, 07500,
96 00600, 01600, 02600, 03600, 04600, 05600, 06600, 07600,
97 00700, 01700, 02700, 03700, 04700, 05700, 06700, 07700
100 // Control registers lookup table
102 // MC68010/MC68020/MC68030/MC68040/CPU32
103 0x000, // Source Function Code(SFC)
104 0x001, // Destination Function Code(DFC)
105 0x800, // User Stack Pointer(USP)
106 0x801, // Vector Base Register(VBR)
107 // MC68020 / MC68030 / MC68040
108 0x002, // Cache Control Register(CACR)
109 0x802, // Cache Address Register(CAAR) (020/030 only)
110 0x803, // Master Stack Pointer(MSP)
111 0x804, // Interrupt Stack Pointer(ISP)
112 // MC68040 / MC68LC040
113 0x003, // MMU Translation Control Register(TC)
114 0x004, // Instruction Transparent Translation Register 0 (ITT0)
115 0x005, // Instruction Transparent Translation Register 1 (ITT1)
116 0x006, // Data Transparent Translation Register 0 (DTT0)
117 0x007, // Data Transparent Translation Register 1 (DTT1)
118 0x805, // MMU Status Register(MMUSR)
119 0x806, // User Root Pointer(URP)
120 0x807, // Supervisor Root Pointer(SRP)
122 0x004, // Instruction Access Control Register 0 (IACR0)
123 0x005, // Instruction Access Control Register 1 (IACR1)
124 0x006, // Data Access Control Register 0 (DACR1)
125 0x007, // Data Access Control Register 1 (DACR1)
127 0xfff // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
131 int m_unimp(WORD unused1, WORD unused2)
133 return (int)error("unimplemented mnemonic");
137 //int m_badmode(void)
138 int m_badmode(WORD unused1, WORD unused2)
140 return (int)error("inappropriate addressing mode");
144 int m_self(WORD inst, WORD usused)
152 // Do one EA in bits 0..5
154 // Bits in `inst' have the following meaning:
156 // Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits
159 // If bit one is set, the OTHER ea (the one that wasn't generated by bit zero)
160 // is generated after the instruction. Regardless of bit 0's value, ea0 is
161 // always deposited in memory before ea1.
163 // If bit two is set, standard size bits are set in the instr in bits 6 and 7.
165 // If bit four is set, bit three specifies which eaXreg to place in bits 9..11
168 int m_ea(WORD inst, WORD siz)
170 WORD flg = inst; // Save flag bits
171 inst &= ~0x3F; // Clobber flag bits in instr
173 // Install "standard" instr size bits
179 // OR-in register number
181 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
183 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
189 inst |= am1 | a1reg; // Get ea1 into instr
190 D_word(inst); // Deposit instr
192 // Generate ea0 if requested
196 ea1gen(siz); // Generate ea1
201 inst |= am0 | a0reg; // Get ea0 into instr
202 D_word(inst); // Deposit instr
203 ea0gen(siz); // Generate ea0
205 // Generate ea1 if requested
214 // Check if lea x(an),an can be optimised to
215 // addq.w #x,an - otherwise fall back to m_ea.
217 int m_lea(WORD inst, WORD siz)
219 if (optim_flags[OPT_LEA_ADDQ])
220 if (am0==ADISP && a0reg==a1reg && (a0exattr & DEFINED))
221 if (a0exval>0 && a0exval<=8)
223 inst=B16(01010000,01001000)|((a0exval&7)<<9)|(a0reg);
225 warn("lea size(An),An converted to addq #size,An");
229 return m_ea(inst,siz);
232 int m_ea030(WORD inst, WORD siz)
236 WORD flg = inst; // Save flag bits
237 inst &= ~0x3F; // Clobber flag bits in instr
239 // Install "standard" instr size bits
245 // OR-in register number
248 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
252 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
259 inst |= am1 | a1reg; // Get ea1 into instr
260 D_word(inst); // Deposit instr
262 // Generate ea0 if requested
266 ea1gen(siz); // Generate ea1
271 //inst |= am0 | a0reg; // Get ea0 into instr
273 //We get here if we're doing 020+ addressing and an address register is used.
274 //For example, something like "tst a0". A bit of a corner case, so kludge it
276 else if (am0 == PCDISP)
277 //Another corner case (possibly!), so kludge ahoy
278 inst |= am0; // Get ea0 into instr
279 else if (am0 == IMMED)
280 inst |= am0 | a0reg; // Get ea0 into instr
281 else if (am0 == AM_CCR)
283 else if (am0 == AIND)
286 inst |= a0reg; // Get ea0 into instr
287 D_word(inst); // Deposit instr
288 ea0gen(siz); // Generate ea0
290 // Generate ea1 if requested
300 // Dx,Dy nnnnXXXnssnnnYYY If bit 0 of `inst' is set, install size bits in bits
303 int m_abcd(WORD inst, WORD siz)
312 inst |= a0reg | reg_9[a1reg];
322 int m_adda(WORD inst, WORD siz)
324 inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
326 ea0gen(siz); // Generate EA
333 // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr.
334 // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr.
336 int m_reg(WORD inst, WORD siz)
343 // Install other register (9..11)
344 inst |= reg_9[a1reg];
346 inst &= ~7; // Clear off crufty bits
347 inst |= a0reg; // Install first register
357 int m_imm(WORD inst, WORD siz)
369 int m_imm8(WORD inst, WORD siz)
382 int m_shr(WORD inst, WORD siz)
384 inst |= reg_9[a0reg] | a1reg | siz_6[siz];
394 int m_shi(WORD inst, WORD siz)
396 inst |= a1reg | siz_6[siz];
398 if (a0exattr & DEFINED)
401 return error(range_error);
403 inst |= (a0exval & 7) << 9;
408 AddFixup(FU_QUICK, sloc, a0expr);
417 // {bset, btst, bchg, bclr} -- #immed,ea -- Dn,ea
419 int m_bitop(WORD inst, WORD siz)
421 // Enforce instruction sizes
423 { // X,Dn must be .n or .l
424 if (siz & (SIZB | SIZW))
425 return error(siz_error);
427 else if (siz & (SIZW | SIZL)) // X,ea must be .n or .b
428 return error(siz_error);
430 // Construct instr and EAs
436 ea0gen(SIZB); // Immediate bit number
440 inst |= reg_9[a0reg];
451 int m_dbra(WORD inst, WORD siz)
459 if (a1exattr & DEFINED)
461 if ((a1exattr & TDB) != cursect)
462 return error(rel_error);
466 if (v + 0x8000 > 0x10000)
467 return error(range_error);
473 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
484 int m_exg(WORD inst, WORD siz)
490 if (am0 == DREG && am1 == DREG)
492 else if (am0 == AREG && am1 == AREG)
498 m = a1reg; // Get AREG into a1reg
506 inst |= m | reg_9[a0reg] | a1reg;
516 int m_link(WORD inst, WORD siz)
524 inst &= ~((3 << 9)|(1<<6)|(1<<4));
534 WORD extra_addressing[16]=
537 0, //0101 ([bd,An],Xn,od)
538 0x180, //0102 ([bc,An,Xn],od) (111 110 110 111)
540 0, //0104 ([bd,PC],Xn,od)
541 0, //0105 ([bc,PC,Xn],od)
556 // Handle MOVE <C_ALL> <C_ALTDATA>
557 // MOVE <C_ALL> <M_AREG>
559 // Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
561 int m_move(WORD inst, WORD size)
563 // Cast the passed in value to an int
566 // Try to optimize to MOVEQ
567 if (optim_flags[OPT_MOVEL_MOVEQ] && siz == SIZL && am0 == IMMED && am1 == DREG
568 && (a0exattr & (TDB|DEFINED)) == DEFINED && a0exval + 0x80 < 0x100)
570 m_moveq((WORD)0x7000, (WORD)0);
573 warn("move.l #size,dx converted to moveq");
577 if (am0<ABASE && am1<ABASE) //68000 modes
579 inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
587 ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
591 inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0-ABASE];
607 // Handle MOVE <C_ALL030> <C_ALTDATA>
608 // MOVE <C_ALL030> <M_AREG>
610 int m_move30(WORD inst, WORD size)
612 // Cast the passed in value to an int
615 /*if (am0<ABASE && am1<ABASE) //68000 modes
617 inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
625 | 0x8000); // Tell ea1gen we're move ea,ea
629 inst |= siz_12[siz] | reg_9[a1reg&7] | a0reg | extra_addressing[am0-ABASE];
645 // move USP,An -- move An,USP
647 int m_usp(WORD inst, WORD siz)
652 inst |= a1reg; // USP, An
654 inst |= a0reg; // An, USP
665 int m_moveq(WORD inst, WORD siz)
669 // Arrange for future fixup
670 if (!(a0exattr & DEFINED))
672 AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
675 else if (a0exval + 0x100 >= 0x200)
676 return error(range_error);
678 inst |= reg_9[a1reg] | (a0exval & 0xFF);
685 // movep Dn, disp(An) -- movep disp(An), Dn
687 int m_movep(WORD inst, WORD siz)
689 movep = 1; // Tell ea0gen to lay off the 0(a0) optimisations on this one
695 inst |= reg_9[a0reg] | a1reg;
705 inst |= reg_9[a1reg] | a0reg;
722 int m_br(WORD inst, WORD siz)
726 if (a0exattr & DEFINED)
728 if ((a0exattr & TDB) != cursect)
730 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
731 return error(rel_error);
734 v = a0exval - (sloc + 2);
736 // Optimize branch instr. size
739 if (optim_flags[OPT_BSR_BCC_S] && v != 0 && v + 0x80 < 0x100)
745 warn("Bcc.w/BSR.w converted to .s");
751 if (v + 0x8000 > 0x10000)
752 return error(range_error);
760 if (siz == SIZB || siz == SIZS)
762 if (v + 0x80 >= 0x100)
763 return error(range_error);
770 if (v + 0x8000 >= 0x10000)
771 return error(range_error);
779 else if (siz == SIZN)
782 if (siz == SIZB || siz == SIZS)
785 AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
793 AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
804 int m_addq(WORD inst, WORD siz)
806 inst |= siz_6[siz] | am1 | a1reg;
808 if (a0exattr & DEFINED)
810 if (a0exval > 8 || a0exval == 0) // Range in 1..8
811 return error(range_error);
813 inst |= (a0exval & 7) << 9;
818 AddFixup(FU_QUICK, sloc, a0expr);
831 int m_trap(WORD inst, WORD siz)
835 if (a0exattr & DEFINED)
838 return error(abs_error);
841 return error(range_error);
847 return error(undef_error);
854 // movem <rlist>,ea -- movem ea,<rlist>
856 int m_movem(WORD inst, WORD siz)
864 return error("bad size suffix");
871 // Handle #<expr>, ea
874 if (abs_expr(&eval) != OK)
877 if (eval >= 0x10000L)
878 return error(range_error);
884 if (*tok >= KW_D0 && *tok <= KW_A7)
887 if (reglist(&rmask) < 0)
892 return error("missing comma");
899 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
900 return error("invalid addressing mode");
902 // If APREDEC, reverse register mask
908 for(i=0x8000; i; i>>=1, w>>=1)
909 rmask = (WORD)((rmask << 1) | w & 1);
918 inst |= 0x0400 | am0 | a0reg;
921 return error("missing comma");
924 return error("missing register list");
931 if (abs_expr(&eval) != OK)
935 return error(range_error);
939 else if (reglist(&rmask) < 0)
942 if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
943 return error("invalid addressing mode");
955 // CLR.x An ==> SUBA.x An,An
957 int m_clra(WORD inst, WORD siz)
959 inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
965 ////////////////////////////////////////
967 // 68020/30/40 instructions
969 ////////////////////////////////////////
974 int m_br30(WORD inst, WORD siz)
978 if (a0exattr & DEFINED)
980 if ((a0exattr & TDB) != cursect)
982 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
983 return error(rel_error);
986 v = a0exval - (sloc + 2);
996 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1003 // bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
1004 // (68020, 68030, 68040)
1006 int m_bfop(WORD inst, WORD siz)
1008 //TODO: is this needed or can we put that in the mask in 68ktab???
1009 if (am0 == AREG || am0== APOSTINC || am0 == APREDEC || am0 == IMMED|| am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE || am0 == PCBASE || am0 == PCMPOST || am0 == PCMPRE)
1010 return m_badmode(inst, siz);
1012 //First instruction word - just the opcode and first EA
1013 //Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
1016 D_word((inst|am0|a0reg|am1|a1reg));
1017 ea0gen(siz); // Generate EA
1019 //Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
1020 inst = bfparam1 | bfparam2;
1022 inst |= a1reg << 12;
1024 inst |= a0reg << 12;
1031 // bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
1033 int m_bkpt(WORD inst, WORD siz)
1037 if (a0exattr & DEFINED)
1040 return error(abs_error);
1043 return error(range_error);
1049 return error(undef_error);
1057 int m_callm(WORD inst, WORD siz)
1064 if (a0exattr & DEFINED)
1067 return error(abs_error);
1070 return error(range_error);
1076 return error(undef_error);
1085 // cas (68020, 68030, 68040)
1087 int m_cas(WORD inst, WORD siz)
1093 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1094 return error(unsupport);
1109 return error("bad size suffix");
1114 if ((*tok < KW_D0) && (*tok > KW_D7))
1115 return error("CAS accepts only data registers");
1116 inst2 = (*tok++) & 7;
1119 return error("missing comma");
1122 if ((*tok < KW_D0) && (*tok > KW_D7))
1123 return error("CAS accepts only data registers");
1124 inst2 |= ((*tok++) & 7)<<6;
1127 return error("missing comma");
1130 if ((modes=amode(1)) < 0)
1134 return error("too many ea fields");
1137 return error("extra (unexpected) text found");
1139 // Reject invalud ea modes
1140 amsk = amsktab[am0];
1141 if (amsk&(M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE) == 0)
1142 return error("unsupported addressing mode");
1144 inst |= am0 | a0reg;
1153 // cas2 (68020, 68030, 68040)
1155 int m_cas2(WORD inst, WORD siz)
1160 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1161 return error(unsupport);
1176 return error("bad size suffix");
1181 if ((*tok < KW_D0) && (*tok > KW_D7))
1182 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1183 inst2 = (*tok++) & 7;
1186 return error("missing colon");
1189 if ((*tok < KW_D0) && (*tok > KW_D7))
1190 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1191 inst3 = (*tok++) & 7;
1194 return error("missing comma");
1197 if ((*tok < KW_D0) && (*tok > KW_D7))
1198 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1199 inst2 |= ((*tok++) & 7)<<6;
1202 return error("missing colon");
1205 if ((*tok < KW_D0) && (*tok > KW_D7))
1206 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1207 inst3 |= ((*tok++) & 7) << 6;
1210 return error("missing comma");
1214 return error("missing (");
1215 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1216 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1217 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1218 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1220 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1223 return error("missing (");
1226 return error("missing colon");
1230 return error("missing (");
1231 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1232 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1233 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1234 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1236 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1239 return error("missing (");
1242 return error("extra (unexpected) text found");
1252 // cmp2 (68020, 68030, 68040, CPU32)
1254 int m_cmp2(WORD inst, WORD siz)
1256 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1257 return error(unsupport);
1273 WORD flg = inst; // Save flag bits
1274 inst &= ~0x3F; // Clobber flag bits in instr
1276 // Install "standard" instr size bits
1282 // OR-in register number
1284 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1286 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1292 inst |= am1 | a1reg; // Get ea1 into instr
1293 D_word(inst); // Deposit instr
1295 // Generate ea0 if requested
1299 ea1gen(siz); // Generate ea1
1304 inst |= am0 | a0reg; // Get ea0 into instr
1305 D_word(inst); // Deposit instr
1306 ea0gen(siz); // Generate ea0
1308 // Generate ea1 if requested
1313 // If we're called from chk2 then bit 11 of size will be set.
1314 // This is just a dumb mechanism to pass this, required by the extension word.
1315 // (you might have noticed the siz&15 thing above!)
1316 inst = (a1reg << 12)|(siz&(1<<11));
1326 // chk2 (68020, 68030, 68040, CPU32)
1328 int m_chk2(WORD inst, WORD siz)
1330 return m_cmp2(inst, siz | (1 << 11));
1334 // cpbcc(68020, 68030)
1336 int m_cpbr(WORD inst, WORD siz)
1338 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1339 return error(unsupport);
1343 if (a0exattr & DEFINED)
1345 if ((a0exattr & TDB) != cursect)
1347 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
1348 return error(rel_error);
1351 v = a0exval - (sloc + 2);
1353 // Optimize branch instr. size
1356 if (v != 0 && v + 0x8000 < 0x10000)
1360 WARNING(check what s "optional coprocessor-defined extension words!")
1367 if (v + 0x8000 >= 0x10000)
1368 return error(range_error);
1370 WARNING(check what s "optional coprocessor-defined extension words!")
1376 else if (siz == SIZN)
1383 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1391 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1399 // cpdbcc(68020, 68030)
1401 int m_cpdbr(WORD inst, WORD siz)
1403 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1404 return error(unsupport);
1406 return error("Not implemented yet.");
1414 int m_divs(WORD inst, WORD siz)
1416 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1417 return error(unsupport);
1419 WORD flg = inst; // Save flag bits
1420 inst &= ~0x3F; // Clobber flag bits in instr
1422 // Install "standard" instr size bits
1428 // OR-in register number
1430 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1432 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1438 inst |= am1 | a1reg; // Get ea1 into instr
1439 D_word(inst); // Deposit instr
1441 // Generate ea0 if requested
1445 ea1gen(siz); // Generate ea1
1450 inst |= am0 | a0reg; // Get ea0 into instr
1451 D_word(inst); // Deposit instr
1452 ea0gen(siz); // Generate ea0
1454 // Generate ea1 if requested
1461 inst=a1reg+(a2reg<<12)+(1<<11);
1469 int m_muls(WORD inst, WORD siz)
1471 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1472 return error(unsupport);
1474 WORD flg = inst; // Save flag bits
1475 inst &= ~0x3F; // Clobber flag bits in instr
1477 // Install "standard" instr size bits
1483 // OR-in register number
1485 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1487 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1493 inst |= am1 | a1reg; // Get ea1 into instr
1494 D_word(inst); // Deposit instr
1496 // Generate ea0 if requested
1500 ea1gen(siz); // Generate ea1
1505 inst |= am0 | a0reg; // Get ea0 into instr
1506 D_word(inst); // Deposit instr
1507 ea0gen(siz); // Generate ea0
1509 // Generate ea1 if requested
1516 inst=a1reg+(a2reg<<12)+(1<<11);
1517 inst|=mulmode; // add size bit
1525 int m_divu(WORD inst, WORD siz)
1527 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1528 return error(unsupport);
1530 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1532 WORD flg = inst; // Save flag bits
1533 inst &= ~0x3F; // Clobber flag bits in instr
1535 // Install "standard" instr size bits
1541 // OR-in register number
1543 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1545 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1551 inst |= am1 | a1reg; // Get ea1 into instr
1552 D_word(inst); // Deposit instr
1554 // Generate ea0 if requested
1558 ea1gen(siz); // Generate ea1
1563 inst |= am0 | a0reg; // Get ea0 into instr
1564 D_word(inst); // Deposit instr
1565 ea0gen(siz); // Generate ea0
1567 // Generate ea1 if requested
1574 inst=a1reg+(a2reg<<12);
1582 int m_mulu(WORD inst, WORD siz)
1584 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1585 return error(unsupport);
1587 WORD flg = inst; // Save flag bits
1588 inst &= ~0x3F; // Clobber flag bits in instr
1590 // Install "standard" instr size bits
1596 // OR-in register number
1598 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1600 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1606 inst |= am1 | a1reg; // Get ea1 into instr
1607 D_word(inst); // Deposit instr
1609 // Generate ea0 if requested
1613 ea1gen(siz); // Generate ea1
1618 inst |= am0 | a0reg; // Get ea0 into instr
1619 D_word(inst); // Deposit instr
1620 ea0gen(siz); // Generate ea0
1622 // Generate ea1 if requested
1629 inst=a1reg+(a2reg<<12);
1630 inst|=mulmode; // add size bit
1639 int m_divsl(WORD inst, WORD siz)
1641 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1642 return error(unsupport);
1644 WORD flg = inst; // Save flag bits
1645 inst &= ~0x3F; // Clobber flag bits in instr
1647 // Install "standard" instr size bits
1653 // OR-in register number
1655 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1657 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1663 inst |= am1 | a1reg; // Get ea1 into instr
1664 D_word(inst); // Deposit instr
1666 // Generate ea0 if requested
1670 ea1gen(siz); // Generate ea1
1675 inst |= am0 | a0reg; // Get ea0 into instr
1676 D_word(inst); // Deposit instr
1677 ea0gen(siz); // Generate ea0
1679 // Generate ea1 if requested
1686 inst=a1reg+(a2reg<<12)+(1<<11)+(1<<10);
1695 int m_divul(WORD inst, WORD siz)
1697 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1698 return error(unsupport);
1700 WORD flg = inst; // Save flag bits
1701 inst &= ~0x3F; // Clobber flag bits in instr
1703 // Install "standard" instr size bits
1709 // OR-in register number
1711 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1713 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1719 inst |= am1 | a1reg; // Get ea1 into instr
1720 D_word(inst); // Deposit instr
1722 // Generate ea0 if requested
1726 ea1gen(siz); // Generate ea1
1731 inst |= am0 | a0reg; // Get ea0 into instr
1732 D_word(inst); // Deposit instr
1733 ea0gen(siz); // Generate ea0
1735 // Generate ea1 if requested
1742 inst=a1reg+(a2reg<<12)+(1<<10);
1749 // move16 (ax)+,(ay)+
1751 int m_move16a(WORD inst, WORD siz)
1753 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
1754 return error(unsupport);
1758 inst=(1<<15)+(a1reg<<12);
1765 // move16 with absolute address
1767 int m_move16b(WORD inst, WORD siz)
1769 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
1770 return error(unsupport);
1778 return error("Wasn't this suppose to call m_move16a???");
1781 //move16 (ax)+,(xxx).L
1788 //move16 (xxx).L,(ax)+
1794 //move16 (xxx).L,(ax)
1800 //move16 (ax),(xxx).L
1812 int m_pack(WORD inst, WORD siz)
1814 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1815 return error(unsupport);
1817 WARNING(Parsing stuff by hand here might be better)
1819 //if (am0==DREG && am1==DREG)
1821 // inst|=(1<<3)+(a0reg<<9)+(a1reg);
1823 //else if (am0==APREDEC && am1==APREDEC)
1825 // inst|=(a0reg<<9)+(a1reg);
1828 // return error("Only allowed combinations for pack/unpack are -(ax),-(ay) and dx,dy.");
1838 int m_rtm(WORD inst, WORD siz)
1851 return error("rtm only allows data or address registers.");
1861 int m_rtd(WORD inst, WORD siz)
1865 if (a0exattr & DEFINED)
1868 return error(abs_error);
1870 if (a0exval+0x8000 <= 0x7fff)
1871 return error(range_error);
1877 return error(undef_error);
1886 int m_trapcc(WORD inst, WORD siz)
1894 else if (am0==IMMED)
1898 if (a0exval<0x10000)
1906 return error("Immediate value too big");
1917 return error("Invalid parameter for trapcc");
1925 int m_cinv(WORD inst, WORD siz)
1929 WARNING("cinvl ,(an) / cinvp ,(an) / cinva should work!")
1931 inst|=(0<<6)|(a1reg);
1932 else if (am0==KW_IC40)
1933 inst|=(2<<6)|(a1reg);
1934 else if (am0==KW_DC40)
1935 inst|=(1<<6)|(a1reg);
1936 else if (am0==KW_BC40)
1937 inst|=(3<<6)|(a1reg);
1945 // cpRESTORE (68020, 68030)
1947 int m_cprest(WORD inst, WORD siz)
1949 if (activecpu & !(CPU_68020|CPU_68030))
1950 return error(unsupport);
1960 // movec (68010, 68020, 68030, 68040, CPU32)
1962 int m_movec(WORD inst, WORD siz)
1966 if (am0 == DREG || am0 == AREG)
1973 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
1978 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
1988 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
1993 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2002 // moves (68010, 68020, 68030, 68040, CPU32)
2004 int m_moves(WORD inst, WORD siz)
2006 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2007 return error(unsupport);
2013 else if (siz == SIZL)
2024 inst |= am1 | a1reg;
2026 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2029 else if (am0 == AREG)
2031 inst |= am1 | a1reg;
2033 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2040 inst |= am0 | a0reg;
2042 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2047 inst |= am0 | a0reg;
2049 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2061 int m_pbcc(WORD inst, WORD siz)
2064 return error("Not implemented yet.");
2070 int m_pflusha(WORD inst, WORD siz)
2075 inst=((1 << 13) | (1 << 10)) | (0 << 5) | 0;
2081 // pflush (68030, 68040, 68060)
2083 int m_pflush(WORD inst, WORD siz)
2085 if (activecpu == CPU_68030)
2088 D_word(((1 << 13) | (1 << 10)) | (0 << 5) | 0);
2090 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2095 return error(unsupport);
2103 int m_pflushr(WORD inst, WORD siz)
2107 WORD flg = inst; // Save flag bits
2108 inst &= ~0x3F; // Clobber flag bits in instr
2110 // Install "standard" instr size bits
2116 // OR-in register number
2118 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2120 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2126 inst |= am1 | a1reg; // Get ea1 into instr
2127 D_word(inst); // Deposit instr
2129 // Generate ea0 if requested
2133 ea1gen(siz); // Generate ea1
2138 inst |= am0 | a0reg; // Get ea0 into instr
2139 D_word(inst); // Deposit instr
2140 ea0gen(siz); // Generate ea0
2142 // Generate ea1 if requested
2147 D_word(B16(10100000, 00000000));
2151 // ploadr, ploadw (68030)
2153 int m_pload(WORD inst, WORD siz)
2156 return error("Not implemented yet.");
2162 int m_pmove(WORD inst, WORD siz)
2168 inst2 = inst&(1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2169 inst &= ~(1 << 8); //And mask it out
2175 else if (am1 == CREG)
2181 return error("pmove sez: Wut?");
2183 if ((reg == KW_URP-KW_SFC || reg == KW_SRP-KW_SFC) && ((siz != SIZD) && (siz!=SIZN)))
2184 return error(siz_error);
2185 if ((reg == KW_TC-KW_SFC || reg == KW_TT0-KW_SFC || reg == KW_TT1-KW_SFC) && ((siz != SIZL)&&(siz!=SIZN)))
2186 return error(siz_error);
2187 if ((reg == KW_MMUSR-KW_SFC) && ((siz != SIZW)&&(siz!=SIZN)))
2188 return error(siz_error);
2190 WARNING(Not all addressing modes are legal here!)
2197 else if (am1 == CREG)
2206 case (KW_URP-KW_SFC):
2207 inst2 |= (3 << 10) + (2 << 13); break;
2208 case (KW_SRP-KW_SFC):
2209 inst2 |= (2 << 10) + (2 << 13); break;
2210 case (KW_TC-KW_SFC):
2211 inst2 |= (0 << 10) + (2 << 13); break;
2212 case (KW_TT0-KW_SFC):
2213 inst2 |= (2 << 10) + (0 << 13); break;
2214 case (KW_TT1-KW_SFC):
2215 inst2 |= (3 << 10) + (0 << 13); break;
2216 case (KW_MMUSR-KW_SFC):
2217 inst2 |= (3 << 10) + (3 << 13); break;
2218 case (KW_CRP-KW_SFC) : //68851 only
2219 inst2 |= (3 << 10) + (2 << 13); break;
2230 int m_pmovefd(WORD inst, WORD siz)
2234 return m_pmove(inst|(1<<8),siz);
2240 int m_ptrapbs(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000000)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000000)); D_long(a0exval); } return OK; }
2241 int m_ptrapbc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000001)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000001)); D_long(a0exval); } return OK; }
2242 int m_ptrapls(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000010)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000010)); D_long(a0exval); } return OK; }
2243 int m_ptraplc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000011)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000011)); D_long(a0exval); } return OK; }
2244 int m_ptrapss(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000100)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000100)); D_long(a0exval); } return OK; }
2245 int m_ptrapsc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000101)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000101)); D_long(a0exval); } return OK; }
2246 int m_ptrapas(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000110)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000110)); D_long(a0exval); } return OK; }
2247 int m_ptrapac(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00000111)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00000111)); D_long(a0exval); } return OK; }
2248 int m_ptrapws(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001000)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001000)); D_long(a0exval); } return OK; }
2249 int m_ptrapwc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001001)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001001)); D_long(a0exval); } return OK; }
2250 int m_ptrapis(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001010)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001010)); D_long(a0exval); } return OK; }
2251 int m_ptrapic(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001011)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001011)); D_long(a0exval); } return OK; }
2252 int m_ptrapgc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001100)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001100)); D_long(a0exval); } return OK; }
2253 int m_ptrapgs(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001101)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001101)); D_long(a0exval); } return OK; }
2254 int m_ptrapcs(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001110)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001110)); D_long(a0exval); } return OK; }
2255 int m_ptrapcc(WORD inst, WORD siz) { CHECKNO20; if (siz == SIZW) { D_word(inst); D_word(B8(00001111)); D_word(a0exval); } else { inst |= 3; D_word(inst); D_word(B8(00001111)); D_long(a0exval); } return OK; }
2256 int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2257 int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2258 int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2259 int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2260 int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2261 int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2262 int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2263 int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2264 int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2265 int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2266 int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2267 int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2268 int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2269 int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2270 int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2271 int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2274 // ptestr, ptestw (68030)
2276 int m_ptest(WORD inst, WORD siz)
2279 if (activecpu == CPU_68030)
2280 return error("Not implemented yet.");
2281 else if (activecpu == CPU_68040)
2282 return error("Not implemented yet.");
2286 #define FPU_NOWARN 0
2287 #define FPU_P_EMUL 1
2288 #define FPU_P2_EMU 2
2292 // Generate a FPU opcode
2294 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2296 if (am0<AM_NONE) // Check first operand for ea or fp - is this right?
2298 inst|=(1<<9); // Bolt on FPU id
2303 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2306 case SIZB: inst |= (6<<10); break;
2307 case SIZW: inst |= (4<<10); break;
2308 case SIZL: inst |= (0<<10); break;
2310 case SIZS: inst |= (1<<10); break;
2311 case SIZD: inst |= (5<<10); break;
2312 case SIZX: inst |= (2<<10); break;
2317 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2320 default: return error("Something bad happened, possibly, in gen_fpu."); break;
2322 inst |= (a1reg << 7);
2329 inst|=(1<<9); //Bolt on FPU id
2333 inst |= (a1reg << 7);
2337 if (emul&FPU_FPSP && activefpu==FPU_68040)
2338 warn("Instruction is emulated in 68040");
2344 // fabs, fsabs, fdabs (6888X, 68040)
2346 int m_fabs(WORD inst, WORD siz)
2348 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2350 int m_fsabs(WORD inst, WORD siz)
2352 if (activefpu == FPU_68040)
2353 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2355 return error("Unsupported in current FPU");
2357 int m_fdabs(WORD inst, WORD siz)
2359 if (activefpu == FPU_68040)
2360 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2362 return error("Unsupported in current FPU");
2366 // facos (6888X, 68040FPSP)
2368 int m_facos(WORD inst, WORD siz)
2370 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
2374 // fadd (6888X, 68040FPSP)
2376 int m_fadd(WORD inst, WORD siz)
2378 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
2380 int m_fsadd(WORD inst, WORD siz)
2382 if (activefpu == FPU_68040)
2383 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
2385 return error("Unsupported in current FPU");
2387 int m_fdadd(WORD inst, WORD siz)
2389 if (activefpu == FPU_68040)
2390 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
2392 return error("Unsupported in current FPU");
2396 // fasin (6888X, 68040FPSP)f
2398 int m_fasin(WORD inst, WORD siz)
2400 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
2404 // fatan (6888X, 68040FPSP)
2406 int m_fatan(WORD inst, WORD siz)
2408 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
2412 // fatanh (6888X, 68040FPSP)
2414 int m_fatanh(WORD inst, WORD siz)
2416 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
2420 // fcmp (6888X, 68040)
2422 int m_fcmp(WORD inst, WORD siz)
2424 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
2428 // fcos (6888X, 68040FPSP)
2430 int m_fcos(WORD inst, WORD siz)
2432 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
2436 // fcosh (6888X, 68040FPSP)
2438 int m_fcosh(WORD inst, WORD siz)
2440 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
2444 // fdbcc (6888X, 68040)
2446 int m_fdbcc(WORD inst, WORD siz)
2450 WORD opcode=inst&0x3f; //Grab conditional bitfield
2461 if (a1exattr & DEFINED)
2463 if ((a1exattr & TDB) != cursect)
2464 return error(rel_error);
2468 if (v + 0x8000 > 0x10000)
2469 return error(range_error);
2475 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
2486 // fdiv (6888X, 68040)
2488 int m_fdiv(WORD inst, WORD siz)
2490 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
2492 int m_fsdiv(WORD inst, WORD siz)
2494 if (activefpu == FPU_68040)
2495 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
2497 return error("Unsupported in current FPU");
2499 int m_fddiv(WORD inst, WORD siz)
2501 if (activefpu == FPU_68040)
2502 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
2504 return error("Unsupported in current FPU");
2508 // fetox (6888X, 68040FPSP)
2510 int m_fetox(WORD inst, WORD siz)
2512 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
2516 // fetoxm1 (6888X, 68040FPSP)
2518 int m_fetoxm1(WORD inst, WORD siz)
2520 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
2524 // fgetexp (6888X, 68040FPSP)
2526 int m_fgetexp(WORD inst, WORD siz)
2528 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
2532 // fgetman (6888X, 68040FPSP)
2534 int m_fgetman(WORD inst, WORD siz)
2536 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
2540 // fint (6888X, 68040FPSP)
2542 int m_fint(WORD inst, WORD siz)
2545 // special case - fint fpx = fint fpx,fpx
2547 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
2551 // fintrz (6888X, 68040FPSP)
2553 int m_fintrz(WORD inst, WORD siz)
2556 // special case - fintrz fpx = fintrz fpx,fpx
2558 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
2562 // flog10 (6888X, 68040FPSP)
2564 int m_flog10(WORD inst, WORD siz)
2566 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
2570 // flog2 (6888X, 68040FPSP)
2572 int m_flog2(WORD inst, WORD siz)
2574 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
2578 // flogn (6888X, 68040FPSP)
2580 int m_flogn(WORD inst, WORD siz)
2582 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
2586 // flognp1 (6888X, 68040FPSP)
2588 int m_flognp1(WORD inst, WORD siz)
2590 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
2594 // fmod (6888X, 68040FPSP)
2596 int m_fmod(WORD inst, WORD siz)
2598 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
2602 // fmove (6888X, 68040)
2604 int m_fmove(WORD inst, WORD siz)
2607 ////////////ea to register
2608 if (am0==FREG&&am1<AM_USP)
2622 WARNING("K-factor logic is totally bogus - fix!")
2627 case SIZB: inst |= (6<<10); break;
2628 case SIZW: inst |= (4<<10); break;
2629 case SIZL: inst |= (0<<10); break;
2631 case SIZS: inst |= (1<<10); break;
2632 case SIZD: inst |= (5<<10); break;
2633 case SIZX: inst |= (2<<10); break;
2634 case SIZP: inst |= (3<<10); if (bfparam1) inst|=1<<12; inst|=(bfparam1&0x7ff)>>2; break;
2635 default: return error("Something bad happened, possibly."); break;
2638 //immediate {} value
2640 return error("K-factor must be between 0 and 31");
2641 if ((!bfparam1) && siz==SIZP)
2644 //destination specifier
2654 else if (am0<AM_USP&&am1==FREG)
2671 case SIZB: inst |= (6<<10); break;
2672 case SIZW: inst |= (4<<10); break;
2673 case SIZL: inst |= (0<<10); break;
2675 case SIZS: inst |= (1<<10); break;
2676 case SIZD: inst |= (5<<10); break;
2677 case SIZX: inst |= (2<<10); break;
2678 case SIZP: inst |= (3<<10); break;
2679 default: return error("Something bad happened, possibly."); break;
2682 //destination specifier
2692 else if (am0==FREG&&am1==FREG)
2702 return error("Invalid size");
2707 //destination register
2714 ///////////register to memory
2716 //destination format
2718 //k-factor (if required)
2721 //return error("Not implemented yet.");
2722 //return gen_fpu(inst, siz, B8(00101101), FPU_P_EMUL);
2726 // fmove (6888X, 68040)
2728 int m_fmovescr(WORD inst, WORD siz)
2730 ///////////Move Floating-Point System Control Register (FPCR)
2734 if (am0==FPSCR&&am1<AM_USP)
2738 inst=(1<<13)+(1<<15);
2744 else if (am1==FPSCR&&am0<AM_USP)
2748 inst=(0<<13)+(1<<15);
2755 return error("m_fmovescr says: wut?");
2759 // fsmove/fdmove (68040)
2761 int m_fsmove(WORD inst, WORD siz)
2763 return error("Not implemented yet.");
2764 if (activefpu == FPU_68040)
2765 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
2767 return error("Unsupported in current FPU");
2769 int m_fdmove(WORD inst, WORD siz)
2771 return error("Not implemented yet.");
2772 if (activefpu == FPU_68040)
2773 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
2775 return error("Unsupported in current FPU");
2778 // fmovecr (6888X, 68040FPSP)
2780 int m_fmovecr(WORD inst, WORD siz)
2787 if (activefpu == FPU_68040)
2788 warn("Instruction is emulated in 68040");
2793 // fmovem (6888X, 68040)
2795 int m_fmovem(WORD inst, WORD siz)
2802 if (*tok>=KW_FP0 && *tok<=KW_FP7)
2804 //fmovem.x <rlist>,ea
2805 if (fpu_reglist_left(®mask) < 0)
2808 return error("missing comma");
2812 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
2813 return error("invalid addressing mode");
2815 inst=((1<<15)|(1<<14))|(1<<13)|(0<<11)|regmask;
2820 else if (*tok >= KW_D0 && *tok <= KW_D7)
2823 datareg=(*tok++&7)<<10;
2825 return error("missing comma");
2829 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
2830 return error("invalid addressing mode");
2832 inst=((1<<15)|(1<<14))|(1<<13)|(1<<11)|(datareg<<4);
2844 return error("missing comma");
2845 if (*tok>=KW_FP0 && *tok<=KW_FP7)
2847 //fmovem.x ea,<rlist>
2848 if (fpu_reglist_right(®mask) < 0)
2851 inst=((1<<15)|(1<<14))|(0<<13)|(2<<11)|regmask;
2859 datareg=(*tok++&7)<<10;
2861 inst=((1<<15)|(1<<14))|(0<<13)|(3<<11)|(datareg<<4);
2868 else if (siz == SIZL||siz==SIZN)
2870 if (*tok==KW_FPCR || *tok==KW_FPSR || *tok==KW_FPIAR)
2872 //fmovem.l <rlist>,ea
2873 regmask=(1<<15)|(1<<13);
2893 if (*tok=='/' || *tok=='-')
2899 return error("missing comma");
2909 //fmovem.l ea,<rlist>
2914 return error("missing comma");
2915 regmask=(1<<15)|(0<<13);
2935 if (*tok=='/' || *tok=='-')
2941 return error("extra (unexpected) text found");
2949 return error("bad size suffix");
2955 // fmul (6888X, 68040)
2957 int m_fmul(WORD inst, WORD siz)
2959 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
2961 int m_fsmul(WORD inst, WORD siz)
2963 if (activefpu == FPU_68040)
2964 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
2966 return error("Unsupported in current FPU");
2968 int m_fdmul(WORD inst, WORD siz)
2970 if (activefpu == FPU_68040)
2971 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
2973 return error("Unsupported in current FPU");
2977 // fneg (6888X, 68040)
2979 int m_fneg(WORD inst, WORD siz)
2981 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
2983 int m_fsneg(WORD inst, WORD siz)
2985 if (activefpu == FPU_68040)
2986 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
2988 return error("Unsupported in current FPU");
2990 int m_fdneg(WORD inst, WORD siz)
2992 if (activefpu == FPU_68040)
2993 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
2995 return error("Unsupported in current FPU");
2999 // fnop (6888X, 68040)
3001 int m_fnop(WORD inst, WORD siz)
3003 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3007 // frem (6888X, 68040FPSP)
3009 int m_frem(WORD inst, WORD siz)
3011 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3015 // fscale (6888X, 68040FPSP)
3017 int m_fscale(WORD inst, WORD siz)
3019 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3023 // FScc (6888X, 68040)
3025 int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3026 int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3027 int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3028 int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3029 int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3030 int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3031 int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3032 int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3033 int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3034 int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3035 int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3036 int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3037 int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3038 int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3039 int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3040 int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3041 int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3042 int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3043 int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3044 int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3045 int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3046 int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3047 int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3048 int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3049 int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3050 int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3051 int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3052 int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3053 int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3054 int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3055 int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3056 int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3059 // FTRAPcc (6888X, 68040)
3062 int m_ftrapeq (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000001)); D_long(a0exval); } return OK;}
3063 int m_ftrapne (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001110)); D_long(a0exval); } return OK;}
3064 int m_ftrapgt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010010)); D_long(a0exval); } return OK;}
3065 int m_ftrapngt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011101)); D_long(a0exval); } return OK;}
3066 int m_ftrapge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010011)); D_long(a0exval); } return OK;}
3067 int m_ftrapnge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011100)); D_long(a0exval); } return OK;}
3068 int m_ftraplt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010100)); D_long(a0exval); } return OK;}
3069 int m_ftrapnlt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011011)); D_long(a0exval); } return OK;}
3070 int m_ftraple (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010101)); D_long(a0exval); } return OK;}
3071 int m_ftrapnle (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011010)); D_long(a0exval); } return OK;}
3072 int m_ftrapgl (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010110)); D_long(a0exval); } return OK;}
3073 int m_ftrapngl (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011001)); D_long(a0exval); } return OK;}
3074 int m_ftrapgle (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010111)); D_long(a0exval); } return OK;}
3075 int m_ftrapngle(WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011000)); D_long(a0exval); } return OK;}
3076 int m_ftrapogt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000010)); D_long(a0exval); } return OK;}
3077 int m_ftrapule (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001101)); D_long(a0exval); } return OK;}
3078 int m_ftrapoge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000011)); D_long(a0exval); } return OK;}
3079 int m_ftrapult (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001100)); D_long(a0exval); } return OK;}
3080 int m_ftrapolt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000100)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000100)); D_long(a0exval); } return OK;}
3081 int m_ftrapuge (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001011)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001011)); D_long(a0exval); } return OK;}
3082 int m_ftrapole (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000101)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000101)); D_long(a0exval); } return OK;}
3083 int m_ftrapugt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001010)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001010)); D_long(a0exval); } return OK;}
3084 int m_ftrapogl (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000110)); D_long(a0exval); } return OK;}
3085 int m_ftrapueq (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001001)); D_long(a0exval); } return OK;}
3086 int m_ftrapor (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000111)); D_long(a0exval); } return OK;}
3087 int m_ftrapun (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001000)); D_long(a0exval); } return OK;}
3088 int m_ftrapf (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00000000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00000000)); D_long(a0exval); } return OK;}
3089 int m_ftrapt (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00001111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00001111)); D_long(a0exval); } return OK;}
3090 int m_ftrapsf (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010000)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010000)); D_long(a0exval); } return OK;}
3091 int m_ftrapst (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011111)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011111)); D_long(a0exval); } return OK;}
3092 int m_ftrapseq (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00010001)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00010001)); D_long(a0exval); } return OK;}
3093 int m_ftrapsne (WORD inst, WORD siz) { if (siz==SIZW) { D_word(inst); D_word(B8(00011110)); D_word(a0exval); } else { inst|=3; D_word(inst); D_word(B8(00011110)); D_long(a0exval); } return OK;}
3095 int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3096 int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3097 int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3098 int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3099 int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3100 int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3101 int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3102 int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3103 int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3104 int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3105 int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3106 int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3107 int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3108 int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3109 int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3110 int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3111 int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3112 int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3113 int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3114 int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3115 int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3116 int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3117 int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3118 int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3119 int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3120 int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3121 int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3122 int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3123 int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3124 int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3125 int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3126 int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3130 // fsgldiv (6888X, 68040)
3132 int m_fsgldiv(WORD inst, WORD siz)
3134 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3138 // fsglmul (6888X, 68040)
3140 int m_fsglmul(WORD inst, WORD siz)
3142 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3146 // fsin (6888X, 68040FPSP)
3148 int m_fsin(WORD inst, WORD siz)
3150 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3154 // fsincos (6888X, 68040FPSP)
3156 int m_fsincos(WORD inst, WORD siz)
3159 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP)==OK)
3169 // fsin (6888X, 68040FPSP)
3171 int m_fsinh(WORD inst, WORD siz)
3173 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3177 // fsqrt (6888X, 68040)
3179 int m_fsqrt(WORD inst, WORD siz)
3181 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3183 int m_fsfsqrt(WORD inst, WORD siz)
3185 if (activefpu == FPU_68040)
3186 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
3188 return error("Unsupported in current FPU");
3190 int m_fdfsqrt(WORD inst, WORD siz)
3192 if (activefpu == FPU_68040)
3193 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
3195 return error("Unsupported in current FPU");
3199 // fsub (6888X, 68040)
3201 int m_fsub(WORD inst, WORD siz)
3203 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
3205 int m_fsfsub(WORD inst, WORD siz)
3207 if (activefpu == FPU_68040)
3208 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
3210 return error("Unsupported in current FPU");
3212 int m_fdsub(WORD inst, WORD siz)
3214 if (activefpu == FPU_68040)
3215 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
3217 return error("Unsupported in current FPU");
3221 // ftan (6888X, 68040FPSP)
3223 int m_ftan(WORD inst, WORD siz)
3225 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
3229 // ftanh (6888X, 68040FPSP)
3231 int m_ftanh(WORD inst, WORD siz)
3233 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
3237 // ftentox (6888X, 68040FPSP)
3239 int m_ftentox(WORD inst, WORD siz)
3241 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
3245 // ftst (6888X, 68040)
3247 int m_ftst(WORD inst, WORD siz)
3249 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
3253 // ftwotox (6888X, 68040FPSP)
3255 int m_ftwotox(WORD inst, WORD siz)
3257 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);