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 // N.B.: We can get away with casting the uint64_t to a 32-bit value
826 // because it checks for a SIZL (i.e., a 32-bit value).
827 if (CHECK_OPTS(OPT_MOVEL_MOVEQ)
828 && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
829 && ((a0exattr & (TDB | DEFINED)) == DEFINED)
830 && ((uint32_t)a0exval + 0x80 < 0x100))
832 m_moveq((WORD)0x7000, (WORD)0);
835 warn("move.l #size,dx converted to moveq");
839 if ((am0 < ABASE) && (am1 < ABASE)) //68000 modes
841 inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
849 ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
853 inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0 - ABASE];
869 // Handle MOVE <C_ALL030> <C_ALTDATA>
870 // MOVE <C_ALL030> <M_AREG>
872 int m_move30(WORD inst, WORD size)
875 // TODO: is extra_addressing necessary/correct?
876 //inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
877 inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg;
892 // move USP,An -- move An,USP
894 int m_usp(WORD inst, WORD siz)
899 inst |= a1reg; // USP, An
901 inst |= a0reg; // An, USP
912 int m_moveq(WORD inst, WORD siz)
916 // Arrange for future fixup
917 if (!(a0exattr & DEFINED))
919 AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
922 else if (a0exval + 0x100 >= 0x200)
923 return error(range_error);
925 inst |= reg_9[a1reg] | (a0exval & 0xFF);
933 // movep Dn, disp(An) -- movep disp(An), Dn
935 int m_movep(WORD inst, WORD siz)
937 // Tell ea0gen to lay off the 0(a0) optimisations on this one
945 inst |= reg_9[a0reg] | a1reg;
955 inst |= reg_9[a1reg] | a0reg;
972 int m_br(WORD inst, WORD siz)
976 if (a0exattr & DEFINED)
978 if ((a0exattr & TDB) != cursect)
980 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
981 return error(rel_error);
984 v = (uint32_t)a0exval - (sloc + 2);
986 // Optimize branch instr. size
989 if (CHECK_OPTS(OPT_BSR_BCC_S) && (v != 0) && ((v + 0x80) < 0x100))
996 warn("Bcc.w/BSR.w converted to .s");
1003 if ((v + 0x8000) > 0x10000)
1004 return error(range_error);
1012 if (siz == SIZB || siz == SIZS)
1014 if ((v + 0x80) >= 0x100)
1015 return error(range_error);
1022 if ((v + 0x8000) >= 0x10000)
1023 return error(range_error);
1031 else if (siz == SIZN)
1034 if (siz == SIZB || siz == SIZS)
1037 AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
1045 AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
1056 int m_addq(WORD inst, WORD siz)
1058 inst |= siz_6[siz] | am1 | a1reg;
1060 if (a0exattr & DEFINED)
1062 if ((a0exval > 8) || (a0exval == 0)) // Range in 1..8
1063 return error(range_error);
1065 inst |= (a0exval & 7) << 9;
1070 AddFixup(FU_QUICK, sloc, a0expr);
1083 int m_trap(WORD inst, WORD siz)
1087 if (a0exattr & DEFINED)
1090 return error(abs_error);
1093 return error(range_error);
1099 return error(undef_error);
1106 // movem <rlist>,ea -- movem ea,<rlist>
1108 int m_movem(WORD inst, WORD siz)
1116 return error("bad size suffix");
1123 // Handle #<expr>, ea
1126 if (abs_expr(&eval) != OK)
1129 if (eval >= 0x10000L)
1130 return error(range_error);
1136 if ((*tok >= KW_D0) && (*tok <= KW_A7))
1139 if (reglist(&rmask) < 0)
1144 return error("missing comma");
1149 inst |= am0 | a0reg;
1151 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
1152 return error("invalid addressing mode");
1154 // If APREDEC, reverse register mask
1160 for(i=0x8000; i; i>>=1, w>>=1)
1161 rmask = (WORD)((rmask << 1) | w & 1);
1170 inst |= 0x0400 | am0 | a0reg;
1173 return error("missing comma");
1176 return error("missing register list");
1183 if (abs_expr(&eval) != OK)
1186 if (eval >= 0x10000)
1187 return error(range_error);
1191 else if (reglist(&rmask) < 0)
1194 if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
1195 return error("invalid addressing mode");
1207 // CLR.x An ==> SUBA.x An,An
1209 int m_clra(WORD inst, WORD siz)
1211 inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
1218 ////////////////////////////////////////
1220 // 68020/30/40 instructions
1222 ////////////////////////////////////////
1227 int m_br30(WORD inst, WORD siz)
1229 if (a0exattr & DEFINED)
1231 if ((a0exattr & TDB) != cursect)
1232 return error(rel_error);
1234 uint32_t v = a0exval - (sloc + 2);
1243 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1251 // bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
1252 // (68020, 68030, 68040)
1254 int m_bfop(WORD inst, WORD siz)
1256 if ((bfval1 > 31) || (bfval1 < 0))
1257 return error("bfxxx offset: immediate value must be between 0 and 31");
1259 // First instruction word - just the opcode and first EA
1260 // Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
1267 if (bfval2 > 31 || bfval2 < 0)
1268 return error("bfxxx width: immediate value must be between 0 and 31");
1270 // For Dw both immediate and register number are stuffed
1271 // into the same field O_o
1272 bfparam2 = (bfval2 << 0);
1277 bfparam1 = (bfval1 << 6);
1281 bfparam1 = bfval1 << 12;
1284 D_word((inst | am0 | a0reg | am1 | a1reg));
1285 ea0gen(siz); // Generate EA
1287 // Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
1289 inst = bfparam1 | bfparam2;
1295 inst |= a0reg << 12;
1304 // bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
1306 int m_bkpt(WORD inst, WORD siz)
1310 if (a0exattr & DEFINED)
1313 return error(abs_error);
1316 return error(range_error);
1322 return error(undef_error);
1331 int m_callm(WORD inst, WORD siz)
1338 if (a0exattr & DEFINED)
1341 return error(abs_error);
1344 return error(range_error);
1350 return error(undef_error);
1360 // cas (68020, 68030, 68040)
1362 int m_cas(WORD inst, WORD siz)
1368 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1369 return error(unsupport);
1384 return error("bad size suffix");
1389 if ((*tok < KW_D0) && (*tok > KW_D7))
1390 return error("CAS accepts only data registers");
1392 inst2 = (*tok++) & 7;
1395 return error("missing comma");
1398 if ((*tok < KW_D0) && (*tok > KW_D7))
1399 return error("CAS accepts only data registers");
1401 inst2 |= ((*tok++) & 7) << 6;
1404 return error("missing comma");
1407 if ((modes = amode(1)) < 0)
1411 return error("too many ea fields");
1414 return error("extra (unexpected) text found");
1416 // Reject invalud ea modes
1417 amsk = amsktab[am0];
1419 if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
1420 return error("unsupported addressing mode");
1422 inst |= am0 | a0reg;
1432 // cas2 (68020, 68030, 68040)
1434 int m_cas2(WORD inst, WORD siz)
1438 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1439 return error(unsupport);
1454 return error("bad size suffix");
1459 if ((*tok < KW_D0) && (*tok > KW_D7))
1460 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1462 inst2 = (*tok++) & 7;
1465 return error("missing colon");
1468 if ((*tok < KW_D0) && (*tok > KW_D7))
1469 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1471 inst3 = (*tok++) & 7;
1474 return error("missing comma");
1477 if ((*tok < KW_D0) && (*tok > KW_D7))
1478 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1480 inst2 |= ((*tok++) & 7) << 6;
1483 return error("missing colon");
1486 if ((*tok < KW_D0) && (*tok > KW_D7))
1487 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1489 inst3 |= ((*tok++) & 7) << 6;
1492 return error("missing comma");
1496 return error("missing (");
1497 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1498 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1499 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1500 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1502 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1505 return error("missing (");
1508 return error("missing colon");
1512 return error("missing (");
1513 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1514 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1515 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1516 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1518 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1521 return error("missing (");
1524 return error("extra (unexpected) text found");
1535 // cmp2 (68020, 68030, 68040, CPU32)
1537 int m_cmp2(WORD inst, WORD siz)
1539 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1540 return error(unsupport);
1542 switch (siz & 0x000F)
1556 WORD flg = inst; // Save flag bits
1557 inst &= ~0x3F; // Clobber flag bits in instr
1559 // Install "standard" instr size bits
1565 // OR-in register number
1567 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1569 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1575 inst |= am1 | a1reg; // Get ea1 into instr
1576 D_word(inst); // Deposit instr
1578 // Generate ea0 if requested
1582 ea1gen(siz); // Generate ea1
1587 inst |= am0 | a0reg; // Get ea0 into instr
1588 D_word(inst); // Deposit instr
1589 ea0gen(siz); // Generate ea0
1591 // Generate ea1 if requested
1596 // If we're called from chk2 then bit 11 of size will be set. This is just
1597 // a dumb mechanism to pass this, required by the extension word. (You might
1598 // have noticed the siz & 15 thing above!)
1599 inst = (a1reg << 12) | (siz & (1 << 11));
1611 // chk2 (68020, 68030, 68040, CPU32)
1613 int m_chk2(WORD inst, WORD siz)
1615 return m_cmp2(inst, siz | (1 << 11));
1620 // cpbcc(68020, 68030)
1622 int m_cpbr(WORD inst, WORD siz)
1624 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1625 return error(unsupport);
1627 if (a0exattr & DEFINED)
1629 if ((a0exattr & TDB) != cursect)
1630 return error(rel_error);
1632 uint32_t v = a0exval - (sloc + 2);
1634 // Optimize branch instr. size
1637 if ((v != 0) && ((v + 0x8000) < 0x10000))
1647 if ((v + 0x8000) >= 0x10000)
1648 return error(range_error);
1656 else if (siz == SIZN)
1663 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1671 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1680 // cpdbcc(68020, 68030)
1682 int m_cpdbr(WORD inst, WORD siz)
1687 WORD condition = inst & 0x1f; // Grab condition sneakily placed in the lower 5 bits of inst
1688 inst &= 0xffe0; // And then mask them out - you ain't seen me, roit?
1690 inst |= (1 << 9); // Bolt on FPU id
1697 if (a1exattr & DEFINED)
1699 if ((a1exattr & TDB) != cursect)
1700 return error(rel_error);
1704 if (v + 0x8000 > 0x10000)
1705 return error(range_error);
1711 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
1723 int m_divs(WORD inst, WORD siz)
1725 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1726 return error(unsupport);
1728 WORD flg = inst; // Save flag bits
1729 inst &= ~0x3F; // Clobber flag bits in instr
1731 // Install "standard" instr size bits
1737 // OR-in register number
1739 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1741 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1747 inst |= am1 | a1reg; // Get ea1 into instr
1748 D_word(inst); // Deposit instr
1750 // Generate ea0 if requested
1754 ea1gen(siz); // Generate ea1
1759 inst |= am0 | a0reg; // Get ea0 into instr
1760 D_word(inst); // Deposit instr
1761 ea0gen(siz); // Generate ea0
1763 // Generate ea1 if requested
1768 inst = a1reg + (a2reg << 12) + (1 << 11);
1778 int m_muls(WORD inst, WORD siz)
1780 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1781 return error(unsupport);
1783 WORD flg = inst; // Save flag bits
1784 inst &= ~0x3F; // Clobber flag bits in instr
1786 // Install "standard" instr size bits
1792 // OR-in register number
1794 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1796 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1802 inst |= am1 | a1reg; // Get ea1 into instr
1803 D_word(inst); // Deposit instr
1806 inst = a1reg + (a2reg << 12) + (1 << 11);
1807 inst |= mulmode; // add size bit
1810 // Generate ea0 if requested
1814 ea1gen(siz); // Generate ea1
1819 inst |= am0 | a0reg; // Get ea0 into instr
1820 D_word(inst); // Deposit instr
1822 inst = a1reg + (a2reg << 12) + (1 << 11);
1823 inst |= mulmode; // add size bit
1826 ea0gen(siz); // Generate ea0
1828 // Generate ea1 if requested
1843 int m_divu(WORD inst, WORD siz)
1845 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1846 return error(unsupport);
1848 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1850 WORD flg = inst; // Save flag bits
1851 inst &= ~0x3F; // Clobber flag bits in instr
1853 // Install "standard" instr size bits
1859 // OR-in register number
1861 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1863 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1869 inst |= am1 | a1reg; // Get ea1 into instr
1870 D_word(inst); // Deposit instr
1872 // Generate ea0 if requested
1876 ea1gen(siz); // Generate ea1
1881 inst |= am0 | a0reg; // Get ea0 into instr
1882 D_word(inst); // Deposit instr
1883 ea0gen(siz); // Generate ea0
1885 // Generate ea1 if requested
1890 inst = a1reg + (a2reg << 12);
1900 int m_mulu(WORD inst, WORD siz)
1902 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1903 return error(unsupport);
1905 WORD flg = inst; // Save flag bits
1906 inst &= ~0x3F; // Clobber flag bits in instr
1908 // Install "standard" instr size bits
1914 // OR-in register number
1916 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1918 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1924 inst |= am1 | a1reg; // Get ea1 into instr
1925 D_word(inst); // Deposit instr
1927 // Generate ea0 if requested
1931 ea1gen(siz); // Generate ea1
1936 inst |= am0 | a0reg; // Get ea0 into instr
1937 D_word(inst); // Deposit instr
1938 ea0gen(siz); // Generate ea0
1940 // Generate ea1 if requested
1945 inst = a1reg + (a2reg << 12);
1946 inst |= mulmode; // add size bit
1956 int m_divsl(WORD inst, WORD siz)
1958 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1959 return error(unsupport);
1961 WORD flg = inst; // Save flag bits
1962 inst &= ~0x3F; // Clobber flag bits in instr
1964 // Install "standard" instr size bits
1970 // OR-in register number
1972 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1974 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1980 inst |= am1 | a1reg; // Get ea1 into instr
1981 D_word(inst); // Deposit instr
1983 // Generate ea0 if requested
1987 ea1gen(siz); // Generate ea1
1992 inst |= am0 | a0reg; // Get ea0 into instr
1993 D_word(inst); // Deposit instr
1994 ea0gen(siz); // Generate ea0
1996 // Generate ea1 if requested
2001 inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
2010 int m_divul(WORD inst, WORD siz)
2012 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
2013 return error(unsupport);
2015 WORD flg = inst; // Save flag bits
2016 inst &= ~0x3F; // Clobber flag bits in instr
2018 // Install "standard" instr size bits
2024 // OR-in register number
2026 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2028 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2034 inst |= am1 | a1reg; // Get ea1 into instr
2035 D_word(inst); // Deposit instr
2037 // Generate ea0 if requested
2041 ea1gen(siz); // Generate ea1
2046 inst |= am0 | a0reg; // Get ea0 into instr
2047 D_word(inst); // Deposit instr
2048 ea0gen(siz); // Generate ea0
2050 // Generate ea1 if requested
2055 inst = a1reg + (a2reg << 12) + (1 << 10);
2063 // move16 (ax)+,(ay)+
2065 int m_move16a(WORD inst, WORD siz)
2067 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2068 return error(unsupport);
2072 inst = (1 << 15) + (a1reg << 12);
2080 // move16 with absolute address
2082 int m_move16b(WORD inst, WORD siz)
2084 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2085 return error(unsupport);
2091 if (am0 == APOSTINC)
2094 return error("Wasn't this suppose to call m_move16a???");
2097 //move16 (ax)+,(xxx).L
2102 else if (am0 == ABSL)
2106 //move16 (xxx).L,(ax)+
2112 //move16 (xxx).L,(ax)
2117 else if (am0 == AIND)
2119 //move16 (ax),(xxx).L
2132 // pack/unpack (68020/68030/68040)
2134 int m_pack(WORD inst, WORD siz)
2139 return error("bad size suffix");
2141 if (*tok >= KW_D0 && *tok <= KW_D7)
2143 // Dx,Dy,#<adjustment>
2144 inst |= (0 << 3); // R/M
2145 inst |= (*tok++ & 7);
2146 if (*tok != ',' && tok[2] != ',')
2147 return error("missing comma");
2148 if (tok[1] < KW_D0 && tok[1] > KW_D7)
2149 return error(syntax_error);
2150 inst |= ((tok[1] & 7)<<9);
2153 // Fall through for adjustment (common in both valid cases)
2155 else if (*tok == '-')
2157 // -(Ax),-(Ay),#<adjustment>
2158 inst |= (1 << 3); // R/M
2159 tok++; // eat the minus
2160 if ((*tok != '(') && (tok[2]!=')') && (tok[3]!=',') && (tok[4] != '-') && (tok[5] != '(') && (tok[7] != ')') && (tok[8] != ','))
2161 return error(syntax_error);
2162 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2163 return error(syntax_error);
2164 if (tok[5] < KW_A0 && tok[6] > KW_A7)
2165 return error(syntax_error);
2166 inst |= ((tok[1] & 7) << 0);
2167 inst |= ((tok[6] & 7) << 9);
2170 // Fall through for adjustment (common in both valid cases)
2173 return error("invalid syntax");
2176 if ((*tok != CONST) && (*tok != SYMBOL) && (*tok != '-'))
2177 return error(syntax_error);
2179 if (expr(a0expr, &a0exval, &a0exattr, &a0esym)==ERROR)
2182 if ((a0exattr & DEFINED) == 0)
2183 return error(undef_error);
2185 if (a0exval + 0x8000 > 0x10000)
2189 return error(extra_stuff);
2191 D_word((a0exval & 0xffff));
2203 int m_rtm(WORD inst, WORD siz)
2211 else if (am0 == AREG)
2213 inst |= (1 << 3) + a0reg;
2216 return error("rtm only allows data or address registers.");
2227 int m_rtd(WORD inst, WORD siz)
2231 if (a0exattr & DEFINED)
2234 return error(abs_error);
2236 if ((a0exval + 0x8000) <= 0x7FFF)
2237 return error(range_error);
2243 return error(undef_error);
2252 int m_trapcc(WORD inst, WORD siz)
2260 else if (am0 == IMMED)
2264 if (a0exval < 0x10000)
2271 return error("Immediate value too big");
2281 return error("Invalid parameter for trapcc");
2288 // cinvl/p/a (68040)
2290 int m_cinv(WORD inst, WORD siz)
2295 inst |= (0 << 6) | (a1reg);
2299 inst |= (2 << 6) | (a1reg);
2302 inst |= (1 << 6) | (a1reg);
2305 inst |= (3 << 6) | (a1reg);
2315 // cpRESTORE (68020, 68030)
2317 int m_cprest(WORD inst, WORD siz)
2319 if (activecpu & !(CPU_68020 | CPU_68030))
2320 return error(unsupport);
2322 inst |= am0 | a0reg;
2331 // movec (68010, 68020, 68030, 68040, CPU32)
2333 int m_movec(WORD inst, WORD siz)
2337 if (am0 == DREG || am0 == AREG)
2345 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
2350 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
2361 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
2366 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2376 // moves (68010, 68020, 68030, 68040, CPU32)
2378 int m_moves(WORD inst, WORD siz)
2380 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2381 return error(unsupport);
2387 else if (siz == SIZL)
2398 inst |= am1 | a1reg;
2400 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2403 else if (am0 == AREG)
2405 inst |= am1 | a1reg;
2407 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2414 inst |= am0 | a0reg;
2416 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2421 inst |= am0 | a0reg;
2423 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2435 int m_pbcc(WORD inst, WORD siz)
2438 return error("Not implemented yet.");
2443 // pflusha (68030, 68040)
2445 int m_pflusha(WORD inst, WORD siz)
2447 if (activecpu == CPU_68030)
2450 inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
2454 else if (activecpu == CPU_68040)
2456 inst = B16(11110101, 00011000);
2461 return error(unsupport);
2469 // pflush (68030, 68040, 68060)
2471 int m_pflush(WORD inst, WORD siz)
2473 if (activecpu == CPU_68030)
2476 // PFLUSH FC, MASK, < ea >
2482 if (*tok != CONST && *tok != SYMBOL)
2483 return error("function code should be an expression");
2484 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2486 if ((a0exattr & DEFINED) == 0)
2487 return error("function code immediate should be defined");
2488 if (a0exval > 7 && a0exval < 0)
2489 return error("function code out of range (0-7)");
2500 fc = (1 << 4) | (*tok++ & 7);
2511 return error(syntax_error);
2515 return error("comma exptected");
2518 return error("mask should be an immediate value");
2519 if (*tok != CONST && *tok != SYMBOL)
2520 return error("mask is supposed to be immediate");
2521 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2523 if ((a0exattr & DEFINED) == 0)
2524 return error("mask immediate value should be defined");
2525 if (a0exval > 7 && a0exval < 0)
2526 return error("function code out of range (0-7)");
2527 mask = a0exval << 5;
2533 inst = (1 << 13) | fc | mask | (4 << 10);
2537 else if (*tok == ',')
2539 // PFLUSH FC, MASK, < ea >
2541 if (amode(0) == ERROR)
2544 return error(extra_stuff);
2545 if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE)
2547 inst |= am0 | a0reg;
2549 inst = (1 << 13) | fc | mask | (6 << 10);
2555 return error("unsupported addressing mode");
2559 return error(syntax_error);
2564 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2568 if (*tok != '(' && tok[2] != ')')
2569 return error(syntax_error);
2570 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2571 return error("expected (An)");
2572 if ((inst & 7) == 7)
2573 // With pflushn/pflush there's no easy way to
2574 // distinguish between the two in 68040 mode.
2575 // Ideally the opcode bitfields would have been
2576 // hardcoded in 68ktab but there is aliasing
2577 // between 68030 and 68040 opcode. So we just
2578 // set the 3 lower bits to 1 in pflushn inside
2579 // 68ktab and detect it here.
2580 inst = (inst & 0xff8) | 8;
2581 inst |= (tok[1] & 7) | (5 << 8);
2583 return error(extra_stuff);
2587 return error(unsupport);
2596 int m_pflushr(WORD inst, WORD siz)
2600 WORD flg = inst; // Save flag bits
2601 inst &= ~0x3F; // Clobber flag bits in instr
2603 // Install "standard" instr size bits
2609 // OR-in register number
2611 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2613 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2619 inst |= am1 | a1reg; // Get ea1 into instr
2620 D_word(inst); // Deposit instr
2622 // Generate ea0 if requested
2626 ea1gen(siz); // Generate ea1
2631 inst |= am0 | a0reg; // Get ea0 into instr
2632 D_word(inst); // Deposit instr
2633 ea0gen(siz); // Generate ea0
2635 // Generate ea1 if requested
2640 D_word(B16(10100000, 00000000));
2646 // ploadr, ploadw (68030)
2648 int m_pload(WORD inst, WORD siz, WORD extension)
2650 // TODO: 68551 support is not added yet.
2651 // None of the ST series of computers had
2652 // a 68020 + 68551 socket and since this is
2653 // an Atari targetted assembler....
2663 if (a0reg == KW_SFC - KW_SFC)
2667 else if (a0reg == KW_DFC - KW_SFC)
2672 return error("illegal control register specified");
2675 inst = (1 << 3) | a0reg;
2678 if ((a0exattr & DEFINED) == 0)
2679 return error("constant value must be defined");
2680 inst = (2 << 3) | a0exval;
2684 inst |= extension | (1 << 13);
2692 int m_ploadr(WORD inst, WORD siz)
2694 return m_pload(inst, siz, 1 << 9);
2697 int m_ploadw(WORD inst, WORD siz)
2699 return m_pload(inst, siz, 0 << 9);
2703 // pmove (68030/68551)
2705 int m_pmove(WORD inst, WORD siz)
2709 // TODO: 68551 support is not added yet.
2710 // None of the ST series of computers had
2711 // a 68020 + 68551 socket and since this is
2712 // an Atari targetted assembler....
2713 // (same for 68EC030)
2716 inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2717 inst &= ~(1 << 8); //And mask it out
2724 else if (am1 == CREG)
2730 return error("pmove sez: Wut?");
2732 // The instruction is a quad-word (8 byte) operation
2733 // for the CPU root pointer and the supervisor root pointer.
2734 // It is a long - word operation for the translation control register
2735 // and the transparent translation registers(TT0 and TT1).
2736 // It is a word operation for the MMU status register.
2738 if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
2739 && ((siz != SIZD) && (siz != SIZN)))
2740 return error(siz_error);
2742 if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
2743 && ((siz != SIZL) && (siz != SIZN)))
2744 return error(siz_error);
2746 if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
2747 return error(siz_error);
2752 inst |= am1 | a1reg;
2755 else if (am1 == CREG)
2757 inst |= am0 | a0reg;
2761 switch (reg + KW_SFC)
2764 inst2 |= (0 << 10) + (1 << 14); break;
2766 inst2 |= (2 << 10) + (1 << 14); break;
2768 inst2 |= (3 << 10) + (1 << 14); break;
2770 inst2 |= (2 << 10) + (0 << 13); break;
2772 inst2 |= (3 << 10) + (0 << 13); break;
2775 inst2 |= (1 << 9) + (3 << 13);
2777 inst2 |= (0 << 9) + (3 << 13);
2780 return error("unsupported register");
2790 else if (am1 == CREG)
2802 int m_pmovefd(WORD inst, WORD siz)
2806 return m_pmove(inst | (1 << 8), siz);
2813 #define gen_ptrapcc(name,opcode) \
2814 int m_##name(WORD inst, WORD siz) \
2820 D_word(B8(opcode)); \
2827 D_word(B8(opcode)); \
2832 int m_##name##n(WORD inst, WORD siz) \
2836 D_word(B8(opcode)); \
2840 gen_ptrapcc(ptrapbs,00000000)
2841 gen_ptrapcc(ptrapbc,00000001)
2842 gen_ptrapcc(ptrapls,00000010)
2843 gen_ptrapcc(ptraplc,00000011)
2844 gen_ptrapcc(ptrapss,00000100)
2845 gen_ptrapcc(ptrapsc,00000101)
2846 gen_ptrapcc(ptrapas,00000110)
2847 gen_ptrapcc(ptrapac,00000111)
2848 gen_ptrapcc(ptrapws,00001000)
2849 gen_ptrapcc(ptrapwc,00001001)
2850 gen_ptrapcc(ptrapis,00001010)
2851 gen_ptrapcc(ptrapic,00001011)
2852 gen_ptrapcc(ptrapgc,00001100)
2853 gen_ptrapcc(ptrapgs,00001101)
2854 gen_ptrapcc(ptrapcs,00001110)
2855 gen_ptrapcc(ptrapcc,00001111)
2857 //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; }
2858 //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; }
2859 //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; }
2860 //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; }
2861 //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; }
2862 //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; }
2863 //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; }
2864 //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; }
2865 //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; }
2866 //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; }
2867 //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; }
2868 //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; }
2869 //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; }
2870 //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; }
2871 //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; }
2872 //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; }
2873 //int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2874 //int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2875 //int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2876 //int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2877 //int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2878 //int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2879 //int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2880 //int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2881 //int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2882 //int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2883 //int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2884 //int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2885 //int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2886 //int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2887 //int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2888 //int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2892 // ptestr, ptestw (68030)
2894 int m_ptest(WORD inst, WORD siz)
2898 if (activecpu == CPU_68030)
2899 return error("Not implemented yet.");
2900 else if (activecpu == CPU_68040)
2901 return error("Not implemented yet.");
2907 #define FPU_NOWARN 0
2908 #define FPU_P_EMUL 1
2909 #define FPU_P2_EMU 2
2914 // Generate a FPU opcode
2916 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2918 if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
2920 inst |= (1 << 9); // Bolt on FPU id
2927 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2931 case SIZB: inst |= (6 << 10); break;
2932 case SIZW: inst |= (4 << 10); break;
2933 case SIZL: inst |= (0 << 10); break;
2935 case SIZS: inst |= (1 << 10); break;
2936 case SIZD: inst |= (5 << 10); break;
2937 case SIZX: inst |= (2 << 10); break;
2942 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2946 return error("Something bad happened, possibly, in gen_fpu.");
2950 inst |= (a1reg << 7);
2957 inst |= (1 << 9); //Bolt on FPU id
2961 inst |= (a1reg << 7);
2966 if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
2967 warn("Instruction is emulated in 68040");
2974 // fabs, fsabs, fdabs (6888X, 68040)
2976 int m_fabs(WORD inst, WORD siz)
2978 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2982 int m_fsabs(WORD inst, WORD siz)
2984 if (activefpu == FPU_68040)
2985 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2987 return error("Unsupported in current FPU");
2991 int m_fdabs(WORD inst, WORD siz)
2993 if (activefpu == FPU_68040)
2994 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2996 return error("Unsupported in current FPU");
3001 // facos (6888X, 68040FPSP)
3003 int m_facos(WORD inst, WORD siz)
3005 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
3010 // fadd (6888X, 68040FPSP)
3012 int m_fadd(WORD inst, WORD siz)
3014 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
3018 int m_fsadd(WORD inst, WORD siz)
3020 if (activefpu == FPU_68040)
3021 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
3023 return error("Unsupported in current FPU");
3027 int m_fdadd(WORD inst, WORD siz)
3029 if (activefpu == FPU_68040)
3030 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
3032 return error("Unsupported in current FPU");
3037 // fasin (6888X, 68040FPSP)f
3039 int m_fasin(WORD inst, WORD siz)
3041 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
3046 // fatan (6888X, 68040FPSP)
3048 int m_fatan(WORD inst, WORD siz)
3050 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
3055 // fatanh (6888X, 68040FPSP)
3057 int m_fatanh(WORD inst, WORD siz)
3059 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
3064 // fcmp (6888X, 68040)
3066 int m_fcmp(WORD inst, WORD siz)
3068 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
3073 // fcos (6888X, 68040FPSP)
3075 int m_fcos(WORD inst, WORD siz)
3077 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
3082 // fcosh (6888X, 68040FPSP)
3084 int m_fcosh(WORD inst, WORD siz)
3086 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
3091 // fdbcc (6888X, 68040)
3093 int m_fdbcc(WORD inst, WORD siz)
3095 WORD opcode = inst & 0x3F; //Grab conditional bitfield
3105 if (a1exattr & DEFINED)
3107 if ((a1exattr & TDB) != cursect)
3108 return error(rel_error);
3110 uint32_t v = a1exval - sloc;
3112 if ((v + 0x8000) > 0x10000)
3113 return error(range_error);
3119 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
3128 // fdiv (6888X, 68040)
3130 int m_fdiv(WORD inst, WORD siz)
3132 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
3136 int m_fsdiv(WORD inst, WORD siz)
3138 if (activefpu == FPU_68040)
3139 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
3141 return error("Unsupported in current FPU");
3145 int m_fddiv(WORD inst, WORD siz)
3147 if (activefpu == FPU_68040)
3148 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3150 return error("Unsupported in current FPU");
3155 // fetox (6888X, 68040FPSP)
3157 int m_fetox(WORD inst, WORD siz)
3159 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
3164 // fetoxm1 (6888X, 68040FPSP)
3166 int m_fetoxm1(WORD inst, WORD siz)
3168 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
3173 // fgetexp (6888X, 68040FPSP)
3175 int m_fgetexp(WORD inst, WORD siz)
3177 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
3182 // fgetman (6888X, 68040FPSP)
3184 int m_fgetman(WORD inst, WORD siz)
3186 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
3191 // fint (6888X, 68040FPSP)
3193 int m_fint(WORD inst, WORD siz)
3196 // special case - fint fpx = fint fpx,fpx
3199 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
3204 // fintrz (6888X, 68040FPSP)
3206 int m_fintrz(WORD inst, WORD siz)
3209 // special case - fintrz fpx = fintrz fpx,fpx
3212 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
3217 // flog10 (6888X, 68040FPSP)
3219 int m_flog10(WORD inst, WORD siz)
3221 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
3226 // flog2 (6888X, 68040FPSP)
3228 int m_flog2(WORD inst, WORD siz)
3230 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
3235 // flogn (6888X, 68040FPSP)
3237 int m_flogn(WORD inst, WORD siz)
3239 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
3244 // flognp1 (6888X, 68040FPSP)
3246 int m_flognp1(WORD inst, WORD siz)
3248 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
3253 // fmod (6888X, 68040FPSP)
3255 int m_fmod(WORD inst, WORD siz)
3257 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
3262 // fmove (6888X, 68040)
3264 int m_fmove(WORD inst, WORD siz)
3268 if ((am0 == FREG) && (am1 < AM_USP))
3272 inst |= am1 | a1reg;
3281 case SIZB: inst |= (6 << 10); break;
3282 case SIZW: inst |= (4 << 10); break;
3283 case SIZL: inst |= (0 << 10); break;
3285 case SIZS: inst |= (1 << 10); break;
3286 case SIZD: inst |= (5 << 10); break;
3287 case SIZX: inst |= (2 << 10); break;
3288 case SIZP: inst |= (3 << 10);
3289 // In P size we have 2 cases: {#k} where k is immediate
3290 // and {Dn} where Dn=Data register
3296 inst |= bfval1 << 4;
3301 if (bfval1>63 && bfval1<-64)
3302 return error("K-factor must be between -64 and 63");
3303 inst |= bfval1 & 127;
3308 return error("Something bad happened, possibly.");
3313 // Destination specifier
3314 inst |= (a0reg << 7);
3322 else if ((am0 < AM_USP) && (am1 == FREG))
3327 inst |= am0 | a0reg;
3336 case SIZB: inst |= (6 << 10); break;
3337 case SIZW: inst |= (4 << 10); break;
3338 case SIZL: inst |= (0 << 10); break;
3340 case SIZS: inst |= (1 << 10); break;
3341 case SIZD: inst |= (5 << 10); break;
3342 case SIZX: inst |= (2 << 10); break;
3343 case SIZP: inst |= (3 << 10); break;
3345 return error("Something bad happened, possibly.");
3349 // Destination specifier
3350 inst |= (a1reg << 7);
3358 else if ((am0 == FREG) && (am1 == FREG))
3360 // register-to-register
3361 // Essentially ea to register with R/0=0
3371 return error("Invalid size");
3374 inst |= (a0reg << 10);
3376 // Destination register
3377 inst |= (a1reg << 7);
3387 // fmove (6888X, 68040)
3389 int m_fmovescr(WORD inst, WORD siz)
3391 // Move Floating-Point System Control Register (FPCR)
3395 if ((am0 == FPSCR) && (am1 < AM_USP))
3397 inst |= am1 | a1reg;
3399 inst = (1 << 13) + (1 << 15);
3405 else if ((am1 == FPSCR) && (am0 < AM_USP))
3407 inst |= am0 | a0reg;
3409 inst = (0 << 13) + (1 << 15);
3416 return error("m_fmovescr says: wut?");
3420 // fsmove/fdmove (68040)
3422 int m_fsmove(WORD inst, WORD siz)
3424 return error("Not implemented yet.");
3427 if (activefpu == FPU_68040)
3428 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3430 return error("Unsupported in current FPU");
3435 int m_fdmove(WORD inst, WORD siz)
3437 return error("Not implemented yet.");
3440 if (activefpu == FPU_68040)
3441 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3443 return error("Unsupported in current FPU");
3449 // fmovecr (6888X, 68040FPSP)
3451 int m_fmovecr(WORD inst, WORD siz)
3459 if (activefpu == FPU_68040)
3460 warn("Instruction is emulated in 68040");
3467 // fmovem (6888X, 68040)
3469 int m_fmovem(WORD inst, WORD siz)
3474 if (siz == SIZX || siz==SIZN)
3476 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3478 //fmovem.x <rlist>,ea
3479 if (fpu_reglist_left(®mask) < 0)
3483 return error("missing comma");
3488 inst |= am0 | a0reg;
3490 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3491 return error("invalid addressing mode");
3494 inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
3499 else if ((*tok >= KW_D0) && (*tok <= KW_D7))
3502 datareg = (*tok++ & 7) << 10;
3505 return error("missing comma");
3510 inst |= am0 | a0reg;
3512 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3513 return error("invalid addressing mode");
3516 inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
3527 inst |= am0 | a0reg;
3530 return error("missing comma");
3532 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3534 //fmovem.x ea,<rlist>
3535 if (fpu_reglist_right(®mask) < 0)
3539 inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
3547 datareg = (*tok++ & 7) << 10;
3549 inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
3556 else if (siz == SIZL)
3558 if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
3560 //fmovem.l <rlist>,ea
3561 regmask = (1 << 15) | (1 << 13);
3563 if (*tok == KW_FPCR)
3565 regmask |= (1 << 12);
3570 if (*tok == KW_FPSR)
3572 regmask |= (1 << 11);
3577 if (*tok == KW_FPIAR)
3579 regmask |= (1 << 10);
3584 if ((*tok == '/') || (*tok == '-'))
3591 return error("missing comma");
3596 inst |= am0 | a0reg;
3603 //fmovem.l ea,<rlist>
3607 inst |= am0 | a0reg;
3610 return error("missing comma");
3612 regmask = (1 << 15) | (0 << 13);
3615 if (*tok == KW_FPCR)
3617 regmask |= (1 << 12);
3622 if (*tok == KW_FPSR)
3624 regmask |= (1 << 11);
3629 if (*tok == KW_FPIAR)
3631 regmask |= (1 << 10);
3636 if ((*tok == '/') || (*tok == '-'))
3643 return error("extra (unexpected) text found");
3645 inst |= am0 | a0reg;
3652 return error("bad size suffix");
3659 // fmul (6888X, 68040)
3661 int m_fmul(WORD inst, WORD siz)
3663 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
3667 int m_fsmul(WORD inst, WORD siz)
3669 if (activefpu == FPU_68040)
3670 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
3672 return error("Unsupported in current FPU");
3676 int m_fdmul(WORD inst, WORD siz)
3678 if (activefpu == FPU_68040)
3679 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
3681 return error("Unsupported in current FPU");
3686 // fneg (6888X, 68040)
3688 int m_fneg(WORD inst, WORD siz)
3690 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
3694 int m_fsneg(WORD inst, WORD siz)
3696 if (activefpu == FPU_68040)
3697 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
3699 return error("Unsupported in current FPU");
3703 int m_fdneg(WORD inst, WORD siz)
3705 if (activefpu == FPU_68040)
3706 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
3708 return error("Unsupported in current FPU");
3713 // fnop (6888X, 68040)
3715 int m_fnop(WORD inst, WORD siz)
3717 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3722 // frem (6888X, 68040FPSP)
3724 int m_frem(WORD inst, WORD siz)
3726 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3731 // fscale (6888X, 68040FPSP)
3733 int m_fscale(WORD inst, WORD siz)
3735 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3740 // FScc (6888X, 68040)
3742 //int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3743 //int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3744 //int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3745 //int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3746 //int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3747 //int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3748 //int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3749 //int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3750 //int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3751 //int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3752 //int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3753 //int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3754 //int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3755 //int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3756 //int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3757 //int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3758 //int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3759 //int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3760 //int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3761 //int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3762 //int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3763 //int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3764 //int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3765 //int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3766 //int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3767 //int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3768 //int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3769 //int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3770 //int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3771 //int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3772 //int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3773 //int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3775 #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;}
3776 gen_FScc(fseq , 00000001);
3777 gen_FScc(fsne , 00001110);
3778 gen_FScc(fsgt , 00010010);
3779 gen_FScc(fsngt , 00011101);
3780 gen_FScc(fsge , 00010011);
3781 gen_FScc(fsnge , 00011100);
3782 gen_FScc(fslt , 00010100);
3783 gen_FScc(fsnlt , 00011011);
3784 gen_FScc(fsle , 00010101);
3785 gen_FScc(fsnle , 00011010);
3786 gen_FScc(fsgl , 00010110);
3787 gen_FScc(fsngl , 00011001);
3788 gen_FScc(fsgle , 00010111);
3789 gen_FScc(fsngle, 00011000);
3790 gen_FScc(fsogt , 00000010);
3791 gen_FScc(fsule , 00001101);
3792 gen_FScc(fsoge , 00000011);
3793 gen_FScc(fsult , 00001100);
3794 gen_FScc(fsolt , 00000100);
3795 gen_FScc(fsuge , 00001011);
3796 gen_FScc(fsole , 00000101);
3797 gen_FScc(fsugt , 00001010);
3798 gen_FScc(fsogl , 00000110);
3799 gen_FScc(fsueq , 00001001);
3800 gen_FScc(fsor , 00000111);
3801 gen_FScc(fsun , 00001000);
3802 gen_FScc(fsf , 00000000);
3803 gen_FScc(fst , 00001111);
3804 gen_FScc(fssf , 00010000);
3805 gen_FScc(fsst , 00011111);
3806 gen_FScc(fsseq , 00010001);
3807 gen_FScc(fssne , 00011110);
3810 // FTRAPcc (6888X, 68040)
3812 //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;}
3813 //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;}
3814 //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;}
3815 //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;}
3816 //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;}
3817 //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;}
3818 //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;}
3819 //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;}
3820 //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;}
3821 //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;}
3822 //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;}
3823 //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;}
3824 //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;}
3825 //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;}
3826 //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;}
3827 //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;}
3828 //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;}
3829 //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;}
3830 //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;}
3831 //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;}
3832 //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;}
3833 //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;}
3834 //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;}
3835 //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;}
3836 //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;}
3837 //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;}
3838 //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;}
3839 //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;}
3840 //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;}
3841 //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;}
3842 //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;}
3843 //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;}
3845 //int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3846 //int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3847 //int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3848 //int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3849 //int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3850 //int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3851 //int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3852 //int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3853 //int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3854 //int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3855 //int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3856 //int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3857 //int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3858 //int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3859 //int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3860 //int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3861 //int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3862 //int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3863 //int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3864 //int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3865 //int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3866 //int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3867 //int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3868 //int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3869 //int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3870 //int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3871 //int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3872 //int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3873 //int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3874 //int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3875 //int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3876 //int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3878 #define gen_FTRAPcc(name,opcode) \
3879 int m_##name (WORD inst, WORD siz) \
3884 D_word(B8(opcode)); \
3891 D_word(B8(opcode)); \
3896 int m_##name##n (WORD inst, WORD siz) \
3899 D_word(B8(opcode)); \
3903 gen_FTRAPcc(ftrapeq ,00000001)
3904 gen_FTRAPcc(ftrapne ,00001110)
3905 gen_FTRAPcc(ftrapgt ,00010010)
3906 gen_FTRAPcc(ftrapngt ,00011101)
3907 gen_FTRAPcc(ftrapge ,00010011)
3908 gen_FTRAPcc(ftrapnge ,00011100)
3909 gen_FTRAPcc(ftraplt ,00010100)
3910 gen_FTRAPcc(ftrapnlt ,00011011)
3911 gen_FTRAPcc(ftraple ,00010101)
3912 gen_FTRAPcc(ftrapnle ,00011010)
3913 gen_FTRAPcc(ftrapgl ,00010110)
3914 gen_FTRAPcc(ftrapngl ,00011001)
3915 gen_FTRAPcc(ftrapgle ,00010111)
3916 gen_FTRAPcc(ftrapngle ,00011000)
3917 gen_FTRAPcc(ftrapogt ,00000010)
3918 gen_FTRAPcc(ftrapule ,00001101)
3919 gen_FTRAPcc(ftrapoge ,00000011)
3920 gen_FTRAPcc(ftrapult ,00001100)
3921 gen_FTRAPcc(ftrapolt ,00000100)
3922 gen_FTRAPcc(ftrapuge ,00001011)
3923 gen_FTRAPcc(ftrapole ,00000101)
3924 gen_FTRAPcc(ftrapugt ,00001010)
3925 gen_FTRAPcc(ftrapogl ,00000110)
3926 gen_FTRAPcc(ftrapueq ,00001001)
3927 gen_FTRAPcc(ftrapor ,00000111)
3928 gen_FTRAPcc(ftrapun ,00001000)
3929 gen_FTRAPcc(ftrapf ,00000000)
3930 gen_FTRAPcc(ftrapt ,00001111)
3931 gen_FTRAPcc(ftrapsf ,00010000)
3932 gen_FTRAPcc(ftrapst ,00011111)
3933 gen_FTRAPcc(ftrapseq ,00010001)
3934 gen_FTRAPcc(ftrapsne ,00011110)
3937 // fsgldiv (6888X, 68040)
3939 int m_fsgldiv(WORD inst, WORD siz)
3941 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3946 // fsglmul (6888X, 68040)
3948 int m_fsglmul(WORD inst, WORD siz)
3950 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3955 // fsin (6888X, 68040FPSP)
3957 int m_fsin(WORD inst, WORD siz)
3959 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3964 // fsincos (6888X, 68040FPSP)
3966 int m_fsincos(WORD inst, WORD siz)
3968 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
3979 // fsin (6888X, 68040FPSP)
3981 int m_fsinh(WORD inst, WORD siz)
3983 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3988 // fsqrt (6888X, 68040)
3990 int m_fsqrt(WORD inst, WORD siz)
3992 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3996 int m_fsfsqrt(WORD inst, WORD siz)
3998 if (activefpu == FPU_68040)
3999 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
4001 return error("Unsupported in current FPU");
4005 int m_fdfsqrt(WORD inst, WORD siz)
4007 if (activefpu == FPU_68040)
4008 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
4010 return error("Unsupported in current FPU");
4015 // fsub (6888X, 68040)
4017 int m_fsub(WORD inst, WORD siz)
4019 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
4023 int m_fsfsub(WORD inst, WORD siz)
4025 if (activefpu == FPU_68040)
4026 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
4028 return error("Unsupported in current FPU");
4032 int m_fdsub(WORD inst, WORD siz)
4034 if (activefpu == FPU_68040)
4035 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
4037 return error("Unsupported in current FPU");
4042 // ftan (6888X, 68040FPSP)
4044 int m_ftan(WORD inst, WORD siz)
4046 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
4051 // ftanh (6888X, 68040FPSP)
4053 int m_ftanh(WORD inst, WORD siz)
4055 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
4060 // ftentox (6888X, 68040FPSP)
4062 int m_ftentox(WORD inst, WORD siz)
4064 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
4069 // ftst (6888X, 68040)
4071 int m_ftst(WORD inst, WORD siz)
4073 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
4078 // ftwotox (6888X, 68040FPSP)
4080 int m_ftwotox(WORD inst, WORD siz)
4082 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);