2 // RMAC - Reboot's Macro Assembler for all Atari computers
3 // MACH.C - Code Generation
4 // Copyright (C) 199x Landon Dyer, 2011-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
24 int movep = 0; // Global flag to indicate we're generating a movep instruction
26 // Function prototypes
27 int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
28 int m_self(WORD, WORD);
29 int m_abcd(WORD, WORD);
30 int m_reg(WORD, WORD);
31 int m_imm(WORD, WORD);
32 int m_imm8(WORD, WORD);
33 int m_shi(WORD, WORD);
34 int m_shr(WORD, WORD);
35 int m_bitop(WORD, WORD);
36 int m_exg(WORD, WORD);
38 int m_lea(WORD, WORD);
40 int m_dbra(WORD, WORD);
41 int m_link(WORD, WORD);
42 int m_adda(WORD, WORD);
43 int m_addq(WORD, WORD);
44 //int m_move(WORD, int);
45 int m_move(WORD, WORD);
46 int m_moveq(WORD, WORD);
47 int m_usp(WORD, WORD);
48 int m_movep(WORD, WORD);
49 int m_trap(WORD, WORD);
50 int m_movem(WORD, WORD);
51 int m_clra(WORD, WORD);
53 int m_move30(WORD, WORD); //68020/30/40/60
54 int m_br30(WORD inst, WORD siz);
55 int m_ea030(WORD inst, WORD siz);
56 int m_bfop(WORD inst, WORD siz);
57 int m_callm(WORD inst, WORD siz);
58 int m_cas(WORD inst, WORD siz);
59 int m_cas2(WORD inst, WORD siz);
60 int m_chk2(WORD inst, WORD siz);
61 int m_cmp2(WORD inst, WORD siz);
62 int m_bkpt(WORD inst, WORD siz);
63 int m_cpbr(WORD inst, WORD siz);
64 int m_cpdbr(WORD inst, WORD siz);
65 int m_divs(WORD inst, WORD siz);
66 int m_muls(WORD inst, WORD siz);
67 int m_divu(WORD inst, WORD siz);
68 int m_mulu(WORD inst, WORD siz);
69 int m_divsl(WORD inst, WORD siz);
70 int m_divul(WORD inst, WORD siz);
71 int m_move16a(WORD inst, WORD siz);
72 int m_move16b(WORD inst, WORD siz);
73 int m_pack(WORD inst, WORD siz);
74 int m_rtm(WORD inst, WORD siz);
75 int m_rtd(WORD inst, WORD siz);
76 int m_trapcc(WORD inst, WORD siz);
77 int m_cinv(WORD inst, WORD siz);
78 int m_cprest(WORD inst, WORD siz);
79 int m_movec(WORD inst, WORD siz);
80 int m_moves(WORD inst, WORD siz);
83 int m_pbcc(WORD inst, WORD siz);
84 int m_pflusha(WORD inst, WORD siz);
85 int m_pflush(WORD inst, WORD siz);
86 int m_pflushr(WORD inst, WORD siz);
87 int m_pload(WORD inst, WORD siz, WORD extension);
88 int m_pmove(WORD inst, WORD siz);
89 int m_pmovefd(WORD inst, WORD siz);
90 int m_ptest(WORD inst, WORD siz);
91 int m_ptrapbs(WORD inst, WORD siz);
92 int m_ptrapbc(WORD inst, WORD siz);
93 int m_ptrapls(WORD inst, WORD siz);
94 int m_ptraplc(WORD inst, WORD siz);
95 int m_ptrapss(WORD inst, WORD siz);
96 int m_ptrapsc(WORD inst, WORD siz);
97 int m_ptrapas(WORD inst, WORD siz);
98 int m_ptrapac(WORD inst, WORD siz);
99 int m_ptrapws(WORD inst, WORD siz);
100 int m_ptrapwc(WORD inst, WORD siz);
101 int m_ptrapis(WORD inst, WORD siz);
102 int m_ptrapic(WORD inst, WORD siz);
103 int m_ptrapgc(WORD inst, WORD siz);
104 int m_ptrapgs(WORD inst, WORD siz);
105 int m_ptrapcs(WORD inst, WORD siz);
106 int m_ptrapcc(WORD inst, WORD siz);
107 int m_ptrapbsn(WORD inst, WORD siz);
108 int m_ptrapbcn(WORD inst, WORD siz);
109 int m_ptraplsn(WORD inst, WORD siz);
110 int m_ptraplcn(WORD inst, WORD siz);
111 int m_ptrapssn(WORD inst, WORD siz);
112 int m_ptrapscn(WORD inst, WORD siz);
113 int m_ptrapasn(WORD inst, WORD siz);
114 int m_ptrapacn(WORD inst, WORD siz);
115 int m_ptrapwsn(WORD inst, WORD siz);
116 int m_ptrapwcn(WORD inst, WORD siz);
117 int m_ptrapisn(WORD inst, WORD siz);
118 int m_ptrapicn(WORD inst, WORD siz);
119 int m_ptrapgsn(WORD inst, WORD siz);
120 int m_ptrapgcn(WORD inst, WORD siz);
121 int m_ptrapcsn(WORD inst, WORD siz);
122 int m_ptrapccn(WORD inst, WORD siz);
123 int m_ploadr(WORD inst, WORD siz);
124 int m_ploadw(WORD inst, WORD siz);
127 int m_fabs(WORD inst, WORD siz);
128 int m_facos(WORD inst, WORD siz);
129 int m_fadd(WORD inst, WORD siz);
130 int m_fasin(WORD inst, WORD siz);
131 int m_fatan(WORD inst, WORD siz);
132 int m_fatanh(WORD inst, WORD siz);
133 int m_fcmp(WORD inst, WORD siz);
134 int m_fcos(WORD inst, WORD siz);
135 int m_fcosh(WORD inst, WORD siz);
136 int m_fdabs(WORD inst, WORD siz);
137 int m_fdadd(WORD inst, WORD siz);
138 int m_fdbcc(WORD inst, WORD siz);
139 int m_fddiv(WORD inst, WORD siz);
140 int m_fdfsqrt(WORD inst, WORD siz);
141 int m_fdiv(WORD inst, WORD siz);
142 int m_fdmove(WORD inst, WORD siz);
143 int m_fdmul(WORD inst, WORD siz);
144 int m_fdneg(WORD inst, WORD siz);
145 int m_fdsub(WORD inst, WORD siz);
146 int m_fetox(WORD inst, WORD siz);
147 int m_fetoxm1(WORD inst, WORD siz);
148 int m_fgetexp(WORD inst, WORD siz);
149 int m_fgetman(WORD inst, WORD siz);
150 int m_fint(WORD inst, WORD siz);
151 int m_fintrz(WORD inst, WORD siz);
152 int m_flog10(WORD inst, WORD siz);
153 int m_flog2(WORD inst, WORD siz);
154 int m_flogn(WORD inst, WORD siz);
155 int m_flognp1(WORD inst, WORD siz);
156 int m_fmod(WORD inst, WORD siz);
157 int m_fmove(WORD inst, WORD siz);
158 int m_fmovescr(WORD inst, WORD siz);
159 int m_fmovecr(WORD inst, WORD siz);
160 int m_fmovem(WORD inst, WORD siz);
161 int m_fmul(WORD inst, WORD siz);
162 int m_fneg(WORD inst, WORD siz);
163 int m_fnop(WORD inst, WORD siz);
164 int m_frem(WORD inst, WORD siz);
165 int m_fsabs(WORD inst, WORD siz);
166 int m_fsadd(WORD inst, WORD siz);
167 int m_fseq(WORD inst, WORD siz);
168 int m_fsne(WORD inst, WORD siz);
169 int m_fsgt(WORD inst, WORD siz);
170 int m_fsngt(WORD inst, WORD siz);
171 int m_fsge(WORD inst, WORD siz);
172 int m_fsnge(WORD inst, WORD siz);
173 int m_fslt(WORD inst, WORD siz);
174 int m_fsnlt(WORD inst, WORD siz);
175 int m_fsle(WORD inst, WORD siz);
176 int m_fsnle(WORD inst, WORD siz);
177 int m_fsgl(WORD inst, WORD siz);
178 int m_fsngl(WORD inst, WORD siz);
179 int m_fsgle(WORD inst, WORD siz);
180 int m_fsngle(WORD inst, WORD siz);
181 int m_fsogt(WORD inst, WORD siz);
182 int m_fsule(WORD inst, WORD siz);
183 int m_fsoge(WORD inst, WORD siz);
184 int m_fsult(WORD inst, WORD siz);
185 int m_fsolt(WORD inst, WORD siz);
186 int m_fsuge(WORD inst, WORD siz);
187 int m_fsole(WORD inst, WORD siz);
188 int m_fsugt(WORD inst, WORD siz);
189 int m_fsogl(WORD inst, WORD siz);
190 int m_fsueq(WORD inst, WORD siz);
191 int m_fsor(WORD inst, WORD siz);
192 int m_fsun(WORD inst, WORD siz);
193 int m_fsf(WORD inst, WORD siz);
194 int m_fst(WORD inst, WORD siz);
195 int m_fssf(WORD inst, WORD siz);
196 int m_fsst(WORD inst, WORD siz);
197 int m_fsseq(WORD inst, WORD siz);
198 int m_fssne(WORD inst, WORD siz);
199 int m_fscale(WORD inst, WORD siz);
200 int m_fsdiv(WORD inst, WORD siz);
201 int m_fsfsqrt(WORD inst, WORD siz);
202 int m_fsfsub(WORD inst, WORD siz);
203 int m_fsgldiv(WORD inst, WORD siz);
204 int m_fsglmul(WORD inst, WORD siz);
205 int m_fsin(WORD inst, WORD siz);
206 int m_fsincos(WORD inst, WORD siz);
207 int m_fsinh(WORD inst, WORD siz);
208 int m_fsmove(WORD inst, WORD siz);
209 int m_fsmul(WORD inst, WORD siz);
210 int m_fsneg(WORD inst, WORD siz);
211 int m_fsqrt(WORD inst, WORD siz);
212 int m_fsub(WORD inst, WORD siz);
213 int m_ftan(WORD inst, WORD siz);
214 int m_ftanh(WORD inst, WORD siz);
215 int m_ftentox(WORD inst, WORD siz);
216 int m_ftst(WORD inst, WORD siz);
217 int m_ftwotox(WORD inst, WORD siz);
218 int m_ftrapeq(WORD inst, WORD siz);
219 int m_ftrapne(WORD inst, WORD siz);
220 int m_ftrapgt(WORD inst, WORD siz);
221 int m_ftrapngt(WORD inst, WORD siz);
222 int m_ftrapge(WORD inst, WORD siz);
223 int m_ftrapnge(WORD inst, WORD siz);
224 int m_ftraplt(WORD inst, WORD siz);
225 int m_ftrapnlt(WORD inst, WORD siz);
226 int m_ftraple(WORD inst, WORD siz);
227 int m_ftrapnle(WORD inst, WORD siz);
228 int m_ftrapgl(WORD inst, WORD siz);
229 int m_ftrapngl(WORD inst, WORD siz);
230 int m_ftrapgle(WORD inst, WORD siz);
231 int m_ftrapngle(WORD inst, WORD siz);
232 int m_ftrapogt(WORD inst, WORD siz);
233 int m_ftrapule(WORD inst, WORD siz);
234 int m_ftrapoge(WORD inst, WORD siz);
235 int m_ftrapult(WORD inst, WORD siz);
236 int m_ftrapolt(WORD inst, WORD siz);
237 int m_ftrapuge(WORD inst, WORD siz);
238 int m_ftrapole(WORD inst, WORD siz);
239 int m_ftrapugt(WORD inst, WORD siz);
240 int m_ftrapogl(WORD inst, WORD siz);
241 int m_ftrapueq(WORD inst, WORD siz);
242 int m_ftrapor(WORD inst, WORD siz);
243 int m_ftrapun(WORD inst, WORD siz);
244 int m_ftrapf(WORD inst, WORD siz);
245 int m_ftrapt(WORD inst, WORD siz);
246 int m_ftrapsf(WORD inst, WORD siz);
247 int m_ftrapst(WORD inst, WORD siz);
248 int m_ftrapseq(WORD inst, WORD siz);
249 int m_ftrapsne(WORD inst, WORD siz);
250 int m_ftrapeqn(WORD inst, WORD siz);
251 int m_ftrapnen(WORD inst, WORD siz);
252 int m_ftrapgtn(WORD inst, WORD siz);
253 int m_ftrapngtn(WORD inst, WORD siz);
254 int m_ftrapgen(WORD inst, WORD siz);
255 int m_ftrapngen(WORD inst, WORD siz);
256 int m_ftrapltn(WORD inst, WORD siz);
257 int m_ftrapnltn(WORD inst, WORD siz);
258 int m_ftraplen(WORD inst, WORD siz);
259 int m_ftrapnlen(WORD inst, WORD siz);
260 int m_ftrapgln(WORD inst, WORD siz);
261 int m_ftrapngln(WORD inst, WORD siz);
262 int m_ftrapglen(WORD inst, WORD siz);
263 int m_ftrapnglen(WORD inst, WORD siz);
264 int m_ftrapogtn(WORD inst, WORD siz);
265 int m_ftrapulen(WORD inst, WORD siz);
266 int m_ftrapogen(WORD inst, WORD siz);
267 int m_ftrapultn(WORD inst, WORD siz);
268 int m_ftrapoltn(WORD inst, WORD siz);
269 int m_ftrapugen(WORD inst, WORD siz);
270 int m_ftrapolen(WORD inst, WORD siz);
271 int m_ftrapugtn(WORD inst, WORD siz);
272 int m_ftrapogln(WORD inst, WORD siz);
273 int m_ftrapueqn(WORD inst, WORD siz);
274 int m_ftraporn(WORD inst, WORD siz);
275 int m_ftrapunn(WORD inst, WORD siz);
276 int m_ftrapfn(WORD inst, WORD siz);
277 int m_ftraptn(WORD inst, WORD siz);
278 int m_ftrapsfn(WORD inst, WORD siz);
279 int m_ftrapstn(WORD inst, WORD siz);
280 int m_ftrapseqn(WORD inst, WORD siz);
281 int m_ftrapsnen(WORD inst, WORD siz);
283 // Common error messages
284 char range_error[] = "expression out of range";
285 char abs_error[] = "illegal absolute expression";
286 char seg_error[] = "bad (section) expression";
287 char rel_error[] = "illegal relative address";
288 char siz_error[] = "bad size specified";
289 char undef_error[] = "undefined expression";
290 char fwd_error[] = "forward or undefined expression";
291 char unsupport[] = "unsupported for selected CPU";
293 // Include code tables
295 { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0
297 { 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry
300 // Register number << 9
302 0, 1 << 9, 2 << 9, 3 << 9, 4 << 9, 5 << 9, 6 << 9, 7 << 9
305 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
309 1<<6, (WORD)-1, // SIZW, n/a
310 2<<6, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
314 // Byte/word/long size for MOVE instrs
318 0x3000, (WORD)-1, // Word
319 0x2000, (WORD)-1, (WORD)-1, (WORD)-1, // Long
320 0x3000 // Word (SIZN)
323 // Word/long size (0=.w, 1=.l) in bit 8
327 0, (WORD)-1, // SIZW, n/a
328 1<<8, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
332 // Byte/Word/long size (0=.w, 1=.l) in bit 9
336 1<<9, (WORD)-1, // Word
337 1<<10, (WORD)-1, (WORD)-1, (WORD)-1, // Long
341 // Addressing mode in bits 6..11 (register/mode fields are reversed)
343 00000, 01000, 02000, 03000, 04000, 05000, 06000, 07000,
344 00100, 01100, 02100, 03100, 04100, 05100, 06100, 07100,
345 00200, 01200, 02200, 03200, 04200, 05200, 06200, 07200,
346 00300, 01300, 02300, 03300, 04300, 05300, 06300, 07300,
347 00400, 01400, 02400, 03400, 04400, 05400, 06400, 07400,
348 00500, 01500, 02500, 03500, 04500, 05500, 06500, 07500,
349 00600, 01600, 02600, 03600, 04600, 05600, 06600, 07600,
350 00700, 01700, 02700, 03700, 04700, 05700, 06700, 07700
353 // Control registers lookup table
355 // MC68010/MC68020/MC68030/MC68040/CPU32
356 0x000, // Source Function Code(SFC)
357 0x001, // Destination Function Code(DFC)
358 0x800, // User Stack Pointer(USP)
359 0x801, // Vector Base Register(VBR)
360 // MC68020 / MC68030 / MC68040
361 0x002, // Cache Control Register(CACR)
362 0x802, // Cache Address Register(CAAR) (020/030 only)
363 0x803, // Master Stack Pointer(MSP)
364 0x804, // Interrupt Stack Pointer(ISP)
365 // MC68040 / MC68LC040
366 0x003, // MMU Translation Control Register(TC)
367 0x004, // Instruction Transparent Translation Register 0 (ITT0)
368 0x005, // Instruction Transparent Translation Register 1 (ITT1)
369 0x006, // Data Transparent Translation Register 0 (DTT0)
370 0x007, // Data Transparent Translation Register 1 (DTT1)
371 0x805, // MMU Status Register(MMUSR)
372 0x806, // User Root Pointer(URP)
373 0x807, // Supervisor Root Pointer(SRP)
375 0x004, // Instruction Access Control Register 0 (IACR0)
376 0x005, // Instruction Access Control Register 1 (IACR1)
377 0x006, // Data Access Control Register 0 (DACR1)
378 0x007, // Data Access Control Register 1 (DACR1)
380 0xFFF // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
385 int m_unimp(WORD unused1, WORD unused2)
387 return (int)error("unimplemented mnemonic");
391 //int m_badmode(void)
392 int m_badmode(WORD unused1, WORD unused2)
394 return (int)error("inappropriate addressing mode");
398 int m_self(WORD inst, WORD usused)
406 // Do one EA in bits 0..5
408 // Bits in `inst' have the following meaning:
410 // Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits
413 // If bit one is set, the OTHER ea (the one that wasn't generated by bit zero)
414 // is generated after the instruction. Regardless of bit 0's value, ea0 is
415 // always deposited in memory before ea1.
417 // If bit two is set, standard size bits are set in the instr in bits 6 and 7.
419 // If bit four is set, bit three specifies which eaXreg to place in bits 9..11
422 int m_ea(WORD inst, WORD siz)
424 WORD flg = inst; // Save flag bits
425 inst &= ~0x3F; // Clobber flag bits in instr
427 // Install "standard" instr size bits
433 // OR-in register number
435 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
437 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
443 inst |= am1 | a1reg; // Get ea1 into instr
444 D_word(inst); // Deposit instr
446 // Generate ea0 if requested
450 ea1gen(siz); // Generate ea1
455 inst |= am0 | a0reg; // Get ea0 into instr
456 D_word(inst); // Deposit instr
457 ea0gen(siz); // Generate ea0
459 // Generate ea1 if requested
469 // Check if lea x(an),an can be optimised to addq.w #x,an--otherwise fall back
472 int m_lea(WORD inst, WORD siz)
474 if (CHECK_OPTS(OPT_LEA_ADDQ)
475 && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
476 && ((a0exval > 0) && (a0exval <= 8)))
478 inst = B16(01010000, 01001000) | ((a0exval & 7) << 9) | (a0reg);
480 warn("lea size(An),An converted to addq #size,An");
484 return m_ea(inst, siz);
488 int m_ea030(WORD inst, WORD siz)
491 WORD flg = inst; // Save flag bits
492 inst &= ~0x3F; // Clobber flag bits in instr
494 // Install "standard" instr size bits
500 // OR-in register number
503 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
507 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
514 inst |= am1 | a1reg; // Get ea1 into instr
515 D_word(inst); // Deposit instr
517 // Generate ea0 if requested
521 ea1gen(siz); // Generate ea1
527 // We get here if we're doing 020+ addressing and an address
528 // register is used. For example, something like "tst a0". A bit of
529 // a corner case, so kludge it
531 else if (am0 == PCDISP)
532 //Another corner case (possibly!), so kludge ahoy
533 inst |= am0; // Get ea0 into instr
534 else if (am0 == IMMED)
535 inst |= am0 | a0reg; // Get ea0 into instr
536 else if (am0 == AM_CCR)
538 else if (am0 == AIND)
541 inst |= a0reg; // Get ea0 into instr
542 D_word(inst); // Deposit instr
543 ea0gen(siz); // Generate ea0
545 // Generate ea1 if requested
555 // Dx,Dy nnnnXXXnssnnnYYY If bit 0 of `inst' is set, install size bits in bits
558 int m_abcd(WORD inst, WORD siz)
567 inst |= a0reg | reg_9[a1reg];
577 int m_adda(WORD inst, WORD siz)
579 inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
581 ea0gen(siz); // Generate EA
588 // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr.
589 // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr.
591 int m_reg(WORD inst, WORD siz)
598 // Install other register (9..11)
599 inst |= reg_9[a1reg];
601 inst &= ~7; // Clear off crufty bits
602 inst |= a0reg; // Install first register
612 int m_imm(WORD inst, WORD siz)
624 int m_imm8(WORD inst, WORD siz)
637 int m_shr(WORD inst, WORD siz)
639 inst |= reg_9[a0reg] | a1reg | siz_6[siz];
649 int m_shi(WORD inst, WORD siz)
651 inst |= a1reg | siz_6[siz];
653 if (a0exattr & DEFINED)
656 return error(range_error);
658 inst |= (a0exval & 7) << 9;
663 AddFixup(FU_QUICK, sloc, a0expr);
672 // {bset, btst, bchg, bclr} -- #immed,ea -- Dn,ea
674 int m_bitop(WORD inst, WORD siz)
676 // Enforce instruction sizes
678 { // X,Dn must be .n or .l
679 if (siz & (SIZB | SIZW))
680 return error(siz_error);
682 else if (siz & (SIZW | SIZL)) // X,ea must be .n or .b
683 return error(siz_error);
685 // Construct instr and EAs
691 ea0gen(SIZB); // Immediate bit number
695 inst |= reg_9[a0reg];
706 int m_dbra(WORD inst, WORD siz)
714 if (a1exattr & DEFINED)
716 if ((a1exattr & TDB) != cursect)
717 return error(rel_error);
721 if (v + 0x8000 > 0x10000)
722 return error(range_error);
728 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
739 int m_exg(WORD inst, WORD siz)
745 if (am0 == DREG && am1 == DREG)
747 else if (am0 == AREG && am1 == AREG)
753 m = a1reg; // Get AREG into a1reg
761 inst |= m | reg_9[a0reg] | a1reg;
771 int m_link(WORD inst, WORD siz)
775 // Is this an error condition???
780 inst &= ~((3 << 9) | (1 << 6) | (1 << 4));
792 WORD extra_addressing[16]=
795 0, //0101 ([bd,An],Xn,od)
796 0x180, //0102 ([bc,An,Xn],od) (111 110 110 111)
798 0, //0104 ([bd,PC],Xn,od)
799 0, //0105 ([bc,PC,Xn],od)
814 // Handle MOVE <C_ALL> <C_ALTDATA>
815 // MOVE <C_ALL> <M_AREG>
817 // Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
819 int m_move(WORD inst, WORD size)
821 // Cast the passed in value to an int
824 // Try to optimize to MOVEQ
825 if (CHECK_OPTS(OPT_MOVEL_MOVEQ)
826 && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
827 && ((a0exattr & (TDB | DEFINED)) == DEFINED)
828 && (a0exval + 0x80 < 0x100))
830 m_moveq((WORD)0x7000, (WORD)0);
833 warn("move.l #size,dx converted to moveq");
837 if ((am0 < ABASE) && (am1 < ABASE)) //68000 modes
839 inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
847 ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
851 inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0 - ABASE];
867 // Handle MOVE <C_ALL030> <C_ALTDATA>
868 // MOVE <C_ALL030> <M_AREG>
870 int m_move30(WORD inst, WORD size)
873 // TODO: is extra_addressing necessary/correct?
874 //inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
875 inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg;
890 // move USP,An -- move An,USP
892 int m_usp(WORD inst, WORD siz)
897 inst |= a1reg; // USP, An
899 inst |= a0reg; // An, USP
910 int m_moveq(WORD inst, WORD siz)
914 // Arrange for future fixup
915 if (!(a0exattr & DEFINED))
917 AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
920 else if (a0exval + 0x100 >= 0x200)
921 return error(range_error);
923 inst |= reg_9[a1reg] | (a0exval & 0xFF);
931 // movep Dn, disp(An) -- movep disp(An), Dn
933 int m_movep(WORD inst, WORD siz)
935 // Tell ea0gen to lay off the 0(a0) optimisations on this one
943 inst |= reg_9[a0reg] | a1reg;
953 inst |= reg_9[a1reg] | a0reg;
970 int m_br(WORD inst, WORD siz)
974 if (a0exattr & DEFINED)
976 if ((a0exattr & TDB) != cursect)
978 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
979 return error(rel_error);
982 v = a0exval - (sloc + 2);
984 // Optimize branch instr. size
987 if (CHECK_OPTS(OPT_BSR_BCC_S) && (v != 0) && ((v + 0x80) < 0x100))
994 warn("Bcc.w/BSR.w converted to .s");
1001 if ((v + 0x8000) > 0x10000)
1002 return error(range_error);
1010 if (siz == SIZB || siz == SIZS)
1012 if ((v + 0x80) >= 0x100)
1013 return error(range_error);
1020 if ((v + 0x8000) >= 0x10000)
1021 return error(range_error);
1029 else if (siz == SIZN)
1032 if (siz == SIZB || siz == SIZS)
1035 AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
1043 AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
1054 int m_addq(WORD inst, WORD siz)
1056 inst |= siz_6[siz] | am1 | a1reg;
1058 if (a0exattr & DEFINED)
1060 if ((a0exval > 8) || (a0exval == 0)) // Range in 1..8
1061 return error(range_error);
1063 inst |= (a0exval & 7) << 9;
1068 AddFixup(FU_QUICK, sloc, a0expr);
1081 int m_trap(WORD inst, WORD siz)
1085 if (a0exattr & DEFINED)
1088 return error(abs_error);
1091 return error(range_error);
1097 return error(undef_error);
1104 // movem <rlist>,ea -- movem ea,<rlist>
1106 int m_movem(WORD inst, WORD siz)
1114 return error("bad size suffix");
1121 // Handle #<expr>, ea
1124 if (abs_expr(&eval) != OK)
1127 if (eval >= 0x10000L)
1128 return error(range_error);
1134 if ((*tok >= KW_D0) && (*tok <= KW_A7))
1137 if (reglist(&rmask) < 0)
1142 return error("missing comma");
1147 inst |= am0 | a0reg;
1149 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
1150 return error("invalid addressing mode");
1152 // If APREDEC, reverse register mask
1158 for(i=0x8000; i; i>>=1, w>>=1)
1159 rmask = (WORD)((rmask << 1) | w & 1);
1168 inst |= 0x0400 | am0 | a0reg;
1171 return error("missing comma");
1174 return error("missing register list");
1181 if (abs_expr(&eval) != OK)
1184 if (eval >= 0x10000)
1185 return error(range_error);
1189 else if (reglist(&rmask) < 0)
1192 if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
1193 return error("invalid addressing mode");
1205 // CLR.x An ==> SUBA.x An,An
1207 int m_clra(WORD inst, WORD siz)
1209 inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
1216 ////////////////////////////////////////
1218 // 68020/30/40 instructions
1220 ////////////////////////////////////////
1225 int m_br30(WORD inst, WORD siz)
1227 if (a0exattr & DEFINED)
1229 if ((a0exattr & TDB) != cursect)
1230 return error(rel_error);
1232 uint32_t v = a0exval - (sloc + 2);
1241 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1249 // bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
1250 // (68020, 68030, 68040)
1252 int m_bfop(WORD inst, WORD siz)
1255 if ((bfval1 > 31) || (bfval1 < 0))
1256 return error("bfxxx offset: immediate value must be between 0 and 31");
1258 // First instruction word - just the opcode and first EA
1259 // Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
1266 if (bfval2 > 31 || bfval2 < 0)
1267 return error("bfxxx width: immediate value must be between 0 and 31");
1269 // For Dw both immediate and register number are stuffed
1270 // into the same field O_o
1271 bfparam2 = (bfval2 << 0);
1276 bfparam1 = (bfval1 << 6);
1280 bfparam1 = bfval1 << 12;
1283 D_word((inst|am0|a0reg|am1|a1reg));
1284 ea0gen(siz); // Generate EA
1286 // Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
1288 inst = bfparam1 | bfparam2;
1294 inst |= a0reg << 12;
1303 // bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
1305 int m_bkpt(WORD inst, WORD siz)
1309 if (a0exattr & DEFINED)
1312 return error(abs_error);
1315 return error(range_error);
1321 return error(undef_error);
1330 int m_callm(WORD inst, WORD siz)
1337 if (a0exattr & DEFINED)
1340 return error(abs_error);
1343 return error(range_error);
1349 return error(undef_error);
1359 // cas (68020, 68030, 68040)
1361 int m_cas(WORD inst, WORD siz)
1367 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1368 return error(unsupport);
1383 return error("bad size suffix");
1388 if ((*tok < KW_D0) && (*tok > KW_D7))
1389 return error("CAS accepts only data registers");
1391 inst2 = (*tok++) & 7;
1394 return error("missing comma");
1397 if ((*tok < KW_D0) && (*tok > KW_D7))
1398 return error("CAS accepts only data registers");
1400 inst2 |= ((*tok++) & 7) << 6;
1403 return error("missing comma");
1406 if ((modes = amode(1)) < 0)
1410 return error("too many ea fields");
1413 return error("extra (unexpected) text found");
1415 // Reject invalud ea modes
1416 amsk = amsktab[am0];
1418 if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
1419 return error("unsupported addressing mode");
1421 inst |= am0 | a0reg;
1431 // cas2 (68020, 68030, 68040)
1433 int m_cas2(WORD inst, WORD siz)
1437 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1438 return error(unsupport);
1453 return error("bad size suffix");
1458 if ((*tok < KW_D0) && (*tok > KW_D7))
1459 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1461 inst2 = (*tok++) & 7;
1464 return error("missing colon");
1467 if ((*tok < KW_D0) && (*tok > KW_D7))
1468 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1470 inst3 = (*tok++) & 7;
1473 return error("missing comma");
1476 if ((*tok < KW_D0) && (*tok > KW_D7))
1477 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1479 inst2 |= ((*tok++) & 7) << 6;
1482 return error("missing colon");
1485 if ((*tok < KW_D0) && (*tok > KW_D7))
1486 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1488 inst3 |= ((*tok++) & 7) << 6;
1491 return error("missing comma");
1495 return error("missing (");
1496 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1497 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1498 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1499 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1501 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1504 return error("missing (");
1507 return error("missing colon");
1511 return error("missing (");
1512 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1513 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1514 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1515 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1517 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1520 return error("missing (");
1523 return error("extra (unexpected) text found");
1534 // cmp2 (68020, 68030, 68040, CPU32)
1536 int m_cmp2(WORD inst, WORD siz)
1538 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1539 return error(unsupport);
1541 switch (siz & 0x000F)
1555 WORD flg = inst; // Save flag bits
1556 inst &= ~0x3F; // Clobber flag bits in instr
1558 // Install "standard" instr size bits
1564 // OR-in register number
1566 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1568 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1574 inst |= am1 | a1reg; // Get ea1 into instr
1575 D_word(inst); // Deposit instr
1577 // Generate ea0 if requested
1581 ea1gen(siz); // Generate ea1
1586 inst |= am0 | a0reg; // Get ea0 into instr
1587 D_word(inst); // Deposit instr
1588 ea0gen(siz); // Generate ea0
1590 // Generate ea1 if requested
1595 // If we're called from chk2 then bit 11 of size will be set. This is just
1596 // a dumb mechanism to pass this, required by the extension word. (You might
1597 // have noticed the siz & 15 thing above!)
1598 inst = (a1reg << 12) | (siz & (1 << 11));
1610 // chk2 (68020, 68030, 68040, CPU32)
1612 int m_chk2(WORD inst, WORD siz)
1614 return m_cmp2(inst, siz | (1 << 11));
1619 // cpbcc(68020, 68030)
1621 int m_cpbr(WORD inst, WORD siz)
1623 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1624 return error(unsupport);
1626 if (a0exattr & DEFINED)
1628 if ((a0exattr & TDB) != cursect)
1629 return error(rel_error);
1631 uint32_t v = a0exval - (sloc + 2);
1633 // Optimize branch instr. size
1636 if ((v != 0) && ((v + 0x8000) < 0x10000))
1646 if ((v + 0x8000) >= 0x10000)
1647 return error(range_error);
1655 else if (siz == SIZN)
1662 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1670 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1679 // cpdbcc(68020, 68030)
1681 int m_cpdbr(WORD inst, WORD siz)
1686 WORD condition = inst & 0x1f; // Grab condition sneakily placed in the lower 5 bits of inst
1687 inst &= 0xffe0; // And then mask them out - you ain't seen me, roit?
1689 inst |= (1 << 9); // Bolt on FPU id
1696 if (a1exattr & DEFINED)
1698 if ((a1exattr & TDB) != cursect)
1699 return error(rel_error);
1703 if (v + 0x8000 > 0x10000)
1704 return error(range_error);
1710 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
1722 int m_divs(WORD inst, WORD siz)
1724 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1725 return error(unsupport);
1727 WORD flg = inst; // Save flag bits
1728 inst &= ~0x3F; // Clobber flag bits in instr
1730 // Install "standard" instr size bits
1736 // OR-in register number
1738 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1740 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1746 inst |= am1 | a1reg; // Get ea1 into instr
1747 D_word(inst); // Deposit instr
1749 // Generate ea0 if requested
1753 ea1gen(siz); // Generate ea1
1758 inst |= am0 | a0reg; // Get ea0 into instr
1759 D_word(inst); // Deposit instr
1760 ea0gen(siz); // Generate ea0
1762 // Generate ea1 if requested
1767 inst = a1reg + (a2reg << 12) + (1 << 11);
1777 int m_muls(WORD inst, WORD siz)
1779 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1780 return error(unsupport);
1782 WORD flg = inst; // Save flag bits
1783 inst &= ~0x3F; // Clobber flag bits in instr
1785 // Install "standard" instr size bits
1791 // OR-in register number
1793 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1795 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1801 inst |= am1 | a1reg; // Get ea1 into instr
1802 D_word(inst); // Deposit instr
1805 inst = a1reg + (a2reg << 12) + (1 << 11);
1806 inst |= mulmode; // add size bit
1809 // Generate ea0 if requested
1813 ea1gen(siz); // Generate ea1
1818 inst |= am0 | a0reg; // Get ea0 into instr
1819 D_word(inst); // Deposit instr
1821 inst = a1reg + (a2reg << 12) + (1 << 11);
1822 inst |= mulmode; // add size bit
1825 ea0gen(siz); // Generate ea0
1827 // Generate ea1 if requested
1842 int m_divu(WORD inst, WORD siz)
1844 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1845 return error(unsupport);
1847 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1849 WORD flg = inst; // Save flag bits
1850 inst &= ~0x3F; // Clobber flag bits in instr
1852 // Install "standard" instr size bits
1858 // OR-in register number
1860 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1862 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1868 inst |= am1 | a1reg; // Get ea1 into instr
1869 D_word(inst); // Deposit instr
1871 // Generate ea0 if requested
1875 ea1gen(siz); // Generate ea1
1880 inst |= am0 | a0reg; // Get ea0 into instr
1881 D_word(inst); // Deposit instr
1882 ea0gen(siz); // Generate ea0
1884 // Generate ea1 if requested
1889 inst = a1reg + (a2reg << 12);
1899 int m_mulu(WORD inst, WORD siz)
1901 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1902 return error(unsupport);
1904 WORD flg = inst; // Save flag bits
1905 inst &= ~0x3F; // Clobber flag bits in instr
1907 // Install "standard" instr size bits
1913 // OR-in register number
1915 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1917 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1923 inst |= am1 | a1reg; // Get ea1 into instr
1924 D_word(inst); // Deposit instr
1926 // Generate ea0 if requested
1930 ea1gen(siz); // Generate ea1
1935 inst |= am0 | a0reg; // Get ea0 into instr
1936 D_word(inst); // Deposit instr
1937 ea0gen(siz); // Generate ea0
1939 // Generate ea1 if requested
1944 inst = a1reg + (a2reg << 12);
1945 inst |= mulmode; // add size bit
1955 int m_divsl(WORD inst, WORD siz)
1957 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1958 return error(unsupport);
1960 WORD flg = inst; // Save flag bits
1961 inst &= ~0x3F; // Clobber flag bits in instr
1963 // Install "standard" instr size bits
1969 // OR-in register number
1971 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1973 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1979 inst |= am1 | a1reg; // Get ea1 into instr
1980 D_word(inst); // Deposit instr
1982 // Generate ea0 if requested
1986 ea1gen(siz); // Generate ea1
1991 inst |= am0 | a0reg; // Get ea0 into instr
1992 D_word(inst); // Deposit instr
1993 ea0gen(siz); // Generate ea0
1995 // Generate ea1 if requested
2000 inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
2009 int m_divul(WORD inst, WORD siz)
2011 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
2012 return error(unsupport);
2014 WORD flg = inst; // Save flag bits
2015 inst &= ~0x3F; // Clobber flag bits in instr
2017 // Install "standard" instr size bits
2023 // OR-in register number
2025 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2027 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2033 inst |= am1 | a1reg; // Get ea1 into instr
2034 D_word(inst); // Deposit instr
2036 // Generate ea0 if requested
2040 ea1gen(siz); // Generate ea1
2045 inst |= am0 | a0reg; // Get ea0 into instr
2046 D_word(inst); // Deposit instr
2047 ea0gen(siz); // Generate ea0
2049 // Generate ea1 if requested
2054 inst = a1reg + (a2reg << 12) + (1 << 10);
2062 // move16 (ax)+,(ay)+
2064 int m_move16a(WORD inst, WORD siz)
2066 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2067 return error(unsupport);
2071 inst = (1 << 15) + (a1reg << 12);
2079 // move16 with absolute address
2081 int m_move16b(WORD inst, WORD siz)
2083 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2084 return error(unsupport);
2090 if (am0 == APOSTINC)
2093 return error("Wasn't this suppose to call m_move16a???");
2096 //move16 (ax)+,(xxx).L
2101 else if (am0 == ABSL)
2105 //move16 (xxx).L,(ax)+
2111 //move16 (xxx).L,(ax)
2116 else if (am0 == AIND)
2118 //move16 (ax),(xxx).L
2131 // pack/unpack (68020/68030/68040)
2133 int m_pack(WORD inst, WORD siz)
2138 return error("bad size suffix");
2140 if (*tok >= KW_D0 && *tok <= KW_D7)
2142 // Dx,Dy,#<adjustment>
2143 inst |= (0 << 3); // R/M
2144 inst |= (*tok++ & 7);
2145 if (*tok != ',' && tok[2] != ',')
2146 return error("missing comma");
2147 if (tok[1] < KW_D0 && tok[1] > KW_D7)
2148 return error(syntax_error);
2149 inst |= ((tok[1] & 7)<<9);
2152 // Fall through for adjustment (common in both valid cases)
2154 else if (*tok == '-')
2156 // -(Ax),-(Ay),#<adjustment>
2157 inst |= (1 << 3); // R/M
2158 tok++; // eat the minus
2159 if ((*tok != '(') && (tok[2]!=')') && (tok[3]!=',') && (tok[4] != '-') && (tok[5] != '(') && (tok[7] != ')') && (tok[8] != ','))
2160 return error(syntax_error);
2161 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2162 return error(syntax_error);
2163 if (tok[5] < KW_A0 && tok[6] > KW_A7)
2164 return error(syntax_error);
2165 inst |= ((tok[1] & 7) << 0);
2166 inst |= ((tok[6] & 7) << 9);
2169 // Fall through for adjustment (common in both valid cases)
2172 return error("invalid syntax");
2175 if ((*tok != CONST) && (*tok != SYMBOL) && (*tok != '-'))
2176 return error(syntax_error);
2178 if (expr(a0expr, &a0exval, &a0exattr, &a0esym)==ERROR)
2181 if ((a0exattr & DEFINED) == 0)
2182 return error(undef_error);
2184 if (a0exval + 0x8000 > 0x10000)
2188 return error(extra_stuff);
2190 D_word((a0exval & 0xffff));
2202 int m_rtm(WORD inst, WORD siz)
2210 else if (am0 == AREG)
2212 inst |= (1 << 3) + a0reg;
2215 return error("rtm only allows data or address registers.");
2226 int m_rtd(WORD inst, WORD siz)
2230 if (a0exattr & DEFINED)
2233 return error(abs_error);
2235 if ((a0exval + 0x8000) <= 0x7FFF)
2236 return error(range_error);
2242 return error(undef_error);
2251 int m_trapcc(WORD inst, WORD siz)
2259 else if (am0 == IMMED)
2263 if (a0exval < 0x10000)
2270 return error("Immediate value too big");
2280 return error("Invalid parameter for trapcc");
2287 // cinvl/p/a (68040)
2289 int m_cinv(WORD inst, WORD siz)
2294 inst |= (0 << 6) | (a1reg);
2298 inst |= (2 << 6) | (a1reg);
2301 inst |= (1 << 6) | (a1reg);
2304 inst |= (3 << 6) | (a1reg);
2314 // cpRESTORE (68020, 68030)
2316 int m_cprest(WORD inst, WORD siz)
2318 if (activecpu & !(CPU_68020 | CPU_68030))
2319 return error(unsupport);
2321 inst |= am0 | a0reg;
2330 // movec (68010, 68020, 68030, 68040, CPU32)
2332 int m_movec(WORD inst, WORD siz)
2336 if (am0 == DREG || am0 == AREG)
2344 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
2349 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
2360 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
2365 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2375 // moves (68010, 68020, 68030, 68040, CPU32)
2377 int m_moves(WORD inst, WORD siz)
2379 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2380 return error(unsupport);
2386 else if (siz == SIZL)
2397 inst |= am1 | a1reg;
2399 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2402 else if (am0 == AREG)
2404 inst |= am1 | a1reg;
2406 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2413 inst |= am0 | a0reg;
2415 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2420 inst |= am0 | a0reg;
2422 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2434 int m_pbcc(WORD inst, WORD siz)
2437 return error("Not implemented yet.");
2442 // pflusha (68030, 68040)
2444 int m_pflusha(WORD inst, WORD siz)
2446 if (activecpu == CPU_68030)
2449 inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
2453 else if (activecpu == CPU_68040)
2455 inst = B16(11110101, 00011000);
2460 return error(unsupport);
2468 // pflush (68030, 68040, 68060)
2470 int m_pflush(WORD inst, WORD siz)
2472 if (activecpu == CPU_68030)
2475 // PFLUSH FC, MASK, < ea >
2481 if (*tok != CONST && *tok != SYMBOL)
2482 return error("function code should be an expression");
2483 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2485 if ((a0exattr & DEFINED) == 0)
2486 return error("function code immediate should be defined");
2487 if (a0exval > 7 && a0exval < 0)
2488 return error("function code out of range (0-7)");
2499 fc = (1 << 4) | (*tok++ & 7);
2510 return error(syntax_error);
2514 return error("comma exptected");
2517 return error("mask should be an immediate value");
2518 if (*tok != CONST && *tok != SYMBOL)
2519 return error("mask is supposed to be immediate");
2520 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2522 if ((a0exattr & DEFINED) == 0)
2523 return error("mask immediate value should be defined");
2524 if (a0exval > 7 && a0exval < 0)
2525 return error("function code out of range (0-7)");
2526 mask = a0exval << 5;
2532 inst = (1 << 13) | fc | mask | (4 << 10);
2536 else if (*tok == ',')
2538 // PFLUSH FC, MASK, < ea >
2540 if (amode(0) == ERROR)
2543 return error(extra_stuff);
2544 if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE)
2546 inst |= am0 | a0reg;
2548 inst = (1 << 13) | fc | mask | (6 << 10);
2554 return error("unsupported addressing mode");
2558 return error(syntax_error);
2563 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2567 if (*tok != '(' && tok[2] != ')')
2568 return error(syntax_error);
2569 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2570 return error("expected (An)");
2571 if ((inst & 7) == 7)
2572 // With pflushn/pflush there's no easy way to
2573 // distinguish between the two in 68040 mode.
2574 // Ideally the opcode bitfields would have been
2575 // hardcoded in 68ktab but there is aliasing
2576 // between 68030 and 68040 opcode. So we just
2577 // set the 3 lower bits to 1 in pflushn inside
2578 // 68ktab and detect it here.
2579 inst = (inst & 0xff8) | 8;
2580 inst |= (tok[1] & 7) | (5 << 8);
2582 return error(extra_stuff);
2586 return error(unsupport);
2595 int m_pflushr(WORD inst, WORD siz)
2599 WORD flg = inst; // Save flag bits
2600 inst &= ~0x3F; // Clobber flag bits in instr
2602 // Install "standard" instr size bits
2608 // OR-in register number
2610 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2612 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2618 inst |= am1 | a1reg; // Get ea1 into instr
2619 D_word(inst); // Deposit instr
2621 // Generate ea0 if requested
2625 ea1gen(siz); // Generate ea1
2630 inst |= am0 | a0reg; // Get ea0 into instr
2631 D_word(inst); // Deposit instr
2632 ea0gen(siz); // Generate ea0
2634 // Generate ea1 if requested
2639 D_word(B16(10100000, 00000000));
2645 // ploadr, ploadw (68030)
2647 int m_pload(WORD inst, WORD siz, WORD extension)
2649 // TODO: 68551 support is not added yet.
2650 // None of the ST series of computers had
2651 // a 68020 + 68551 socket and since this is
2652 // an Atari targetted assembler....
2662 if (a0reg == KW_SFC - KW_SFC)
2666 else if (a0reg == KW_DFC - KW_SFC)
2671 return error("illegal control register specified");
2674 inst = (1 << 3) | a0reg;
2677 if ((a0exattr & DEFINED) == 0)
2678 return error("constant value must be defined");
2679 inst = (2 << 3) | a0exval;
2683 inst |= extension | (1 << 13);
2691 int m_ploadr(WORD inst, WORD siz)
2693 return m_pload(inst, siz, 1 << 9);
2696 int m_ploadw(WORD inst, WORD siz)
2698 return m_pload(inst, siz, 0 << 9);
2702 // pmove (68030/68551)
2704 int m_pmove(WORD inst, WORD siz)
2708 // TODO: 68551 support is not added yet.
2709 // None of the ST series of computers had
2710 // a 68020 + 68551 socket and since this is
2711 // an Atari targetted assembler....
2712 // (same for 68EC030)
2715 inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2716 inst &= ~(1 << 8); //And mask it out
2723 else if (am1 == CREG)
2729 return error("pmove sez: Wut?");
2731 // The instruction is a quad-word (8 byte) operation
2732 // for the CPU root pointer and the supervisor root pointer.
2733 // It is a long - word operation for the translation control register
2734 // and the transparent translation registers(TT0 and TT1).
2735 // It is a word operation for the MMU status register.
2737 if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
2738 && ((siz != SIZD) && (siz != SIZN)))
2739 return error(siz_error);
2741 if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
2742 && ((siz != SIZL) && (siz != SIZN)))
2743 return error(siz_error);
2745 if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
2746 return error(siz_error);
2751 inst |= am1 | a1reg;
2754 else if (am1 == CREG)
2756 inst |= am0 | a0reg;
2760 switch (reg + KW_SFC)
2763 inst2 |= (0 << 10) + (1 << 14); break;
2765 inst2 |= (2 << 10) + (1 << 14); break;
2767 inst2 |= (3 << 10) + (1 << 14); break;
2769 inst2 |= (2 << 10) + (0 << 13); break;
2771 inst2 |= (3 << 10) + (0 << 13); break;
2774 inst2 |= (1 << 9) + (3 << 13);
2776 inst2 |= (0 << 9) + (3 << 13);
2779 return error("unsupported register");
2789 else if (am1 == CREG)
2801 int m_pmovefd(WORD inst, WORD siz)
2805 return m_pmove(inst | (1 << 8), siz);
2812 #define gen_ptrapcc(name,opcode) \
2813 int m_##name(WORD inst, WORD siz) \
2819 D_word(B8(opcode)); \
2826 D_word(B8(opcode)); \
2831 int m_##name##n(WORD inst, WORD siz) \
2835 D_word(B8(opcode)); \
2839 gen_ptrapcc(ptrapbs,00000000)
2840 gen_ptrapcc(ptrapbc,00000001)
2841 gen_ptrapcc(ptrapls,00000010)
2842 gen_ptrapcc(ptraplc,00000011)
2843 gen_ptrapcc(ptrapss,00000100)
2844 gen_ptrapcc(ptrapsc,00000101)
2845 gen_ptrapcc(ptrapas,00000110)
2846 gen_ptrapcc(ptrapac,00000111)
2847 gen_ptrapcc(ptrapws,00001000)
2848 gen_ptrapcc(ptrapwc,00001001)
2849 gen_ptrapcc(ptrapis,00001010)
2850 gen_ptrapcc(ptrapic,00001011)
2851 gen_ptrapcc(ptrapgc,00001100)
2852 gen_ptrapcc(ptrapgs,00001101)
2853 gen_ptrapcc(ptrapcs,00001110)
2854 gen_ptrapcc(ptrapcc,00001111)
2856 //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; }
2857 //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; }
2858 //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; }
2859 //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; }
2860 //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; }
2861 //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; }
2862 //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; }
2863 //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; }
2864 //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; }
2865 //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; }
2866 //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; }
2867 //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; }
2868 //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; }
2869 //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; }
2870 //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; }
2871 //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; }
2872 //int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2873 //int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2874 //int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2875 //int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2876 //int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2877 //int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2878 //int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2879 //int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2880 //int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2881 //int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2882 //int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2883 //int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2884 //int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2885 //int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2886 //int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2887 //int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2891 // ptestr, ptestw (68030)
2893 int m_ptest(WORD inst, WORD siz)
2897 if (activecpu == CPU_68030)
2898 return error("Not implemented yet.");
2899 else if (activecpu == CPU_68040)
2900 return error("Not implemented yet.");
2906 #define FPU_NOWARN 0
2907 #define FPU_P_EMUL 1
2908 #define FPU_P2_EMU 2
2913 // Generate a FPU opcode
2915 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2917 if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
2919 inst |= (1 << 9); // Bolt on FPU id
2926 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2930 case SIZB: inst |= (6 << 10); break;
2931 case SIZW: inst |= (4 << 10); break;
2932 case SIZL: inst |= (0 << 10); break;
2934 case SIZS: inst |= (1 << 10); break;
2935 case SIZD: inst |= (5 << 10); break;
2936 case SIZX: inst |= (2 << 10); break;
2941 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2945 return error("Something bad happened, possibly, in gen_fpu.");
2949 inst |= (a1reg << 7);
2956 inst |= (1 << 9); //Bolt on FPU id
2960 inst |= (a1reg << 7);
2965 if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
2966 warn("Instruction is emulated in 68040");
2973 // fabs, fsabs, fdabs (6888X, 68040)
2975 int m_fabs(WORD inst, WORD siz)
2977 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2981 int m_fsabs(WORD inst, WORD siz)
2983 if (activefpu == FPU_68040)
2984 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2986 return error("Unsupported in current FPU");
2990 int m_fdabs(WORD inst, WORD siz)
2992 if (activefpu == FPU_68040)
2993 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2995 return error("Unsupported in current FPU");
3000 // facos (6888X, 68040FPSP)
3002 int m_facos(WORD inst, WORD siz)
3004 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
3009 // fadd (6888X, 68040FPSP)
3011 int m_fadd(WORD inst, WORD siz)
3013 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
3017 int m_fsadd(WORD inst, WORD siz)
3019 if (activefpu == FPU_68040)
3020 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
3022 return error("Unsupported in current FPU");
3026 int m_fdadd(WORD inst, WORD siz)
3028 if (activefpu == FPU_68040)
3029 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
3031 return error("Unsupported in current FPU");
3036 // fasin (6888X, 68040FPSP)f
3038 int m_fasin(WORD inst, WORD siz)
3040 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
3045 // fatan (6888X, 68040FPSP)
3047 int m_fatan(WORD inst, WORD siz)
3049 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
3054 // fatanh (6888X, 68040FPSP)
3056 int m_fatanh(WORD inst, WORD siz)
3058 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
3063 // fcmp (6888X, 68040)
3065 int m_fcmp(WORD inst, WORD siz)
3067 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
3072 // fcos (6888X, 68040FPSP)
3074 int m_fcos(WORD inst, WORD siz)
3076 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
3081 // fcosh (6888X, 68040FPSP)
3083 int m_fcosh(WORD inst, WORD siz)
3085 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
3090 // fdbcc (6888X, 68040)
3092 int m_fdbcc(WORD inst, WORD siz)
3094 WORD opcode = inst & 0x3F; //Grab conditional bitfield
3104 if (a1exattr & DEFINED)
3106 if ((a1exattr & TDB) != cursect)
3107 return error(rel_error);
3109 uint32_t v = a1exval - sloc;
3111 if ((v + 0x8000) > 0x10000)
3112 return error(range_error);
3118 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
3127 // fdiv (6888X, 68040)
3129 int m_fdiv(WORD inst, WORD siz)
3131 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
3135 int m_fsdiv(WORD inst, WORD siz)
3137 if (activefpu == FPU_68040)
3138 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
3140 return error("Unsupported in current FPU");
3144 int m_fddiv(WORD inst, WORD siz)
3146 if (activefpu == FPU_68040)
3147 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3149 return error("Unsupported in current FPU");
3154 // fetox (6888X, 68040FPSP)
3156 int m_fetox(WORD inst, WORD siz)
3158 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
3163 // fetoxm1 (6888X, 68040FPSP)
3165 int m_fetoxm1(WORD inst, WORD siz)
3167 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
3172 // fgetexp (6888X, 68040FPSP)
3174 int m_fgetexp(WORD inst, WORD siz)
3176 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
3181 // fgetman (6888X, 68040FPSP)
3183 int m_fgetman(WORD inst, WORD siz)
3185 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
3190 // fint (6888X, 68040FPSP)
3192 int m_fint(WORD inst, WORD siz)
3195 // special case - fint fpx = fint fpx,fpx
3198 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
3203 // fintrz (6888X, 68040FPSP)
3205 int m_fintrz(WORD inst, WORD siz)
3208 // special case - fintrz fpx = fintrz fpx,fpx
3211 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
3216 // flog10 (6888X, 68040FPSP)
3218 int m_flog10(WORD inst, WORD siz)
3220 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
3225 // flog2 (6888X, 68040FPSP)
3227 int m_flog2(WORD inst, WORD siz)
3229 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
3234 // flogn (6888X, 68040FPSP)
3236 int m_flogn(WORD inst, WORD siz)
3238 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
3243 // flognp1 (6888X, 68040FPSP)
3245 int m_flognp1(WORD inst, WORD siz)
3247 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
3252 // fmod (6888X, 68040FPSP)
3254 int m_fmod(WORD inst, WORD siz)
3256 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
3261 // fmove (6888X, 68040)
3263 int m_fmove(WORD inst, WORD siz)
3267 if ((am0 == FREG) && (am1 < AM_USP))
3271 inst |= am1 | a1reg;
3280 case SIZB: inst |= (6 << 10); break;
3281 case SIZW: inst |= (4 << 10); break;
3282 case SIZL: inst |= (0 << 10); break;
3284 case SIZS: inst |= (1 << 10); break;
3285 case SIZD: inst |= (5 << 10); break;
3286 case SIZX: inst |= (2 << 10); break;
3287 case SIZP: inst |= (3 << 10);
3288 // In P size we have 2 cases: {#k} where k is immediate
3289 // and {Dn} where Dn=Data register
3295 inst |= bfval1 << 4;
3300 if (bfval1>63 && bfval1<-64)
3301 return error("K-factor must be between -64 and 63");
3302 inst |= bfval1 & 127;
3307 return error("Something bad happened, possibly.");
3312 // Destination specifier
3313 inst |= (a0reg << 7);
3321 else if ((am0 < AM_USP) && (am1 == FREG))
3326 inst |= am0 | a0reg;
3335 case SIZB: inst |= (6 << 10); break;
3336 case SIZW: inst |= (4 << 10); break;
3337 case SIZL: inst |= (0 << 10); break;
3339 case SIZS: inst |= (1 << 10); break;
3340 case SIZD: inst |= (5 << 10); break;
3341 case SIZX: inst |= (2 << 10); break;
3342 case SIZP: inst |= (3 << 10); break;
3344 return error("Something bad happened, possibly.");
3348 // Destination specifier
3349 inst |= (a1reg << 7);
3357 else if ((am0 == FREG) && (am1 == FREG))
3359 // register-to-register
3360 // Essentially ea to register with R/0=0
3370 return error("Invalid size");
3373 inst |= (a0reg << 10);
3375 // Destination register
3376 inst |= (a1reg << 7);
3386 // fmove (6888X, 68040)
3388 int m_fmovescr(WORD inst, WORD siz)
3390 // Move Floating-Point System Control Register (FPCR)
3394 if ((am0 == FPSCR) && (am1 < AM_USP))
3396 inst |= am1 | a1reg;
3398 inst = (1 << 13) + (1 << 15);
3404 else if ((am1 == FPSCR) && (am0 < AM_USP))
3406 inst |= am0 | a0reg;
3408 inst = (0 << 13) + (1 << 15);
3415 return error("m_fmovescr says: wut?");
3419 // fsmove/fdmove (68040)
3421 int m_fsmove(WORD inst, WORD siz)
3423 return error("Not implemented yet.");
3426 if (activefpu == FPU_68040)
3427 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3429 return error("Unsupported in current FPU");
3434 int m_fdmove(WORD inst, WORD siz)
3436 return error("Not implemented yet.");
3439 if (activefpu == FPU_68040)
3440 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3442 return error("Unsupported in current FPU");
3448 // fmovecr (6888X, 68040FPSP)
3450 int m_fmovecr(WORD inst, WORD siz)
3458 if (activefpu == FPU_68040)
3459 warn("Instruction is emulated in 68040");
3466 // fmovem (6888X, 68040)
3468 int m_fmovem(WORD inst, WORD siz)
3473 if (siz == SIZX || siz==SIZN)
3475 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3477 //fmovem.x <rlist>,ea
3478 if (fpu_reglist_left(®mask) < 0)
3482 return error("missing comma");
3487 inst |= am0 | a0reg;
3489 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3490 return error("invalid addressing mode");
3493 inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
3498 else if ((*tok >= KW_D0) && (*tok <= KW_D7))
3501 datareg = (*tok++ & 7) << 10;
3504 return error("missing comma");
3509 inst |= am0 | a0reg;
3511 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3512 return error("invalid addressing mode");
3515 inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
3526 inst |= am0 | a0reg;
3529 return error("missing comma");
3531 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3533 //fmovem.x ea,<rlist>
3534 if (fpu_reglist_right(®mask) < 0)
3538 inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
3546 datareg = (*tok++ & 7) << 10;
3548 inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
3555 else if (siz == SIZL)
3557 if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
3559 //fmovem.l <rlist>,ea
3560 regmask = (1 << 15) | (1 << 13);
3562 if (*tok == KW_FPCR)
3564 regmask |= (1 << 12);
3569 if (*tok == KW_FPSR)
3571 regmask |= (1 << 11);
3576 if (*tok == KW_FPIAR)
3578 regmask |= (1 << 10);
3583 if ((*tok == '/') || (*tok == '-'))
3590 return error("missing comma");
3595 inst |= am0 | a0reg;
3602 //fmovem.l ea,<rlist>
3606 inst |= am0 | a0reg;
3609 return error("missing comma");
3611 regmask = (1 << 15) | (0 << 13);
3614 if (*tok == KW_FPCR)
3616 regmask |= (1 << 12);
3621 if (*tok == KW_FPSR)
3623 regmask |= (1 << 11);
3628 if (*tok == KW_FPIAR)
3630 regmask |= (1 << 10);
3635 if ((*tok == '/') || (*tok == '-'))
3642 return error("extra (unexpected) text found");
3644 inst |= am0 | a0reg;
3651 return error("bad size suffix");
3658 // fmul (6888X, 68040)
3660 int m_fmul(WORD inst, WORD siz)
3662 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
3666 int m_fsmul(WORD inst, WORD siz)
3668 if (activefpu == FPU_68040)
3669 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
3671 return error("Unsupported in current FPU");
3675 int m_fdmul(WORD inst, WORD siz)
3677 if (activefpu == FPU_68040)
3678 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
3680 return error("Unsupported in current FPU");
3685 // fneg (6888X, 68040)
3687 int m_fneg(WORD inst, WORD siz)
3689 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
3693 int m_fsneg(WORD inst, WORD siz)
3695 if (activefpu == FPU_68040)
3696 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
3698 return error("Unsupported in current FPU");
3702 int m_fdneg(WORD inst, WORD siz)
3704 if (activefpu == FPU_68040)
3705 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
3707 return error("Unsupported in current FPU");
3712 // fnop (6888X, 68040)
3714 int m_fnop(WORD inst, WORD siz)
3716 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3721 // frem (6888X, 68040FPSP)
3723 int m_frem(WORD inst, WORD siz)
3725 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3730 // fscale (6888X, 68040FPSP)
3732 int m_fscale(WORD inst, WORD siz)
3734 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3739 // FScc (6888X, 68040)
3741 //int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3742 //int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3743 //int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3744 //int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3745 //int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3746 //int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3747 //int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3748 //int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3749 //int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3750 //int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3751 //int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3752 //int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3753 //int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3754 //int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3755 //int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3756 //int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3757 //int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3758 //int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3759 //int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3760 //int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3761 //int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3762 //int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3763 //int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3764 //int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3765 //int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3766 //int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3767 //int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3768 //int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3769 //int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3770 //int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3771 //int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3772 //int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3774 #define gen_FScc(name, opcode) int m_##name (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(opcode)); return OK;}
3775 gen_FScc(fseq , 00000001);
3776 gen_FScc(fsne , 00001110);
3777 gen_FScc(fsgt , 00010010);
3778 gen_FScc(fsngt , 00011101);
3779 gen_FScc(fsge , 00010011);
3780 gen_FScc(fsnge , 00011100);
3781 gen_FScc(fslt , 00010100);
3782 gen_FScc(fsnlt , 00011011);
3783 gen_FScc(fsle , 00010101);
3784 gen_FScc(fsnle , 00011010);
3785 gen_FScc(fsgl , 00010110);
3786 gen_FScc(fsngl , 00011001);
3787 gen_FScc(fsgle , 00010111);
3788 gen_FScc(fsngle, 00011000);
3789 gen_FScc(fsogt , 00000010);
3790 gen_FScc(fsule , 00001101);
3791 gen_FScc(fsoge , 00000011);
3792 gen_FScc(fsult , 00001100);
3793 gen_FScc(fsolt , 00000100);
3794 gen_FScc(fsuge , 00001011);
3795 gen_FScc(fsole , 00000101);
3796 gen_FScc(fsugt , 00001010);
3797 gen_FScc(fsogl , 00000110);
3798 gen_FScc(fsueq , 00001001);
3799 gen_FScc(fsor , 00000111);
3800 gen_FScc(fsun , 00001000);
3801 gen_FScc(fsf , 00000000);
3802 gen_FScc(fst , 00001111);
3803 gen_FScc(fssf , 00010000);
3804 gen_FScc(fsst , 00011111);
3805 gen_FScc(fsseq , 00010001);
3806 gen_FScc(fssne , 00011110);
3809 // FTRAPcc (6888X, 68040)
3811 //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;}
3812 //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;}
3813 //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;}
3814 //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;}
3815 //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;}
3816 //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;}
3817 //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;}
3818 //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;}
3819 //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;}
3820 //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;}
3821 //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;}
3822 //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;}
3823 //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;}
3824 //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;}
3825 //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;}
3826 //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;}
3827 //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;}
3828 //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;}
3829 //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;}
3830 //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;}
3831 //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;}
3832 //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;}
3833 //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;}
3834 //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;}
3835 //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;}
3836 //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;}
3837 //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;}
3838 //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;}
3839 //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;}
3840 //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;}
3841 //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;}
3842 //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;}
3844 //int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3845 //int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3846 //int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3847 //int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3848 //int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3849 //int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3850 //int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3851 //int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3852 //int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3853 //int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3854 //int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3855 //int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3856 //int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3857 //int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3858 //int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3859 //int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3860 //int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3861 //int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3862 //int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3863 //int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3864 //int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3865 //int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3866 //int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3867 //int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3868 //int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3869 //int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3870 //int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3871 //int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3872 //int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3873 //int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3874 //int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3875 //int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3877 #define gen_FTRAPcc(name,opcode) \
3878 int m_##name (WORD inst, WORD siz) \
3883 D_word(B8(opcode)); \
3890 D_word(B8(opcode)); \
3895 int m_##name##n (WORD inst, WORD siz) \
3898 D_word(B8(opcode)); \
3902 gen_FTRAPcc(ftrapeq ,00000001)
3903 gen_FTRAPcc(ftrapne ,00001110)
3904 gen_FTRAPcc(ftrapgt ,00010010)
3905 gen_FTRAPcc(ftrapngt ,00011101)
3906 gen_FTRAPcc(ftrapge ,00010011)
3907 gen_FTRAPcc(ftrapnge ,00011100)
3908 gen_FTRAPcc(ftraplt ,00010100)
3909 gen_FTRAPcc(ftrapnlt ,00011011)
3910 gen_FTRAPcc(ftraple ,00010101)
3911 gen_FTRAPcc(ftrapnle ,00011010)
3912 gen_FTRAPcc(ftrapgl ,00010110)
3913 gen_FTRAPcc(ftrapngl ,00011001)
3914 gen_FTRAPcc(ftrapgle ,00010111)
3915 gen_FTRAPcc(ftrapngle ,00011000)
3916 gen_FTRAPcc(ftrapogt ,00000010)
3917 gen_FTRAPcc(ftrapule ,00001101)
3918 gen_FTRAPcc(ftrapoge ,00000011)
3919 gen_FTRAPcc(ftrapult ,00001100)
3920 gen_FTRAPcc(ftrapolt ,00000100)
3921 gen_FTRAPcc(ftrapuge ,00001011)
3922 gen_FTRAPcc(ftrapole ,00000101)
3923 gen_FTRAPcc(ftrapugt ,00001010)
3924 gen_FTRAPcc(ftrapogl ,00000110)
3925 gen_FTRAPcc(ftrapueq ,00001001)
3926 gen_FTRAPcc(ftrapor ,00000111)
3927 gen_FTRAPcc(ftrapun ,00001000)
3928 gen_FTRAPcc(ftrapf ,00000000)
3929 gen_FTRAPcc(ftrapt ,00001111)
3930 gen_FTRAPcc(ftrapsf ,00010000)
3931 gen_FTRAPcc(ftrapst ,00011111)
3932 gen_FTRAPcc(ftrapseq ,00010001)
3933 gen_FTRAPcc(ftrapsne ,00011110)
3936 // fsgldiv (6888X, 68040)
3938 int m_fsgldiv(WORD inst, WORD siz)
3940 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3945 // fsglmul (6888X, 68040)
3947 int m_fsglmul(WORD inst, WORD siz)
3949 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3954 // fsin (6888X, 68040FPSP)
3956 int m_fsin(WORD inst, WORD siz)
3958 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3963 // fsincos (6888X, 68040FPSP)
3965 int m_fsincos(WORD inst, WORD siz)
3967 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
3978 // fsin (6888X, 68040FPSP)
3980 int m_fsinh(WORD inst, WORD siz)
3982 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3987 // fsqrt (6888X, 68040)
3989 int m_fsqrt(WORD inst, WORD siz)
3991 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3995 int m_fsfsqrt(WORD inst, WORD siz)
3997 if (activefpu == FPU_68040)
3998 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
4000 return error("Unsupported in current FPU");
4004 int m_fdfsqrt(WORD inst, WORD siz)
4006 if (activefpu == FPU_68040)
4007 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
4009 return error("Unsupported in current FPU");
4014 // fsub (6888X, 68040)
4016 int m_fsub(WORD inst, WORD siz)
4018 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
4022 int m_fsfsub(WORD inst, WORD siz)
4024 if (activefpu == FPU_68040)
4025 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
4027 return error("Unsupported in current FPU");
4031 int m_fdsub(WORD inst, WORD siz)
4033 if (activefpu == FPU_68040)
4034 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
4036 return error("Unsupported in current FPU");
4041 // ftan (6888X, 68040FPSP)
4043 int m_ftan(WORD inst, WORD siz)
4045 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
4050 // ftanh (6888X, 68040FPSP)
4052 int m_ftanh(WORD inst, WORD siz)
4054 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
4059 // ftentox (6888X, 68040FPSP)
4061 int m_ftentox(WORD inst, WORD siz)
4063 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
4068 // ftst (6888X, 68040)
4070 int m_ftst(WORD inst, WORD siz)
4072 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
4077 // ftwotox (6888X, 68040FPSP)
4079 int m_ftwotox(WORD inst, WORD siz)
4081 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);