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)
712 if (a1exattr & DEFINED)
714 if ((a1exattr & TDB) != cursect)
715 return error(rel_error);
717 uint32_t v = a1exval - sloc;
719 if (v + 0x8000 > 0x10000)
720 return error(range_error);
726 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
737 int m_exg(WORD inst, WORD siz)
743 if (am0 == DREG && am1 == DREG)
745 else if (am0 == AREG && am1 == AREG)
751 m = a1reg; // Get AREG into a1reg
759 inst |= m | reg_9[a0reg] | a1reg;
769 int m_link(WORD inst, WORD siz)
773 // Is this an error condition???
778 inst &= ~((3 << 9) | (1 << 6) | (1 << 4));
790 WORD extra_addressing[16]=
793 0, //0101 ([bd,An],Xn,od)
794 0x180, //0102 ([bc,An,Xn],od) (111 110 110 111)
796 0, //0104 ([bd,PC],Xn,od)
797 0, //0105 ([bc,PC,Xn],od)
812 // Handle MOVE <C_ALL> <C_ALTDATA>
813 // MOVE <C_ALL> <M_AREG>
815 // Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
817 int m_move(WORD inst, WORD size)
819 // Cast the passed in value to an int
822 // Try to optimize to MOVEQ
823 // N.B.: We can get away with casting the uint64_t to a 32-bit value
824 // because it checks for a SIZL (i.e., a 32-bit value).
825 if (CHECK_OPTS(OPT_MOVEL_MOVEQ)
826 && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
827 && ((a0exattr & (TDB | DEFINED)) == DEFINED)
828 && ((uint32_t)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 ((uint32_t)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)
972 if (a0exattr & DEFINED)
974 if ((a0exattr & TDB) != cursect)
976 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
977 return error(rel_error);
980 uint32_t v = (uint32_t)a0exval - (sloc + 2);
982 // Optimize branch instr. size
985 if (CHECK_OPTS(OPT_BSR_BCC_S) && (v != 0) && ((v + 0x80) < 0x100))
992 warn("Bcc.w/BSR.w converted to .s");
999 if ((v + 0x8000) > 0x10000)
1000 return error(range_error);
1008 if (siz == SIZB || siz == SIZS)
1010 if ((v + 0x80) >= 0x100)
1011 return error(range_error);
1018 if ((v + 0x8000) >= 0x10000)
1019 return error(range_error);
1027 else if (siz == SIZN)
1030 if (siz == SIZB || siz == SIZS)
1033 AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
1041 AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
1052 int m_addq(WORD inst, WORD siz)
1054 inst |= siz_6[siz] | am1 | a1reg;
1056 if (a0exattr & DEFINED)
1058 if ((a0exval > 8) || (a0exval == 0)) // Range in 1..8
1059 return error(range_error);
1061 inst |= (a0exval & 7) << 9;
1066 AddFixup(FU_QUICK, sloc, a0expr);
1079 int m_trap(WORD inst, WORD siz)
1083 if (a0exattr & DEFINED)
1086 return error(abs_error);
1089 return error(range_error);
1095 return error(undef_error);
1102 // movem <rlist>,ea -- movem ea,<rlist>
1104 int m_movem(WORD inst, WORD siz)
1112 return error("bad size suffix");
1119 // Handle #<expr>, ea
1122 if (abs_expr(&eval) != OK)
1125 if (eval >= 0x10000L)
1126 return error(range_error);
1132 if ((*tok >= KW_D0) && (*tok <= KW_A7))
1135 if (reglist(&rmask) < 0)
1140 return error("missing comma");
1145 inst |= am0 | a0reg;
1147 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
1148 return error("invalid addressing mode");
1150 // If APREDEC, reverse register mask
1156 for(i=0x8000; i; i>>=1, w>>=1)
1157 rmask = (WORD)((rmask << 1) | w & 1);
1166 inst |= 0x0400 | am0 | a0reg;
1169 return error("missing comma");
1172 return error("missing register list");
1179 if (abs_expr(&eval) != OK)
1182 if (eval >= 0x10000)
1183 return error(range_error);
1187 else if (reglist(&rmask) < 0)
1190 if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
1191 return error("invalid addressing mode");
1203 // CLR.x An ==> SUBA.x An,An
1205 int m_clra(WORD inst, WORD siz)
1207 inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
1214 ////////////////////////////////////////
1216 // 68020/30/40 instructions
1218 ////////////////////////////////////////
1223 int m_br30(WORD inst, WORD siz)
1225 if (a0exattr & DEFINED)
1227 if ((a0exattr & TDB) != cursect)
1228 return error(rel_error);
1230 uint32_t v = a0exval - (sloc + 2);
1239 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1247 // bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
1248 // (68020, 68030, 68040)
1250 int m_bfop(WORD inst, WORD siz)
1252 if ((bfval1 > 31) || (bfval1 < 0))
1253 return error("bfxxx offset: immediate value must be between 0 and 31");
1255 // First instruction word - just the opcode and first EA
1256 // Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
1263 if (bfval2 > 31 || bfval2 < 0)
1264 return error("bfxxx width: immediate value must be between 0 and 31");
1266 // For Dw both immediate and register number are stuffed
1267 // into the same field O_o
1268 bfparam2 = (bfval2 << 0);
1273 bfparam1 = (bfval1 << 6);
1277 bfparam1 = bfval1 << 12;
1280 D_word((inst | am0 | a0reg | am1 | a1reg));
1281 ea0gen(siz); // Generate EA
1283 // Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
1285 inst = bfparam1 | bfparam2;
1291 inst |= a0reg << 12;
1300 // bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
1302 int m_bkpt(WORD inst, WORD siz)
1306 if (a0exattr & DEFINED)
1309 return error(abs_error);
1312 return error(range_error);
1318 return error(undef_error);
1327 int m_callm(WORD inst, WORD siz)
1334 if (a0exattr & DEFINED)
1337 return error(abs_error);
1340 return error(range_error);
1346 return error(undef_error);
1356 // cas (68020, 68030, 68040)
1358 int m_cas(WORD inst, WORD siz)
1364 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1365 return error(unsupport);
1380 return error("bad size suffix");
1385 if ((*tok < KW_D0) && (*tok > KW_D7))
1386 return error("CAS accepts only data registers");
1388 inst2 = (*tok++) & 7;
1391 return error("missing comma");
1394 if ((*tok < KW_D0) && (*tok > KW_D7))
1395 return error("CAS accepts only data registers");
1397 inst2 |= ((*tok++) & 7) << 6;
1400 return error("missing comma");
1403 if ((modes = amode(1)) < 0)
1407 return error("too many ea fields");
1410 return error("extra (unexpected) text found");
1412 // Reject invalud ea modes
1413 amsk = amsktab[am0];
1415 if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
1416 return error("unsupported addressing mode");
1418 inst |= am0 | a0reg;
1428 // cas2 (68020, 68030, 68040)
1430 int m_cas2(WORD inst, WORD siz)
1434 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1435 return error(unsupport);
1450 return error("bad size suffix");
1455 if ((*tok < KW_D0) && (*tok > KW_D7))
1456 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1458 inst2 = (*tok++) & 7;
1461 return error("missing colon");
1464 if ((*tok < KW_D0) && (*tok > KW_D7))
1465 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1467 inst3 = (*tok++) & 7;
1470 return error("missing comma");
1473 if ((*tok < KW_D0) && (*tok > KW_D7))
1474 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1476 inst2 |= ((*tok++) & 7) << 6;
1479 return error("missing colon");
1482 if ((*tok < KW_D0) && (*tok > KW_D7))
1483 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1485 inst3 |= ((*tok++) & 7) << 6;
1488 return error("missing comma");
1492 return error("missing (");
1493 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1494 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1495 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1496 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1498 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1501 return error("missing (");
1504 return error("missing colon");
1508 return error("missing (");
1509 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1510 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1511 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1512 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1514 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1517 return error("missing (");
1520 return error("extra (unexpected) text found");
1531 // cmp2 (68020, 68030, 68040, CPU32)
1533 int m_cmp2(WORD inst, WORD siz)
1535 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1536 return error(unsupport);
1538 switch (siz & 0x000F)
1552 WORD flg = inst; // Save flag bits
1553 inst &= ~0x3F; // Clobber flag bits in instr
1555 // Install "standard" instr size bits
1561 // OR-in register number
1563 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1565 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1571 inst |= am1 | a1reg; // Get ea1 into instr
1572 D_word(inst); // Deposit instr
1574 // Generate ea0 if requested
1578 ea1gen(siz); // Generate ea1
1583 inst |= am0 | a0reg; // Get ea0 into instr
1584 D_word(inst); // Deposit instr
1585 ea0gen(siz); // Generate ea0
1587 // Generate ea1 if requested
1592 // If we're called from chk2 then bit 11 of size will be set. This is just
1593 // a dumb mechanism to pass this, required by the extension word. (You might
1594 // have noticed the siz & 15 thing above!)
1595 inst = (a1reg << 12) | (siz & (1 << 11));
1607 // chk2 (68020, 68030, 68040, CPU32)
1609 int m_chk2(WORD inst, WORD siz)
1611 return m_cmp2(inst, siz | (1 << 11));
1616 // cpbcc(68020, 68030)
1618 int m_cpbr(WORD inst, WORD siz)
1620 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1621 return error(unsupport);
1623 if (a0exattr & DEFINED)
1625 if ((a0exattr & TDB) != cursect)
1626 return error(rel_error);
1628 uint32_t v = a0exval - (sloc + 2);
1630 // Optimize branch instr. size
1633 if ((v != 0) && ((v + 0x8000) < 0x10000))
1643 if ((v + 0x8000) >= 0x10000)
1644 return error(range_error);
1652 else if (siz == SIZN)
1659 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1667 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1676 // cpdbcc(68020, 68030)
1678 int m_cpdbr(WORD inst, WORD siz)
1683 WORD condition = inst & 0x1f; // Grab condition sneakily placed in the lower 5 bits of inst
1684 inst &= 0xffe0; // And then mask them out - you ain't seen me, roit?
1686 inst |= (1 << 9); // Bolt on FPU id
1693 if (a1exattr & DEFINED)
1695 if ((a1exattr & TDB) != cursect)
1696 return error(rel_error);
1700 if (v + 0x8000 > 0x10000)
1701 return error(range_error);
1707 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
1719 int m_divs(WORD inst, WORD siz)
1721 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1722 return error(unsupport);
1724 WORD flg = inst; // Save flag bits
1725 inst &= ~0x3F; // Clobber flag bits in instr
1727 // Install "standard" instr size bits
1733 // OR-in register number
1735 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1737 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1743 inst |= am1 | a1reg; // Get ea1 into instr
1744 D_word(inst); // Deposit instr
1746 // Generate ea0 if requested
1750 ea1gen(siz); // Generate ea1
1755 inst |= am0 | a0reg; // Get ea0 into instr
1756 D_word(inst); // Deposit instr
1757 ea0gen(siz); // Generate ea0
1759 // Generate ea1 if requested
1764 inst = a1reg + (a2reg << 12) + (1 << 11);
1774 int m_muls(WORD inst, WORD siz)
1776 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1777 return error(unsupport);
1779 WORD flg = inst; // Save flag bits
1780 inst &= ~0x3F; // Clobber flag bits in instr
1782 // Install "standard" instr size bits
1788 // OR-in register number
1790 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1792 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1798 inst |= am1 | a1reg; // Get ea1 into instr
1799 D_word(inst); // Deposit instr
1802 inst = a1reg + (a2reg << 12) + (1 << 11);
1803 inst |= mulmode; // add size bit
1806 // Generate ea0 if requested
1810 ea1gen(siz); // Generate ea1
1815 inst |= am0 | a0reg; // Get ea0 into instr
1816 D_word(inst); // Deposit instr
1818 inst = a1reg + (a2reg << 12) + (1 << 11);
1819 inst |= mulmode; // add size bit
1822 ea0gen(siz); // Generate ea0
1824 // Generate ea1 if requested
1839 int m_divu(WORD inst, WORD siz)
1841 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1842 return error(unsupport);
1844 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1846 WORD flg = inst; // Save flag bits
1847 inst &= ~0x3F; // Clobber flag bits in instr
1849 // Install "standard" instr size bits
1855 // OR-in register number
1857 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1859 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1865 inst |= am1 | a1reg; // Get ea1 into instr
1866 D_word(inst); // Deposit instr
1868 // Generate ea0 if requested
1872 ea1gen(siz); // Generate ea1
1877 inst |= am0 | a0reg; // Get ea0 into instr
1878 D_word(inst); // Deposit instr
1879 ea0gen(siz); // Generate ea0
1881 // Generate ea1 if requested
1886 inst = a1reg + (a2reg << 12);
1896 int m_mulu(WORD inst, WORD siz)
1898 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1899 return error(unsupport);
1901 WORD flg = inst; // Save flag bits
1902 inst &= ~0x3F; // Clobber flag bits in instr
1904 // Install "standard" instr size bits
1910 // OR-in register number
1912 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1914 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1920 inst |= am1 | a1reg; // Get ea1 into instr
1921 D_word(inst); // Deposit instr
1923 // Generate ea0 if requested
1927 ea1gen(siz); // Generate ea1
1932 inst |= am0 | a0reg; // Get ea0 into instr
1933 D_word(inst); // Deposit instr
1934 ea0gen(siz); // Generate ea0
1936 // Generate ea1 if requested
1941 inst = a1reg + (a2reg << 12);
1942 inst |= mulmode; // add size bit
1952 int m_divsl(WORD inst, WORD siz)
1954 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1955 return error(unsupport);
1957 WORD flg = inst; // Save flag bits
1958 inst &= ~0x3F; // Clobber flag bits in instr
1960 // Install "standard" instr size bits
1966 // OR-in register number
1968 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1970 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1976 inst |= am1 | a1reg; // Get ea1 into instr
1977 D_word(inst); // Deposit instr
1979 // Generate ea0 if requested
1983 ea1gen(siz); // Generate ea1
1988 inst |= am0 | a0reg; // Get ea0 into instr
1989 D_word(inst); // Deposit instr
1990 ea0gen(siz); // Generate ea0
1992 // Generate ea1 if requested
1997 inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
2006 int m_divul(WORD inst, WORD siz)
2008 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
2009 return error(unsupport);
2011 WORD flg = inst; // Save flag bits
2012 inst &= ~0x3F; // Clobber flag bits in instr
2014 // Install "standard" instr size bits
2020 // OR-in register number
2022 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2024 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2030 inst |= am1 | a1reg; // Get ea1 into instr
2031 D_word(inst); // Deposit instr
2033 // Generate ea0 if requested
2037 ea1gen(siz); // Generate ea1
2042 inst |= am0 | a0reg; // Get ea0 into instr
2043 D_word(inst); // Deposit instr
2044 ea0gen(siz); // Generate ea0
2046 // Generate ea1 if requested
2051 inst = a1reg + (a2reg << 12) + (1 << 10);
2059 // move16 (ax)+,(ay)+
2061 int m_move16a(WORD inst, WORD siz)
2063 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2064 return error(unsupport);
2068 inst = (1 << 15) + (a1reg << 12);
2076 // move16 with absolute address
2078 int m_move16b(WORD inst, WORD siz)
2080 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2081 return error(unsupport);
2087 if (am0 == APOSTINC)
2090 return error("Wasn't this suppose to call m_move16a???");
2093 //move16 (ax)+,(xxx).L
2098 else if (am0 == ABSL)
2102 //move16 (xxx).L,(ax)+
2108 //move16 (xxx).L,(ax)
2113 else if (am0 == AIND)
2115 //move16 (ax),(xxx).L
2128 // pack/unpack (68020/68030/68040)
2130 int m_pack(WORD inst, WORD siz)
2135 return error("bad size suffix");
2137 if (*tok >= KW_D0 && *tok <= KW_D7)
2139 // Dx,Dy,#<adjustment>
2140 inst |= (0 << 3); // R/M
2141 inst |= (*tok++ & 7);
2142 if (*tok != ',' && tok[2] != ',')
2143 return error("missing comma");
2144 if (tok[1] < KW_D0 && tok[1] > KW_D7)
2145 return error(syntax_error);
2146 inst |= ((tok[1] & 7)<<9);
2149 // Fall through for adjustment (common in both valid cases)
2151 else if (*tok == '-')
2153 // -(Ax),-(Ay),#<adjustment>
2154 inst |= (1 << 3); // R/M
2155 tok++; // eat the minus
2156 if ((*tok != '(') && (tok[2]!=')') && (tok[3]!=',') && (tok[4] != '-') && (tok[5] != '(') && (tok[7] != ')') && (tok[8] != ','))
2157 return error(syntax_error);
2158 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2159 return error(syntax_error);
2160 if (tok[5] < KW_A0 && tok[6] > KW_A7)
2161 return error(syntax_error);
2162 inst |= ((tok[1] & 7) << 0);
2163 inst |= ((tok[6] & 7) << 9);
2166 // Fall through for adjustment (common in both valid cases)
2169 return error("invalid syntax");
2172 if ((*tok != CONST) && (*tok != SYMBOL) && (*tok != '-'))
2173 return error(syntax_error);
2175 if (expr(a0expr, &a0exval, &a0exattr, &a0esym)==ERROR)
2178 if ((a0exattr & DEFINED) == 0)
2179 return error(undef_error);
2181 if (a0exval + 0x8000 > 0x10000)
2185 return error(extra_stuff);
2187 D_word((a0exval & 0xffff));
2199 int m_rtm(WORD inst, WORD siz)
2207 else if (am0 == AREG)
2209 inst |= (1 << 3) + a0reg;
2212 return error("rtm only allows data or address registers.");
2223 int m_rtd(WORD inst, WORD siz)
2227 if (a0exattr & DEFINED)
2230 return error(abs_error);
2232 if ((a0exval + 0x8000) <= 0x7FFF)
2233 return error(range_error);
2239 return error(undef_error);
2248 int m_trapcc(WORD inst, WORD siz)
2256 else if (am0 == IMMED)
2260 if (a0exval < 0x10000)
2267 return error("Immediate value too big");
2277 return error("Invalid parameter for trapcc");
2284 // cinvl/p/a (68040)
2286 int m_cinv(WORD inst, WORD siz)
2291 inst |= (0 << 6) | (a1reg);
2295 inst |= (2 << 6) | (a1reg);
2298 inst |= (1 << 6) | (a1reg);
2301 inst |= (3 << 6) | (a1reg);
2311 // cpRESTORE (68020, 68030)
2313 int m_cprest(WORD inst, WORD siz)
2315 if (activecpu & !(CPU_68020 | CPU_68030))
2316 return error(unsupport);
2318 inst |= am0 | a0reg;
2327 // movec (68010, 68020, 68030, 68040, CPU32)
2329 int m_movec(WORD inst, WORD siz)
2333 if (am0 == DREG || am0 == AREG)
2341 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
2346 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
2357 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
2362 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2372 // moves (68010, 68020, 68030, 68040, CPU32)
2374 int m_moves(WORD inst, WORD siz)
2376 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2377 return error(unsupport);
2383 else if (siz == SIZL)
2394 inst |= am1 | a1reg;
2396 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2399 else if (am0 == AREG)
2401 inst |= am1 | a1reg;
2403 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2410 inst |= am0 | a0reg;
2412 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2417 inst |= am0 | a0reg;
2419 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2431 int m_pbcc(WORD inst, WORD siz)
2434 return error("Not implemented yet.");
2439 // pflusha (68030, 68040)
2441 int m_pflusha(WORD inst, WORD siz)
2443 if (activecpu == CPU_68030)
2446 inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
2450 else if (activecpu == CPU_68040)
2452 inst = B16(11110101, 00011000);
2457 return error(unsupport);
2465 // pflush (68030, 68040, 68060)
2467 int m_pflush(WORD inst, WORD siz)
2469 if (activecpu == CPU_68030)
2472 // PFLUSH FC, MASK, < ea >
2478 if (*tok != CONST && *tok != SYMBOL)
2479 return error("function code should be an expression");
2480 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2482 if ((a0exattr & DEFINED) == 0)
2483 return error("function code immediate should be defined");
2484 if (a0exval > 7 && a0exval < 0)
2485 return error("function code out of range (0-7)");
2496 fc = (1 << 4) | (*tok++ & 7);
2507 return error(syntax_error);
2511 return error("comma exptected");
2514 return error("mask should be an immediate value");
2515 if (*tok != CONST && *tok != SYMBOL)
2516 return error("mask is supposed to be immediate");
2517 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2519 if ((a0exattr & DEFINED) == 0)
2520 return error("mask immediate value should be defined");
2521 if (a0exval > 7 && a0exval < 0)
2522 return error("function code out of range (0-7)");
2523 mask = a0exval << 5;
2529 inst = (1 << 13) | fc | mask | (4 << 10);
2533 else if (*tok == ',')
2535 // PFLUSH FC, MASK, < ea >
2537 if (amode(0) == ERROR)
2540 return error(extra_stuff);
2541 if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE)
2543 inst |= am0 | a0reg;
2545 inst = (1 << 13) | fc | mask | (6 << 10);
2551 return error("unsupported addressing mode");
2555 return error(syntax_error);
2560 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2564 if (*tok != '(' && tok[2] != ')')
2565 return error(syntax_error);
2566 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2567 return error("expected (An)");
2568 if ((inst & 7) == 7)
2569 // With pflushn/pflush there's no easy way to
2570 // distinguish between the two in 68040 mode.
2571 // Ideally the opcode bitfields would have been
2572 // hardcoded in 68ktab but there is aliasing
2573 // between 68030 and 68040 opcode. So we just
2574 // set the 3 lower bits to 1 in pflushn inside
2575 // 68ktab and detect it here.
2576 inst = (inst & 0xff8) | 8;
2577 inst |= (tok[1] & 7) | (5 << 8);
2579 return error(extra_stuff);
2583 return error(unsupport);
2592 int m_pflushr(WORD inst, WORD siz)
2596 WORD flg = inst; // Save flag bits
2597 inst &= ~0x3F; // Clobber flag bits in instr
2599 // Install "standard" instr size bits
2605 // OR-in register number
2607 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2609 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2615 inst |= am1 | a1reg; // Get ea1 into instr
2616 D_word(inst); // Deposit instr
2618 // Generate ea0 if requested
2622 ea1gen(siz); // Generate ea1
2627 inst |= am0 | a0reg; // Get ea0 into instr
2628 D_word(inst); // Deposit instr
2629 ea0gen(siz); // Generate ea0
2631 // Generate ea1 if requested
2636 D_word(B16(10100000, 00000000));
2642 // ploadr, ploadw (68030)
2644 int m_pload(WORD inst, WORD siz, WORD extension)
2646 // TODO: 68551 support is not added yet.
2647 // None of the ST series of computers had
2648 // a 68020 + 68551 socket and since this is
2649 // an Atari targetted assembler....
2659 if (a0reg == KW_SFC - KW_SFC)
2663 else if (a0reg == KW_DFC - KW_SFC)
2668 return error("illegal control register specified");
2671 inst = (1 << 3) | a0reg;
2674 if ((a0exattr & DEFINED) == 0)
2675 return error("constant value must be defined");
2676 inst = (2 << 3) | a0exval;
2680 inst |= extension | (1 << 13);
2688 int m_ploadr(WORD inst, WORD siz)
2690 return m_pload(inst, siz, 1 << 9);
2693 int m_ploadw(WORD inst, WORD siz)
2695 return m_pload(inst, siz, 0 << 9);
2699 // pmove (68030/68551)
2701 int m_pmove(WORD inst, WORD siz)
2705 // TODO: 68551 support is not added yet.
2706 // None of the ST series of computers had
2707 // a 68020 + 68551 socket and since this is
2708 // an Atari targetted assembler....
2709 // (same for 68EC030)
2712 inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2713 inst &= ~(1 << 8); //And mask it out
2720 else if (am1 == CREG)
2726 return error("pmove sez: Wut?");
2728 // The instruction is a quad-word (8 byte) operation
2729 // for the CPU root pointer and the supervisor root pointer.
2730 // It is a long - word operation for the translation control register
2731 // and the transparent translation registers(TT0 and TT1).
2732 // It is a word operation for the MMU status register.
2734 if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
2735 && ((siz != SIZD) && (siz != SIZN)))
2736 return error(siz_error);
2738 if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
2739 && ((siz != SIZL) && (siz != SIZN)))
2740 return error(siz_error);
2742 if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
2743 return error(siz_error);
2748 inst |= am1 | a1reg;
2751 else if (am1 == CREG)
2753 inst |= am0 | a0reg;
2757 switch (reg + KW_SFC)
2760 inst2 |= (0 << 10) + (1 << 14); break;
2762 inst2 |= (2 << 10) + (1 << 14); break;
2764 inst2 |= (3 << 10) + (1 << 14); break;
2766 inst2 |= (2 << 10) + (0 << 13); break;
2768 inst2 |= (3 << 10) + (0 << 13); break;
2771 inst2 |= (1 << 9) + (3 << 13);
2773 inst2 |= (0 << 9) + (3 << 13);
2776 return error("unsupported register");
2786 else if (am1 == CREG)
2798 int m_pmovefd(WORD inst, WORD siz)
2802 return m_pmove(inst | (1 << 8), siz);
2809 #define gen_ptrapcc(name,opcode) \
2810 int m_##name(WORD inst, WORD siz) \
2816 D_word(B8(opcode)); \
2823 D_word(B8(opcode)); \
2828 int m_##name##n(WORD inst, WORD siz) \
2832 D_word(B8(opcode)); \
2836 gen_ptrapcc(ptrapbs,00000000)
2837 gen_ptrapcc(ptrapbc,00000001)
2838 gen_ptrapcc(ptrapls,00000010)
2839 gen_ptrapcc(ptraplc,00000011)
2840 gen_ptrapcc(ptrapss,00000100)
2841 gen_ptrapcc(ptrapsc,00000101)
2842 gen_ptrapcc(ptrapas,00000110)
2843 gen_ptrapcc(ptrapac,00000111)
2844 gen_ptrapcc(ptrapws,00001000)
2845 gen_ptrapcc(ptrapwc,00001001)
2846 gen_ptrapcc(ptrapis,00001010)
2847 gen_ptrapcc(ptrapic,00001011)
2848 gen_ptrapcc(ptrapgc,00001100)
2849 gen_ptrapcc(ptrapgs,00001101)
2850 gen_ptrapcc(ptrapcs,00001110)
2851 gen_ptrapcc(ptrapcc,00001111)
2853 //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; }
2854 //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; }
2855 //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; }
2856 //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; }
2857 //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; }
2858 //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; }
2859 //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; }
2860 //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; }
2861 //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; }
2862 //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; }
2863 //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; }
2864 //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; }
2865 //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; }
2866 //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; }
2867 //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; }
2868 //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; }
2869 //int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2870 //int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2871 //int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2872 //int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2873 //int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2874 //int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2875 //int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2876 //int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2877 //int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2878 //int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2879 //int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2880 //int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2881 //int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2882 //int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2883 //int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2884 //int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2888 // ptestr, ptestw (68030)
2890 int m_ptest(WORD inst, WORD siz)
2894 if (activecpu == CPU_68030)
2895 return error("Not implemented yet.");
2896 else if (activecpu == CPU_68040)
2897 return error("Not implemented yet.");
2903 #define FPU_NOWARN 0
2904 #define FPU_P_EMUL 1
2905 #define FPU_P2_EMU 2
2910 // Generate a FPU opcode
2912 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2914 if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
2916 inst |= (1 << 9); // Bolt on FPU id
2923 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2927 case SIZB: inst |= (6 << 10); break;
2928 case SIZW: inst |= (4 << 10); break;
2929 case SIZL: inst |= (0 << 10); break;
2931 case SIZS: inst |= (1 << 10); break;
2932 case SIZD: inst |= (5 << 10); break;
2933 case SIZX: inst |= (2 << 10); break;
2938 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2942 return error("Something bad happened, possibly, in gen_fpu.");
2946 inst |= (a1reg << 7);
2953 inst |= (1 << 9); //Bolt on FPU id
2957 inst |= (a1reg << 7);
2962 if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
2963 warn("Instruction is emulated in 68040");
2970 // fabs, fsabs, fdabs (6888X, 68040)
2972 int m_fabs(WORD inst, WORD siz)
2974 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2978 int m_fsabs(WORD inst, WORD siz)
2980 if (activefpu == FPU_68040)
2981 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2983 return error("Unsupported in current FPU");
2987 int m_fdabs(WORD inst, WORD siz)
2989 if (activefpu == FPU_68040)
2990 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2992 return error("Unsupported in current FPU");
2997 // facos (6888X, 68040FPSP)
2999 int m_facos(WORD inst, WORD siz)
3001 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
3006 // fadd (6888X, 68040FPSP)
3008 int m_fadd(WORD inst, WORD siz)
3010 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
3014 int m_fsadd(WORD inst, WORD siz)
3016 if (activefpu == FPU_68040)
3017 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
3019 return error("Unsupported in current FPU");
3023 int m_fdadd(WORD inst, WORD siz)
3025 if (activefpu == FPU_68040)
3026 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
3028 return error("Unsupported in current FPU");
3033 // fasin (6888X, 68040FPSP)f
3035 int m_fasin(WORD inst, WORD siz)
3037 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
3042 // fatan (6888X, 68040FPSP)
3044 int m_fatan(WORD inst, WORD siz)
3046 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
3051 // fatanh (6888X, 68040FPSP)
3053 int m_fatanh(WORD inst, WORD siz)
3055 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
3060 // fcmp (6888X, 68040)
3062 int m_fcmp(WORD inst, WORD siz)
3064 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
3069 // fcos (6888X, 68040FPSP)
3071 int m_fcos(WORD inst, WORD siz)
3073 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
3078 // fcosh (6888X, 68040FPSP)
3080 int m_fcosh(WORD inst, WORD siz)
3082 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
3087 // fdbcc (6888X, 68040)
3089 int m_fdbcc(WORD inst, WORD siz)
3091 WORD opcode = inst & 0x3F; //Grab conditional bitfield
3101 if (a1exattr & DEFINED)
3103 if ((a1exattr & TDB) != cursect)
3104 return error(rel_error);
3106 uint32_t v = a1exval - sloc;
3108 if ((v + 0x8000) > 0x10000)
3109 return error(range_error);
3115 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
3124 // fdiv (6888X, 68040)
3126 int m_fdiv(WORD inst, WORD siz)
3128 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
3132 int m_fsdiv(WORD inst, WORD siz)
3134 if (activefpu == FPU_68040)
3135 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
3137 return error("Unsupported in current FPU");
3141 int m_fddiv(WORD inst, WORD siz)
3143 if (activefpu == FPU_68040)
3144 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3146 return error("Unsupported in current FPU");
3151 // fetox (6888X, 68040FPSP)
3153 int m_fetox(WORD inst, WORD siz)
3155 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
3160 // fetoxm1 (6888X, 68040FPSP)
3162 int m_fetoxm1(WORD inst, WORD siz)
3164 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
3169 // fgetexp (6888X, 68040FPSP)
3171 int m_fgetexp(WORD inst, WORD siz)
3173 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
3178 // fgetman (6888X, 68040FPSP)
3180 int m_fgetman(WORD inst, WORD siz)
3182 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
3187 // fint (6888X, 68040FPSP)
3189 int m_fint(WORD inst, WORD siz)
3192 // special case - fint fpx = fint fpx,fpx
3195 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
3200 // fintrz (6888X, 68040FPSP)
3202 int m_fintrz(WORD inst, WORD siz)
3205 // special case - fintrz fpx = fintrz fpx,fpx
3208 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
3213 // flog10 (6888X, 68040FPSP)
3215 int m_flog10(WORD inst, WORD siz)
3217 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
3222 // flog2 (6888X, 68040FPSP)
3224 int m_flog2(WORD inst, WORD siz)
3226 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
3231 // flogn (6888X, 68040FPSP)
3233 int m_flogn(WORD inst, WORD siz)
3235 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
3240 // flognp1 (6888X, 68040FPSP)
3242 int m_flognp1(WORD inst, WORD siz)
3244 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
3249 // fmod (6888X, 68040FPSP)
3251 int m_fmod(WORD inst, WORD siz)
3253 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
3258 // fmove (6888X, 68040)
3260 int m_fmove(WORD inst, WORD siz)
3264 if ((am0 == FREG) && (am1 < AM_USP))
3268 inst |= am1 | a1reg;
3277 case SIZB: inst |= (6 << 10); break;
3278 case SIZW: inst |= (4 << 10); break;
3279 case SIZL: inst |= (0 << 10); break;
3281 case SIZS: inst |= (1 << 10); break;
3282 case SIZD: inst |= (5 << 10); break;
3283 case SIZX: inst |= (2 << 10); break;
3284 case SIZP: inst |= (3 << 10);
3285 // In P size we have 2 cases: {#k} where k is immediate
3286 // and {Dn} where Dn=Data register
3292 inst |= bfval1 << 4;
3297 if (bfval1>63 && bfval1<-64)
3298 return error("K-factor must be between -64 and 63");
3299 inst |= bfval1 & 127;
3304 return error("Something bad happened, possibly.");
3309 // Destination specifier
3310 inst |= (a0reg << 7);
3318 else if ((am0 < AM_USP) && (am1 == FREG))
3323 inst |= am0 | a0reg;
3332 case SIZB: inst |= (6 << 10); break;
3333 case SIZW: inst |= (4 << 10); break;
3334 case SIZL: inst |= (0 << 10); break;
3336 case SIZS: inst |= (1 << 10); break;
3337 case SIZD: inst |= (5 << 10); break;
3338 case SIZX: inst |= (2 << 10); break;
3339 case SIZP: inst |= (3 << 10); break;
3341 return error("Something bad happened, possibly.");
3345 // Destination specifier
3346 inst |= (a1reg << 7);
3354 else if ((am0 == FREG) && (am1 == FREG))
3356 // register-to-register
3357 // Essentially ea to register with R/0=0
3367 return error("Invalid size");
3370 inst |= (a0reg << 10);
3372 // Destination register
3373 inst |= (a1reg << 7);
3383 // fmove (6888X, 68040)
3385 int m_fmovescr(WORD inst, WORD siz)
3387 // Move Floating-Point System Control Register (FPCR)
3391 if ((am0 == FPSCR) && (am1 < AM_USP))
3393 inst |= am1 | a1reg;
3395 inst = (1 << 13) + (1 << 15);
3401 else if ((am1 == FPSCR) && (am0 < AM_USP))
3403 inst |= am0 | a0reg;
3405 inst = (0 << 13) + (1 << 15);
3412 return error("m_fmovescr says: wut?");
3416 // fsmove/fdmove (68040)
3418 int m_fsmove(WORD inst, WORD siz)
3420 return error("Not implemented yet.");
3423 if (activefpu == FPU_68040)
3424 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3426 return error("Unsupported in current FPU");
3431 int m_fdmove(WORD inst, WORD siz)
3433 return error("Not implemented yet.");
3436 if (activefpu == FPU_68040)
3437 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3439 return error("Unsupported in current FPU");
3445 // fmovecr (6888X, 68040FPSP)
3447 int m_fmovecr(WORD inst, WORD siz)
3455 if (activefpu == FPU_68040)
3456 warn("Instruction is emulated in 68040");
3463 // fmovem (6888X, 68040)
3465 int m_fmovem(WORD inst, WORD siz)
3470 if (siz == SIZX || siz==SIZN)
3472 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3474 //fmovem.x <rlist>,ea
3475 if (fpu_reglist_left(®mask) < 0)
3479 return error("missing comma");
3484 inst |= am0 | a0reg;
3486 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3487 return error("invalid addressing mode");
3490 inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
3495 else if ((*tok >= KW_D0) && (*tok <= KW_D7))
3498 datareg = (*tok++ & 7) << 10;
3501 return error("missing comma");
3506 inst |= am0 | a0reg;
3508 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3509 return error("invalid addressing mode");
3512 inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
3523 inst |= am0 | a0reg;
3526 return error("missing comma");
3528 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3530 //fmovem.x ea,<rlist>
3531 if (fpu_reglist_right(®mask) < 0)
3535 inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
3543 datareg = (*tok++ & 7) << 10;
3545 inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
3552 else if (siz == SIZL)
3554 if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
3556 //fmovem.l <rlist>,ea
3557 regmask = (1 << 15) | (1 << 13);
3559 if (*tok == KW_FPCR)
3561 regmask |= (1 << 12);
3566 if (*tok == KW_FPSR)
3568 regmask |= (1 << 11);
3573 if (*tok == KW_FPIAR)
3575 regmask |= (1 << 10);
3580 if ((*tok == '/') || (*tok == '-'))
3587 return error("missing comma");
3592 inst |= am0 | a0reg;
3599 //fmovem.l ea,<rlist>
3603 inst |= am0 | a0reg;
3606 return error("missing comma");
3608 regmask = (1 << 15) | (0 << 13);
3611 if (*tok == KW_FPCR)
3613 regmask |= (1 << 12);
3618 if (*tok == KW_FPSR)
3620 regmask |= (1 << 11);
3625 if (*tok == KW_FPIAR)
3627 regmask |= (1 << 10);
3632 if ((*tok == '/') || (*tok == '-'))
3639 return error("extra (unexpected) text found");
3641 inst |= am0 | a0reg;
3648 return error("bad size suffix");
3655 // fmul (6888X, 68040)
3657 int m_fmul(WORD inst, WORD siz)
3659 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
3663 int m_fsmul(WORD inst, WORD siz)
3665 if (activefpu == FPU_68040)
3666 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
3668 return error("Unsupported in current FPU");
3672 int m_fdmul(WORD inst, WORD siz)
3674 if (activefpu == FPU_68040)
3675 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
3677 return error("Unsupported in current FPU");
3682 // fneg (6888X, 68040)
3684 int m_fneg(WORD inst, WORD siz)
3686 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
3690 int m_fsneg(WORD inst, WORD siz)
3692 if (activefpu == FPU_68040)
3693 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
3695 return error("Unsupported in current FPU");
3699 int m_fdneg(WORD inst, WORD siz)
3701 if (activefpu == FPU_68040)
3702 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
3704 return error("Unsupported in current FPU");
3709 // fnop (6888X, 68040)
3711 int m_fnop(WORD inst, WORD siz)
3713 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3718 // frem (6888X, 68040FPSP)
3720 int m_frem(WORD inst, WORD siz)
3722 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3727 // fscale (6888X, 68040FPSP)
3729 int m_fscale(WORD inst, WORD siz)
3731 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3736 // FScc (6888X, 68040)
3738 //int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3739 //int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3740 //int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3741 //int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3742 //int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3743 //int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3744 //int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3745 //int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3746 //int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3747 //int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3748 //int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3749 //int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3750 //int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3751 //int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3752 //int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3753 //int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3754 //int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3755 //int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3756 //int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3757 //int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3758 //int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3759 //int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3760 //int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3761 //int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3762 //int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3763 //int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3764 //int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3765 //int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3766 //int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3767 //int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3768 //int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3769 //int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3771 #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;}
3772 gen_FScc(fseq , 00000001);
3773 gen_FScc(fsne , 00001110);
3774 gen_FScc(fsgt , 00010010);
3775 gen_FScc(fsngt , 00011101);
3776 gen_FScc(fsge , 00010011);
3777 gen_FScc(fsnge , 00011100);
3778 gen_FScc(fslt , 00010100);
3779 gen_FScc(fsnlt , 00011011);
3780 gen_FScc(fsle , 00010101);
3781 gen_FScc(fsnle , 00011010);
3782 gen_FScc(fsgl , 00010110);
3783 gen_FScc(fsngl , 00011001);
3784 gen_FScc(fsgle , 00010111);
3785 gen_FScc(fsngle, 00011000);
3786 gen_FScc(fsogt , 00000010);
3787 gen_FScc(fsule , 00001101);
3788 gen_FScc(fsoge , 00000011);
3789 gen_FScc(fsult , 00001100);
3790 gen_FScc(fsolt , 00000100);
3791 gen_FScc(fsuge , 00001011);
3792 gen_FScc(fsole , 00000101);
3793 gen_FScc(fsugt , 00001010);
3794 gen_FScc(fsogl , 00000110);
3795 gen_FScc(fsueq , 00001001);
3796 gen_FScc(fsor , 00000111);
3797 gen_FScc(fsun , 00001000);
3798 gen_FScc(fsf , 00000000);
3799 gen_FScc(fst , 00001111);
3800 gen_FScc(fssf , 00010000);
3801 gen_FScc(fsst , 00011111);
3802 gen_FScc(fsseq , 00010001);
3803 gen_FScc(fssne , 00011110);
3806 // FTRAPcc (6888X, 68040)
3808 //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;}
3809 //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;}
3810 //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;}
3811 //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;}
3812 //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;}
3813 //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;}
3814 //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;}
3815 //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;}
3816 //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;}
3817 //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;}
3818 //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;}
3819 //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;}
3820 //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;}
3821 //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;}
3822 //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;}
3823 //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;}
3824 //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;}
3825 //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;}
3826 //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;}
3827 //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;}
3828 //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;}
3829 //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;}
3830 //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;}
3831 //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;}
3832 //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;}
3833 //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;}
3834 //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;}
3835 //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;}
3836 //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;}
3837 //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;}
3838 //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;}
3839 //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;}
3841 //int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3842 //int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3843 //int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3844 //int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3845 //int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3846 //int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3847 //int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3848 //int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3849 //int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3850 //int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3851 //int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3852 //int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3853 //int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3854 //int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3855 //int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3856 //int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3857 //int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3858 //int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3859 //int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3860 //int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3861 //int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3862 //int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3863 //int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3864 //int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3865 //int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3866 //int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3867 //int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3868 //int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3869 //int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3870 //int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3871 //int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3872 //int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3874 #define gen_FTRAPcc(name,opcode) \
3875 int m_##name (WORD inst, WORD siz) \
3880 D_word(B8(opcode)); \
3887 D_word(B8(opcode)); \
3892 int m_##name##n (WORD inst, WORD siz) \
3895 D_word(B8(opcode)); \
3899 gen_FTRAPcc(ftrapeq ,00000001)
3900 gen_FTRAPcc(ftrapne ,00001110)
3901 gen_FTRAPcc(ftrapgt ,00010010)
3902 gen_FTRAPcc(ftrapngt ,00011101)
3903 gen_FTRAPcc(ftrapge ,00010011)
3904 gen_FTRAPcc(ftrapnge ,00011100)
3905 gen_FTRAPcc(ftraplt ,00010100)
3906 gen_FTRAPcc(ftrapnlt ,00011011)
3907 gen_FTRAPcc(ftraple ,00010101)
3908 gen_FTRAPcc(ftrapnle ,00011010)
3909 gen_FTRAPcc(ftrapgl ,00010110)
3910 gen_FTRAPcc(ftrapngl ,00011001)
3911 gen_FTRAPcc(ftrapgle ,00010111)
3912 gen_FTRAPcc(ftrapngle ,00011000)
3913 gen_FTRAPcc(ftrapogt ,00000010)
3914 gen_FTRAPcc(ftrapule ,00001101)
3915 gen_FTRAPcc(ftrapoge ,00000011)
3916 gen_FTRAPcc(ftrapult ,00001100)
3917 gen_FTRAPcc(ftrapolt ,00000100)
3918 gen_FTRAPcc(ftrapuge ,00001011)
3919 gen_FTRAPcc(ftrapole ,00000101)
3920 gen_FTRAPcc(ftrapugt ,00001010)
3921 gen_FTRAPcc(ftrapogl ,00000110)
3922 gen_FTRAPcc(ftrapueq ,00001001)
3923 gen_FTRAPcc(ftrapor ,00000111)
3924 gen_FTRAPcc(ftrapun ,00001000)
3925 gen_FTRAPcc(ftrapf ,00000000)
3926 gen_FTRAPcc(ftrapt ,00001111)
3927 gen_FTRAPcc(ftrapsf ,00010000)
3928 gen_FTRAPcc(ftrapst ,00011111)
3929 gen_FTRAPcc(ftrapseq ,00010001)
3930 gen_FTRAPcc(ftrapsne ,00011110)
3933 // fsgldiv (6888X, 68040)
3935 int m_fsgldiv(WORD inst, WORD siz)
3937 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3942 // fsglmul (6888X, 68040)
3944 int m_fsglmul(WORD inst, WORD siz)
3946 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3951 // fsin (6888X, 68040FPSP)
3953 int m_fsin(WORD inst, WORD siz)
3955 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3960 // fsincos (6888X, 68040FPSP)
3962 int m_fsincos(WORD inst, WORD siz)
3964 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
3975 // fsin (6888X, 68040FPSP)
3977 int m_fsinh(WORD inst, WORD siz)
3979 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3984 // fsqrt (6888X, 68040)
3986 int m_fsqrt(WORD inst, WORD siz)
3988 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3992 int m_fsfsqrt(WORD inst, WORD siz)
3994 if (activefpu == FPU_68040)
3995 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
3997 return error("Unsupported in current FPU");
4001 int m_fdfsqrt(WORD inst, WORD siz)
4003 if (activefpu == FPU_68040)
4004 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
4006 return error("Unsupported in current FPU");
4011 // fsub (6888X, 68040)
4013 int m_fsub(WORD inst, WORD siz)
4015 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
4019 int m_fsfsub(WORD inst, WORD siz)
4021 if (activefpu == FPU_68040)
4022 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
4024 return error("Unsupported in current FPU");
4028 int m_fdsub(WORD inst, WORD siz)
4030 if (activefpu == FPU_68040)
4031 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
4033 return error("Unsupported in current FPU");
4038 // ftan (6888X, 68040FPSP)
4040 int m_ftan(WORD inst, WORD siz)
4042 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
4047 // ftanh (6888X, 68040FPSP)
4049 int m_ftanh(WORD inst, WORD siz)
4051 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
4056 // ftentox (6888X, 68040FPSP)
4058 int m_ftentox(WORD inst, WORD siz)
4060 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
4065 // ftst (6888X, 68040)
4067 int m_ftst(WORD inst, WORD siz)
4069 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
4074 // ftwotox (6888X, 68040FPSP)
4076 int m_ftwotox(WORD inst, WORD siz)
4078 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);