2 // RMAC - Reboot's Macro Assembler for all Atari computers
3 // MACH.C - Code Generation
4 // Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source utilised with the kind permission of Landon Dyer
24 int movep = 0; // Global flag to indicate we're generating a movep instruction
26 // Function prototypes
27 int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
28 int m_self(WORD, WORD);
29 int m_abcd(WORD, WORD);
30 int m_reg(WORD, WORD);
31 int m_imm(WORD, WORD);
32 int m_imm8(WORD, WORD);
33 int m_shi(WORD, WORD);
34 int m_shr(WORD, WORD);
35 int m_bitop(WORD, WORD);
36 int m_exg(WORD, WORD);
38 int m_lea(WORD, WORD);
40 int m_dbra(WORD, WORD);
41 int m_link(WORD, WORD);
42 int m_adda(WORD, WORD);
43 int m_addq(WORD, WORD);
44 //int m_move(WORD, int);
45 int m_move(WORD, WORD);
46 int m_moveq(WORD, WORD);
47 int m_usp(WORD, WORD);
48 int m_movep(WORD, WORD);
49 int m_trap(WORD, WORD);
50 int m_movem(WORD, WORD);
51 int m_clra(WORD, WORD);
53 int m_move30(WORD, WORD); //68020/30/40/60
54 int m_br30(WORD inst, WORD siz);
55 int m_ea030(WORD inst, WORD siz);
56 int m_bfop(WORD inst, WORD siz);
57 int m_callm(WORD inst, WORD siz);
58 int m_cas(WORD inst, WORD siz);
59 int m_cas2(WORD inst, WORD siz);
60 int m_chk2(WORD inst, WORD siz);
61 int m_cmp2(WORD inst, WORD siz);
62 int m_bkpt(WORD inst, WORD siz);
63 int m_cpbr(WORD inst, WORD siz);
64 int m_cpdbr(WORD inst, WORD siz);
65 int m_divs(WORD inst, WORD siz);
66 int m_muls(WORD inst, WORD siz);
67 int m_divu(WORD inst, WORD siz);
68 int m_mulu(WORD inst, WORD siz);
69 int m_divsl(WORD inst, WORD siz);
70 int m_divul(WORD inst, WORD siz);
71 int m_move16a(WORD inst, WORD siz);
72 int m_move16b(WORD inst, WORD siz);
73 int m_pack(WORD inst, WORD siz);
74 int m_rtm(WORD inst, WORD siz);
75 int m_rtd(WORD inst, WORD siz);
76 int m_trapcc(WORD inst, WORD siz);
77 int m_cinv(WORD inst, WORD siz);
78 int m_cprest(WORD inst, WORD siz);
79 int m_movec(WORD inst, WORD siz);
80 int m_moves(WORD inst, WORD siz);
83 int m_pbcc(WORD inst, WORD siz);
84 int m_pflusha(WORD inst, WORD siz);
85 int m_pflush(WORD inst, WORD siz);
86 int m_pflushr(WORD inst, WORD siz);
87 int m_pload(WORD inst, WORD siz, WORD extension);
88 int m_pmove(WORD inst, WORD siz);
89 int m_pmovefd(WORD inst, WORD siz);
90 int m_ptest(WORD inst, WORD siz);
91 int m_ptrapbs(WORD inst, WORD siz);
92 int m_ptrapbc(WORD inst, WORD siz);
93 int m_ptrapls(WORD inst, WORD siz);
94 int m_ptraplc(WORD inst, WORD siz);
95 int m_ptrapss(WORD inst, WORD siz);
96 int m_ptrapsc(WORD inst, WORD siz);
97 int m_ptrapas(WORD inst, WORD siz);
98 int m_ptrapac(WORD inst, WORD siz);
99 int m_ptrapws(WORD inst, WORD siz);
100 int m_ptrapwc(WORD inst, WORD siz);
101 int m_ptrapis(WORD inst, WORD siz);
102 int m_ptrapic(WORD inst, WORD siz);
103 int m_ptrapgc(WORD inst, WORD siz);
104 int m_ptrapgs(WORD inst, WORD siz);
105 int m_ptrapcs(WORD inst, WORD siz);
106 int m_ptrapcc(WORD inst, WORD siz);
107 int m_ptrapbsn(WORD inst, WORD siz);
108 int m_ptrapbcn(WORD inst, WORD siz);
109 int m_ptraplsn(WORD inst, WORD siz);
110 int m_ptraplcn(WORD inst, WORD siz);
111 int m_ptrapssn(WORD inst, WORD siz);
112 int m_ptrapscn(WORD inst, WORD siz);
113 int m_ptrapasn(WORD inst, WORD siz);
114 int m_ptrapacn(WORD inst, WORD siz);
115 int m_ptrapwsn(WORD inst, WORD siz);
116 int m_ptrapwcn(WORD inst, WORD siz);
117 int m_ptrapisn(WORD inst, WORD siz);
118 int m_ptrapicn(WORD inst, WORD siz);
119 int m_ptrapgsn(WORD inst, WORD siz);
120 int m_ptrapgcn(WORD inst, WORD siz);
121 int m_ptrapcsn(WORD inst, WORD siz);
122 int m_ptrapccn(WORD inst, WORD siz);
123 int m_ploadr(WORD inst, WORD siz);
124 int m_ploadw(WORD inst, WORD siz);
127 int m_fabs(WORD inst, WORD siz);
128 int m_facos(WORD inst, WORD siz);
129 int m_fadd(WORD inst, WORD siz);
130 int m_fasin(WORD inst, WORD siz);
131 int m_fatan(WORD inst, WORD siz);
132 int m_fatanh(WORD inst, WORD siz);
133 int m_fcmp(WORD inst, WORD siz);
134 int m_fcos(WORD inst, WORD siz);
135 int m_fcosh(WORD inst, WORD siz);
136 int m_fdabs(WORD inst, WORD siz);
137 int m_fdadd(WORD inst, WORD siz);
138 int m_fdbcc(WORD inst, WORD siz);
139 int m_fddiv(WORD inst, WORD siz);
140 int m_fdfsqrt(WORD inst, WORD siz);
141 int m_fdiv(WORD inst, WORD siz);
142 int m_fdmove(WORD inst, WORD siz);
143 int m_fdmul(WORD inst, WORD siz);
144 int m_fdneg(WORD inst, WORD siz);
145 int m_fdsub(WORD inst, WORD siz);
146 int m_fetox(WORD inst, WORD siz);
147 int m_fetoxm1(WORD inst, WORD siz);
148 int m_fgetexp(WORD inst, WORD siz);
149 int m_fgetman(WORD inst, WORD siz);
150 int m_fint(WORD inst, WORD siz);
151 int m_fintrz(WORD inst, WORD siz);
152 int m_flog10(WORD inst, WORD siz);
153 int m_flog2(WORD inst, WORD siz);
154 int m_flogn(WORD inst, WORD siz);
155 int m_flognp1(WORD inst, WORD siz);
156 int m_fmod(WORD inst, WORD siz);
157 int m_fmove(WORD inst, WORD siz);
158 int m_fmovescr(WORD inst, WORD siz);
159 int m_fmovecr(WORD inst, WORD siz);
160 int m_fmovem(WORD inst, WORD siz);
161 int m_fmul(WORD inst, WORD siz);
162 int m_fneg(WORD inst, WORD siz);
163 int m_fnop(WORD inst, WORD siz);
164 int m_frem(WORD inst, WORD siz);
165 int m_fsabs(WORD inst, WORD siz);
166 int m_fsadd(WORD inst, WORD siz);
167 int m_fseq(WORD inst, WORD siz);
168 int m_fsne(WORD inst, WORD siz);
169 int m_fsgt(WORD inst, WORD siz);
170 int m_fsngt(WORD inst, WORD siz);
171 int m_fsge(WORD inst, WORD siz);
172 int m_fsnge(WORD inst, WORD siz);
173 int m_fslt(WORD inst, WORD siz);
174 int m_fsnlt(WORD inst, WORD siz);
175 int m_fsle(WORD inst, WORD siz);
176 int m_fsnle(WORD inst, WORD siz);
177 int m_fsgl(WORD inst, WORD siz);
178 int m_fsngl(WORD inst, WORD siz);
179 int m_fsgle(WORD inst, WORD siz);
180 int m_fsngle(WORD inst, WORD siz);
181 int m_fsogt(WORD inst, WORD siz);
182 int m_fsule(WORD inst, WORD siz);
183 int m_fsoge(WORD inst, WORD siz);
184 int m_fsult(WORD inst, WORD siz);
185 int m_fsolt(WORD inst, WORD siz);
186 int m_fsuge(WORD inst, WORD siz);
187 int m_fsole(WORD inst, WORD siz);
188 int m_fsugt(WORD inst, WORD siz);
189 int m_fsogl(WORD inst, WORD siz);
190 int m_fsueq(WORD inst, WORD siz);
191 int m_fsor(WORD inst, WORD siz);
192 int m_fsun(WORD inst, WORD siz);
193 int m_fsf(WORD inst, WORD siz);
194 int m_fst(WORD inst, WORD siz);
195 int m_fssf(WORD inst, WORD siz);
196 int m_fsst(WORD inst, WORD siz);
197 int m_fsseq(WORD inst, WORD siz);
198 int m_fssne(WORD inst, WORD siz);
199 int m_fscale(WORD inst, WORD siz);
200 int m_fsdiv(WORD inst, WORD siz);
201 int m_fsfsqrt(WORD inst, WORD siz);
202 int m_fsfsub(WORD inst, WORD siz);
203 int m_fsgldiv(WORD inst, WORD siz);
204 int m_fsglmul(WORD inst, WORD siz);
205 int m_fsin(WORD inst, WORD siz);
206 int m_fsincos(WORD inst, WORD siz);
207 int m_fsinh(WORD inst, WORD siz);
208 int m_fsmove(WORD inst, WORD siz);
209 int m_fsmul(WORD inst, WORD siz);
210 int m_fsneg(WORD inst, WORD siz);
211 int m_fsqrt(WORD inst, WORD siz);
212 int m_fsub(WORD inst, WORD siz);
213 int m_ftan(WORD inst, WORD siz);
214 int m_ftanh(WORD inst, WORD siz);
215 int m_ftentox(WORD inst, WORD siz);
216 int m_ftst(WORD inst, WORD siz);
217 int m_ftwotox(WORD inst, WORD siz);
218 int m_ftrapeq(WORD inst, WORD siz);
219 int m_ftrapne(WORD inst, WORD siz);
220 int m_ftrapgt(WORD inst, WORD siz);
221 int m_ftrapngt(WORD inst, WORD siz);
222 int m_ftrapge(WORD inst, WORD siz);
223 int m_ftrapnge(WORD inst, WORD siz);
224 int m_ftraplt(WORD inst, WORD siz);
225 int m_ftrapnlt(WORD inst, WORD siz);
226 int m_ftraple(WORD inst, WORD siz);
227 int m_ftrapnle(WORD inst, WORD siz);
228 int m_ftrapgl(WORD inst, WORD siz);
229 int m_ftrapngl(WORD inst, WORD siz);
230 int m_ftrapgle(WORD inst, WORD siz);
231 int m_ftrapngle(WORD inst, WORD siz);
232 int m_ftrapogt(WORD inst, WORD siz);
233 int m_ftrapule(WORD inst, WORD siz);
234 int m_ftrapoge(WORD inst, WORD siz);
235 int m_ftrapult(WORD inst, WORD siz);
236 int m_ftrapolt(WORD inst, WORD siz);
237 int m_ftrapuge(WORD inst, WORD siz);
238 int m_ftrapole(WORD inst, WORD siz);
239 int m_ftrapugt(WORD inst, WORD siz);
240 int m_ftrapogl(WORD inst, WORD siz);
241 int m_ftrapueq(WORD inst, WORD siz);
242 int m_ftrapor(WORD inst, WORD siz);
243 int m_ftrapun(WORD inst, WORD siz);
244 int m_ftrapf(WORD inst, WORD siz);
245 int m_ftrapt(WORD inst, WORD siz);
246 int m_ftrapsf(WORD inst, WORD siz);
247 int m_ftrapst(WORD inst, WORD siz);
248 int m_ftrapseq(WORD inst, WORD siz);
249 int m_ftrapsne(WORD inst, WORD siz);
250 int m_ftrapeqn(WORD inst, WORD siz);
251 int m_ftrapnen(WORD inst, WORD siz);
252 int m_ftrapgtn(WORD inst, WORD siz);
253 int m_ftrapngtn(WORD inst, WORD siz);
254 int m_ftrapgen(WORD inst, WORD siz);
255 int m_ftrapngen(WORD inst, WORD siz);
256 int m_ftrapltn(WORD inst, WORD siz);
257 int m_ftrapnltn(WORD inst, WORD siz);
258 int m_ftraplen(WORD inst, WORD siz);
259 int m_ftrapnlen(WORD inst, WORD siz);
260 int m_ftrapgln(WORD inst, WORD siz);
261 int m_ftrapngln(WORD inst, WORD siz);
262 int m_ftrapglen(WORD inst, WORD siz);
263 int m_ftrapnglen(WORD inst, WORD siz);
264 int m_ftrapogtn(WORD inst, WORD siz);
265 int m_ftrapulen(WORD inst, WORD siz);
266 int m_ftrapogen(WORD inst, WORD siz);
267 int m_ftrapultn(WORD inst, WORD siz);
268 int m_ftrapoltn(WORD inst, WORD siz);
269 int m_ftrapugen(WORD inst, WORD siz);
270 int m_ftrapolen(WORD inst, WORD siz);
271 int m_ftrapugtn(WORD inst, WORD siz);
272 int m_ftrapogln(WORD inst, WORD siz);
273 int m_ftrapueqn(WORD inst, WORD siz);
274 int m_ftraporn(WORD inst, WORD siz);
275 int m_ftrapunn(WORD inst, WORD siz);
276 int m_ftrapfn(WORD inst, WORD siz);
277 int m_ftraptn(WORD inst, WORD siz);
278 int m_ftrapsfn(WORD inst, WORD siz);
279 int m_ftrapstn(WORD inst, WORD siz);
280 int m_ftrapseqn(WORD inst, WORD siz);
281 int m_ftrapsnen(WORD inst, WORD siz);
283 // Common error messages
284 char range_error[] = "expression out of range";
285 char abs_error[] = "illegal absolute expression";
286 char seg_error[] = "bad (section) expression";
287 char rel_error[] = "illegal relative address";
288 char siz_error[] = "bad size specified";
289 char undef_error[] = "undefined expression";
290 char fwd_error[] = "forward or undefined expression";
291 char unsupport[] = "unsupported for selected CPU";
293 // Include code tables
295 { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0
297 { 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry
300 // Register number << 9
302 0, 1 << 9, 2 << 9, 3 << 9, 4 << 9, 5 << 9, 6 << 9, 7 << 9
305 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
309 1<<6, (WORD)-1, // SIZW, n/a
310 2<<6, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
314 // Byte/word/long size for MOVE instrs
318 0x3000, (WORD)-1, // Word
319 0x2000, (WORD)-1, (WORD)-1, (WORD)-1, // Long
320 0x3000 // Word (SIZN)
323 // Word/long size (0=.w, 1=.l) in bit 8
327 0, (WORD)-1, // SIZW, n/a
328 1<<8, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
332 // Byte/Word/long size (0=.w, 1=.l) in bit 9
336 1<<9, (WORD)-1, // Word
337 1<<10, (WORD)-1, (WORD)-1, (WORD)-1, // Long
341 // Addressing mode in bits 6..11 (register/mode fields are reversed)
343 00000, 01000, 02000, 03000, 04000, 05000, 06000, 07000,
344 00100, 01100, 02100, 03100, 04100, 05100, 06100, 07100,
345 00200, 01200, 02200, 03200, 04200, 05200, 06200, 07200,
346 00300, 01300, 02300, 03300, 04300, 05300, 06300, 07300,
347 00400, 01400, 02400, 03400, 04400, 05400, 06400, 07400,
348 00500, 01500, 02500, 03500, 04500, 05500, 06500, 07500,
349 00600, 01600, 02600, 03600, 04600, 05600, 06600, 07600,
350 00700, 01700, 02700, 03700, 04700, 05700, 06700, 07700
353 // Control registers lookup table
355 // MC68010/MC68020/MC68030/MC68040/CPU32
356 0x000, // Source Function Code(SFC)
357 0x001, // Destination Function Code(DFC)
358 0x800, // User Stack Pointer(USP)
359 0x801, // Vector Base Register(VBR)
360 // MC68020 / MC68030 / MC68040
361 0x002, // Cache Control Register(CACR)
362 0x802, // Cache Address Register(CAAR) (020/030 only)
363 0x803, // Master Stack Pointer(MSP)
364 0x804, // Interrupt Stack Pointer(ISP)
365 // MC68040 / MC68LC040
366 0x003, // MMU Translation Control Register(TC)
367 0x004, // Instruction Transparent Translation Register 0 (ITT0)
368 0x005, // Instruction Transparent Translation Register 1 (ITT1)
369 0x006, // Data Transparent Translation Register 0 (DTT0)
370 0x007, // Data Transparent Translation Register 1 (DTT1)
371 0x805, // MMU Status Register(MMUSR)
372 0x806, // User Root Pointer(URP)
373 0x807, // Supervisor Root Pointer(SRP)
375 0x004, // Instruction Access Control Register 0 (IACR0)
376 0x005, // Instruction Access Control Register 1 (IACR1)
377 0x006, // Data Access Control Register 0 (DACR1)
378 0x007, // Data Access Control Register 1 (DACR1)
380 0xFFF // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
385 int m_unimp(WORD unused1, WORD unused2)
387 return (int)error("unimplemented mnemonic");
391 //int m_badmode(void)
392 int m_badmode(WORD unused1, WORD unused2)
394 return (int)error("inappropriate addressing mode");
398 int m_self(WORD inst, WORD usused)
406 // Do one EA in bits 0..5
408 // Bits in `inst' have the following meaning:
410 // Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits
413 // If bit one is set, the OTHER ea (the one that wasn't generated by bit zero)
414 // is generated after the instruction. Regardless of bit 0's value, ea0 is
415 // always deposited in memory before ea1.
417 // If bit two is set, standard size bits are set in the instr in bits 6 and 7.
419 // If bit four is set, bit three specifies which eaXreg to place in bits 9..11
422 int m_ea(WORD inst, WORD siz)
424 WORD flg = inst; // Save flag bits
425 inst &= ~0x3F; // Clobber flag bits in instr
427 // Install "standard" instr size bits
433 // OR-in register number
435 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
437 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
443 inst |= am1 | a1reg; // Get ea1 into instr
444 D_word(inst); // Deposit instr
446 // Generate ea0 if requested
450 ea1gen(siz); // Generate ea1
455 inst |= am0 | a0reg; // Get ea0 into instr
456 D_word(inst); // Deposit instr
457 ea0gen(siz); // Generate ea0
459 // Generate ea1 if requested
469 // Check if lea x(an),an can be optimised to addq.w #x,an--otherwise fall back
472 int m_lea(WORD inst, WORD siz)
474 if (CHECK_OPTS(OPT_LEA_ADDQ)
475 && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
476 && ((a0exval > 0) && (a0exval <= 8)))
478 inst = B16(01010000, 01001000) | ((a0exval & 7) << 9) | (a0reg);
480 warn("lea size(An),An converted to addq #size,An");
484 return m_ea(inst, siz);
488 int m_ea030(WORD inst, WORD siz)
491 WORD flg = inst; // Save flag bits
492 inst &= ~0x3F; // Clobber flag bits in instr
494 // Install "standard" instr size bits
500 // OR-in register number
503 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
507 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
514 inst |= am1 | a1reg; // Get ea1 into instr
515 D_word(inst); // Deposit instr
517 // Generate ea0 if requested
521 ea1gen(siz); // Generate ea1
527 // We get here if we're doing 020+ addressing and an address
528 // register is used. For example, something like "tst a0". A bit of
529 // a corner case, so kludge it
531 else if (am0 == PCDISP)
532 //Another corner case (possibly!), so kludge ahoy
533 inst |= am0; // Get ea0 into instr
534 else if (am0 == IMMED)
535 inst |= am0 | a0reg; // Get ea0 into instr
536 else if (am0 == AM_CCR)
538 else if (am0 == AIND)
541 inst |= a0reg; // Get ea0 into instr
542 D_word(inst); // Deposit instr
543 ea0gen(siz); // Generate ea0
545 // Generate ea1 if requested
555 // Dx,Dy nnnnXXXnssnnnYYY If bit 0 of `inst' is set, install size bits in bits
558 int m_abcd(WORD inst, WORD siz)
567 inst |= a0reg | reg_9[a1reg];
577 int m_adda(WORD inst, WORD siz)
579 inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
581 ea0gen(siz); // Generate EA
588 // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr.
589 // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr.
591 int m_reg(WORD inst, WORD siz)
598 // Install other register (9..11)
599 inst |= reg_9[a1reg];
601 inst &= ~7; // Clear off crufty bits
602 inst |= a0reg; // Install first register
612 int m_imm(WORD inst, WORD siz)
624 int m_imm8(WORD inst, WORD siz)
637 int m_shr(WORD inst, WORD siz)
639 inst |= reg_9[a0reg] | a1reg | siz_6[siz];
649 int m_shi(WORD inst, WORD siz)
651 inst |= a1reg | siz_6[siz];
653 if (a0exattr & DEFINED)
656 return error(range_error);
658 inst |= (a0exval & 7) << 9;
663 AddFixup(FU_QUICK, sloc, a0expr);
672 // {bset, btst, bchg, bclr} -- #immed,ea -- Dn,ea
674 int m_bitop(WORD inst, WORD siz)
676 // Enforce instruction sizes
678 { // X,Dn must be .n or .l
679 if (siz & (SIZB | SIZW))
680 return error(siz_error);
682 else if (siz & (SIZW | SIZL)) // X,ea must be .n or .b
683 return error(siz_error);
685 // Construct instr and EAs
691 ea0gen(SIZB); // Immediate bit number
695 inst |= reg_9[a0reg];
706 int m_dbra(WORD inst, WORD siz)
714 if (a1exattr & DEFINED)
716 if ((a1exattr & TDB) != cursect)
717 return error(rel_error);
721 if (v + 0x8000 > 0x10000)
722 return error(range_error);
728 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
739 int m_exg(WORD inst, WORD siz)
745 if (am0 == DREG && am1 == DREG)
747 else if (am0 == AREG && am1 == AREG)
753 m = a1reg; // Get AREG into a1reg
761 inst |= m | reg_9[a0reg] | a1reg;
771 int m_link(WORD inst, WORD siz)
775 // Is this an error condition???
780 inst &= ~((3 << 9) | (1 << 6) | (1 << 4));
792 WORD extra_addressing[16]=
795 0, //0101 ([bd,An],Xn,od)
796 0x180, //0102 ([bc,An,Xn],od) (111 110 110 111)
798 0, //0104 ([bd,PC],Xn,od)
799 0, //0105 ([bc,PC,Xn],od)
814 // Handle MOVE <C_ALL> <C_ALTDATA>
815 // MOVE <C_ALL> <M_AREG>
817 // Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
819 int m_move(WORD inst, WORD size)
821 // Cast the passed in value to an int
824 // Try to optimize to MOVEQ
825 if (CHECK_OPTS(OPT_MOVEL_MOVEQ)
826 && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
827 && ((a0exattr & (TDB | DEFINED)) == DEFINED)
828 && (a0exval + 0x80 < 0x100))
830 m_moveq((WORD)0x7000, (WORD)0);
833 warn("move.l #size,dx converted to moveq");
837 if ((am0 < ABASE) && (am1 < ABASE)) //68000 modes
839 inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
847 ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
851 inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0 - ABASE];
867 // Handle MOVE <C_ALL030> <C_ALTDATA>
868 // MOVE <C_ALL030> <M_AREG>
870 int m_move30(WORD inst, WORD size)
873 // TODO: is extra_addressing necessary/correct?
874 //inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
875 inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg;
890 // move USP,An -- move An,USP
892 int m_usp(WORD inst, WORD siz)
897 inst |= a1reg; // USP, An
899 inst |= a0reg; // An, USP
910 int m_moveq(WORD inst, WORD siz)
914 // Arrange for future fixup
915 if (!(a0exattr & DEFINED))
917 AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
920 else if (a0exval + 0x100 >= 0x200)
921 return error(range_error);
923 inst |= reg_9[a1reg] | (a0exval & 0xFF);
931 // movep Dn, disp(An) -- movep disp(An), Dn
933 int m_movep(WORD inst, WORD siz)
935 // Tell ea0gen to lay off the 0(a0) optimisations on this one
943 inst |= reg_9[a0reg] | a1reg;
953 inst |= reg_9[a1reg] | a0reg;
970 int m_br(WORD inst, WORD siz)
974 if (a0exattr & DEFINED)
976 if ((a0exattr & TDB) != cursect)
978 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
979 return error(rel_error);
982 v = a0exval - (sloc + 2);
984 // Optimize branch instr. size
987 if (CHECK_OPTS(OPT_BSR_BCC_S) && (v != 0) && ((v + 0x80) < 0x100))
994 warn("Bcc.w/BSR.w converted to .s");
1001 if ((v + 0x8000) > 0x10000)
1002 return error(range_error);
1010 if (siz == SIZB || siz == SIZS)
1012 if ((v + 0x80) >= 0x100)
1013 return error(range_error);
1020 if ((v + 0x8000) >= 0x10000)
1021 return error(range_error);
1029 else if (siz == SIZN)
1032 if (siz == SIZB || siz == SIZS)
1035 AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
1043 AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
1054 int m_addq(WORD inst, WORD siz)
1056 inst |= siz_6[siz] | am1 | a1reg;
1058 if (a0exattr & DEFINED)
1060 if ((a0exval > 8) || (a0exval == 0)) // Range in 1..8
1061 return error(range_error);
1063 inst |= (a0exval & 7) << 9;
1068 AddFixup(FU_QUICK, sloc, a0expr);
1081 int m_trap(WORD inst, WORD siz)
1085 if (a0exattr & DEFINED)
1088 return error(abs_error);
1091 return error(range_error);
1097 return error(undef_error);
1104 // movem <rlist>,ea -- movem ea,<rlist>
1106 int m_movem(WORD inst, WORD siz)
1114 return error("bad size suffix");
1121 // Handle #<expr>, ea
1124 if (abs_expr(&eval) != OK)
1127 if (eval >= 0x10000L)
1128 return error(range_error);
1134 if ((*tok >= KW_D0) && (*tok <= KW_A7))
1137 if (reglist(&rmask) < 0)
1142 return error("missing comma");
1147 inst |= am0 | a0reg;
1149 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
1150 return error("invalid addressing mode");
1152 // If APREDEC, reverse register mask
1158 for(i=0x8000; i; i>>=1, w>>=1)
1159 rmask = (WORD)((rmask << 1) | w & 1);
1168 inst |= 0x0400 | am0 | a0reg;
1171 return error("missing comma");
1174 return error("missing register list");
1181 if (abs_expr(&eval) != OK)
1184 if (eval >= 0x10000)
1185 return error(range_error);
1189 else if (reglist(&rmask) < 0)
1192 if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
1193 return error("invalid addressing mode");
1205 // CLR.x An ==> SUBA.x An,An
1207 int m_clra(WORD inst, WORD siz)
1209 inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
1216 ////////////////////////////////////////
1218 // 68020/30/40 instructions
1220 ////////////////////////////////////////
1225 int m_br30(WORD inst, WORD siz)
1227 if (a0exattr & DEFINED)
1229 if ((a0exattr & TDB) != cursect)
1230 return error(rel_error);
1232 uint32_t v = a0exval - (sloc + 2);
1241 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1249 // bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
1250 // (68020, 68030, 68040)
1252 int m_bfop(WORD inst, WORD siz)
1254 if ((bfval1 > 31) || (bfval1 < 0))
1255 return error("bfxxx offset: immediate value must be between 0 and 31");
1257 // First instruction word - just the opcode and first EA
1258 // Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
1265 if (bfval2 > 31 || bfval2 < 0)
1266 return error("bfxxx width: immediate value must be between 0 and 31");
1268 // For Dw both immediate and register number are stuffed
1269 // into the same field O_o
1270 bfparam2 = (bfval2 << 0);
1275 bfparam1 = (bfval1 << 6);
1279 bfparam1 = bfval1 << 12;
1282 D_word((inst | am0 | a0reg | am1 | a1reg));
1283 ea0gen(siz); // Generate EA
1285 // Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
1287 inst = bfparam1 | bfparam2;
1293 inst |= a0reg << 12;
1302 // bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
1304 int m_bkpt(WORD inst, WORD siz)
1308 if (a0exattr & DEFINED)
1311 return error(abs_error);
1314 return error(range_error);
1320 return error(undef_error);
1329 int m_callm(WORD inst, WORD siz)
1336 if (a0exattr & DEFINED)
1339 return error(abs_error);
1342 return error(range_error);
1348 return error(undef_error);
1358 // cas (68020, 68030, 68040)
1360 int m_cas(WORD inst, WORD siz)
1366 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1367 return error(unsupport);
1382 return error("bad size suffix");
1387 if ((*tok < KW_D0) && (*tok > KW_D7))
1388 return error("CAS accepts only data registers");
1390 inst2 = (*tok++) & 7;
1393 return error("missing comma");
1396 if ((*tok < KW_D0) && (*tok > KW_D7))
1397 return error("CAS accepts only data registers");
1399 inst2 |= ((*tok++) & 7) << 6;
1402 return error("missing comma");
1405 if ((modes = amode(1)) < 0)
1409 return error("too many ea fields");
1412 return error("extra (unexpected) text found");
1414 // Reject invalud ea modes
1415 amsk = amsktab[am0];
1417 if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
1418 return error("unsupported addressing mode");
1420 inst |= am0 | a0reg;
1430 // cas2 (68020, 68030, 68040)
1432 int m_cas2(WORD inst, WORD siz)
1436 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1437 return error(unsupport);
1452 return error("bad size suffix");
1457 if ((*tok < KW_D0) && (*tok > KW_D7))
1458 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1460 inst2 = (*tok++) & 7;
1463 return error("missing colon");
1466 if ((*tok < KW_D0) && (*tok > KW_D7))
1467 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1469 inst3 = (*tok++) & 7;
1472 return error("missing comma");
1475 if ((*tok < KW_D0) && (*tok > KW_D7))
1476 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1478 inst2 |= ((*tok++) & 7) << 6;
1481 return error("missing colon");
1484 if ((*tok < KW_D0) && (*tok > KW_D7))
1485 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1487 inst3 |= ((*tok++) & 7) << 6;
1490 return error("missing comma");
1494 return error("missing (");
1495 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1496 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1497 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1498 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1500 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1503 return error("missing (");
1506 return error("missing colon");
1510 return error("missing (");
1511 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1512 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1513 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1514 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1516 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1519 return error("missing (");
1522 return error("extra (unexpected) text found");
1533 // cmp2 (68020, 68030, 68040, CPU32)
1535 int m_cmp2(WORD inst, WORD siz)
1537 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1538 return error(unsupport);
1540 switch (siz & 0x000F)
1554 WORD flg = inst; // Save flag bits
1555 inst &= ~0x3F; // Clobber flag bits in instr
1557 // Install "standard" instr size bits
1563 // OR-in register number
1565 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1567 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1573 inst |= am1 | a1reg; // Get ea1 into instr
1574 D_word(inst); // Deposit instr
1576 // Generate ea0 if requested
1580 ea1gen(siz); // Generate ea1
1585 inst |= am0 | a0reg; // Get ea0 into instr
1586 D_word(inst); // Deposit instr
1587 ea0gen(siz); // Generate ea0
1589 // Generate ea1 if requested
1594 // If we're called from chk2 then bit 11 of size will be set. This is just
1595 // a dumb mechanism to pass this, required by the extension word. (You might
1596 // have noticed the siz & 15 thing above!)
1597 inst = (a1reg << 12) | (siz & (1 << 11));
1609 // chk2 (68020, 68030, 68040, CPU32)
1611 int m_chk2(WORD inst, WORD siz)
1613 return m_cmp2(inst, siz | (1 << 11));
1618 // cpbcc(68020, 68030)
1620 int m_cpbr(WORD inst, WORD siz)
1622 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1623 return error(unsupport);
1625 if (a0exattr & DEFINED)
1627 if ((a0exattr & TDB) != cursect)
1628 return error(rel_error);
1630 uint32_t v = a0exval - (sloc + 2);
1632 // Optimize branch instr. size
1635 if ((v != 0) && ((v + 0x8000) < 0x10000))
1645 if ((v + 0x8000) >= 0x10000)
1646 return error(range_error);
1654 else if (siz == SIZN)
1661 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1669 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1678 // cpdbcc(68020, 68030)
1680 int m_cpdbr(WORD inst, WORD siz)
1685 WORD condition = inst & 0x1f; // Grab condition sneakily placed in the lower 5 bits of inst
1686 inst &= 0xffe0; // And then mask them out - you ain't seen me, roit?
1688 inst |= (1 << 9); // Bolt on FPU id
1695 if (a1exattr & DEFINED)
1697 if ((a1exattr & TDB) != cursect)
1698 return error(rel_error);
1702 if (v + 0x8000 > 0x10000)
1703 return error(range_error);
1709 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
1721 int m_divs(WORD inst, WORD siz)
1723 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1724 return error(unsupport);
1726 WORD flg = inst; // Save flag bits
1727 inst &= ~0x3F; // Clobber flag bits in instr
1729 // Install "standard" instr size bits
1735 // OR-in register number
1737 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1739 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1745 inst |= am1 | a1reg; // Get ea1 into instr
1746 D_word(inst); // Deposit instr
1748 // Generate ea0 if requested
1752 ea1gen(siz); // Generate ea1
1757 inst |= am0 | a0reg; // Get ea0 into instr
1758 D_word(inst); // Deposit instr
1759 ea0gen(siz); // Generate ea0
1761 // Generate ea1 if requested
1766 inst = a1reg + (a2reg << 12) + (1 << 11);
1776 int m_muls(WORD inst, WORD siz)
1778 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1779 return error(unsupport);
1781 WORD flg = inst; // Save flag bits
1782 inst &= ~0x3F; // Clobber flag bits in instr
1784 // Install "standard" instr size bits
1790 // OR-in register number
1792 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1794 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1800 inst |= am1 | a1reg; // Get ea1 into instr
1801 D_word(inst); // Deposit instr
1804 inst = a1reg + (a2reg << 12) + (1 << 11);
1805 inst |= mulmode; // add size bit
1808 // Generate ea0 if requested
1812 ea1gen(siz); // Generate ea1
1817 inst |= am0 | a0reg; // Get ea0 into instr
1818 D_word(inst); // Deposit instr
1820 inst = a1reg + (a2reg << 12) + (1 << 11);
1821 inst |= mulmode; // add size bit
1824 ea0gen(siz); // Generate ea0
1826 // Generate ea1 if requested
1841 int m_divu(WORD inst, WORD siz)
1843 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1844 return error(unsupport);
1846 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1848 WORD flg = inst; // Save flag bits
1849 inst &= ~0x3F; // Clobber flag bits in instr
1851 // Install "standard" instr size bits
1857 // OR-in register number
1859 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1861 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1867 inst |= am1 | a1reg; // Get ea1 into instr
1868 D_word(inst); // Deposit instr
1870 // Generate ea0 if requested
1874 ea1gen(siz); // Generate ea1
1879 inst |= am0 | a0reg; // Get ea0 into instr
1880 D_word(inst); // Deposit instr
1881 ea0gen(siz); // Generate ea0
1883 // Generate ea1 if requested
1888 inst = a1reg + (a2reg << 12);
1898 int m_mulu(WORD inst, WORD siz)
1900 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1901 return error(unsupport);
1903 WORD flg = inst; // Save flag bits
1904 inst &= ~0x3F; // Clobber flag bits in instr
1906 // Install "standard" instr size bits
1912 // OR-in register number
1914 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1916 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1922 inst |= am1 | a1reg; // Get ea1 into instr
1923 D_word(inst); // Deposit instr
1925 // Generate ea0 if requested
1929 ea1gen(siz); // Generate ea1
1934 inst |= am0 | a0reg; // Get ea0 into instr
1935 D_word(inst); // Deposit instr
1936 ea0gen(siz); // Generate ea0
1938 // Generate ea1 if requested
1943 inst = a1reg + (a2reg << 12);
1944 inst |= mulmode; // add size bit
1954 int m_divsl(WORD inst, WORD siz)
1956 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1957 return error(unsupport);
1959 WORD flg = inst; // Save flag bits
1960 inst &= ~0x3F; // Clobber flag bits in instr
1962 // Install "standard" instr size bits
1968 // OR-in register number
1970 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1972 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1978 inst |= am1 | a1reg; // Get ea1 into instr
1979 D_word(inst); // Deposit instr
1981 // Generate ea0 if requested
1985 ea1gen(siz); // Generate ea1
1990 inst |= am0 | a0reg; // Get ea0 into instr
1991 D_word(inst); // Deposit instr
1992 ea0gen(siz); // Generate ea0
1994 // Generate ea1 if requested
1999 inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
2008 int m_divul(WORD inst, WORD siz)
2010 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
2011 return error(unsupport);
2013 WORD flg = inst; // Save flag bits
2014 inst &= ~0x3F; // Clobber flag bits in instr
2016 // Install "standard" instr size bits
2022 // OR-in register number
2024 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2026 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2032 inst |= am1 | a1reg; // Get ea1 into instr
2033 D_word(inst); // Deposit instr
2035 // Generate ea0 if requested
2039 ea1gen(siz); // Generate ea1
2044 inst |= am0 | a0reg; // Get ea0 into instr
2045 D_word(inst); // Deposit instr
2046 ea0gen(siz); // Generate ea0
2048 // Generate ea1 if requested
2053 inst = a1reg + (a2reg << 12) + (1 << 10);
2061 // move16 (ax)+,(ay)+
2063 int m_move16a(WORD inst, WORD siz)
2065 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2066 return error(unsupport);
2070 inst = (1 << 15) + (a1reg << 12);
2078 // move16 with absolute address
2080 int m_move16b(WORD inst, WORD siz)
2082 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2083 return error(unsupport);
2089 if (am0 == APOSTINC)
2092 return error("Wasn't this suppose to call m_move16a???");
2095 //move16 (ax)+,(xxx).L
2100 else if (am0 == ABSL)
2104 //move16 (xxx).L,(ax)+
2110 //move16 (xxx).L,(ax)
2115 else if (am0 == AIND)
2117 //move16 (ax),(xxx).L
2130 // pack/unpack (68020/68030/68040)
2132 int m_pack(WORD inst, WORD siz)
2137 return error("bad size suffix");
2139 if (*tok >= KW_D0 && *tok <= KW_D7)
2141 // Dx,Dy,#<adjustment>
2142 inst |= (0 << 3); // R/M
2143 inst |= (*tok++ & 7);
2144 if (*tok != ',' && tok[2] != ',')
2145 return error("missing comma");
2146 if (tok[1] < KW_D0 && tok[1] > KW_D7)
2147 return error(syntax_error);
2148 inst |= ((tok[1] & 7)<<9);
2151 // Fall through for adjustment (common in both valid cases)
2153 else if (*tok == '-')
2155 // -(Ax),-(Ay),#<adjustment>
2156 inst |= (1 << 3); // R/M
2157 tok++; // eat the minus
2158 if ((*tok != '(') && (tok[2]!=')') && (tok[3]!=',') && (tok[4] != '-') && (tok[5] != '(') && (tok[7] != ')') && (tok[8] != ','))
2159 return error(syntax_error);
2160 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2161 return error(syntax_error);
2162 if (tok[5] < KW_A0 && tok[6] > KW_A7)
2163 return error(syntax_error);
2164 inst |= ((tok[1] & 7) << 0);
2165 inst |= ((tok[6] & 7) << 9);
2168 // Fall through for adjustment (common in both valid cases)
2171 return error("invalid syntax");
2174 if ((*tok != CONST) && (*tok != SYMBOL) && (*tok != '-'))
2175 return error(syntax_error);
2177 if (expr(a0expr, &a0exval, &a0exattr, &a0esym)==ERROR)
2180 if ((a0exattr & DEFINED) == 0)
2181 return error(undef_error);
2183 if (a0exval + 0x8000 > 0x10000)
2187 return error(extra_stuff);
2189 D_word((a0exval & 0xffff));
2201 int m_rtm(WORD inst, WORD siz)
2209 else if (am0 == AREG)
2211 inst |= (1 << 3) + a0reg;
2214 return error("rtm only allows data or address registers.");
2225 int m_rtd(WORD inst, WORD siz)
2229 if (a0exattr & DEFINED)
2232 return error(abs_error);
2234 if ((a0exval + 0x8000) <= 0x7FFF)
2235 return error(range_error);
2241 return error(undef_error);
2250 int m_trapcc(WORD inst, WORD siz)
2258 else if (am0 == IMMED)
2262 if (a0exval < 0x10000)
2269 return error("Immediate value too big");
2279 return error("Invalid parameter for trapcc");
2286 // cinvl/p/a (68040)
2288 int m_cinv(WORD inst, WORD siz)
2293 inst |= (0 << 6) | (a1reg);
2297 inst |= (2 << 6) | (a1reg);
2300 inst |= (1 << 6) | (a1reg);
2303 inst |= (3 << 6) | (a1reg);
2313 // cpRESTORE (68020, 68030)
2315 int m_cprest(WORD inst, WORD siz)
2317 if (activecpu & !(CPU_68020 | CPU_68030))
2318 return error(unsupport);
2320 inst |= am0 | a0reg;
2329 // movec (68010, 68020, 68030, 68040, CPU32)
2331 int m_movec(WORD inst, WORD siz)
2335 if (am0 == DREG || am0 == AREG)
2343 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
2348 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
2359 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
2364 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2374 // moves (68010, 68020, 68030, 68040, CPU32)
2376 int m_moves(WORD inst, WORD siz)
2378 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2379 return error(unsupport);
2385 else if (siz == SIZL)
2396 inst |= am1 | a1reg;
2398 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2401 else if (am0 == AREG)
2403 inst |= am1 | a1reg;
2405 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2412 inst |= am0 | a0reg;
2414 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2419 inst |= am0 | a0reg;
2421 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2433 int m_pbcc(WORD inst, WORD siz)
2436 return error("Not implemented yet.");
2441 // pflusha (68030, 68040)
2443 int m_pflusha(WORD inst, WORD siz)
2445 if (activecpu == CPU_68030)
2448 inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
2452 else if (activecpu == CPU_68040)
2454 inst = B16(11110101, 00011000);
2459 return error(unsupport);
2467 // pflush (68030, 68040, 68060)
2469 int m_pflush(WORD inst, WORD siz)
2471 if (activecpu == CPU_68030)
2474 // PFLUSH FC, MASK, < ea >
2480 if (*tok != CONST && *tok != SYMBOL)
2481 return error("function code should be an expression");
2482 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2484 if ((a0exattr & DEFINED) == 0)
2485 return error("function code immediate should be defined");
2486 if (a0exval > 7 && a0exval < 0)
2487 return error("function code out of range (0-7)");
2498 fc = (1 << 4) | (*tok++ & 7);
2509 return error(syntax_error);
2513 return error("comma exptected");
2516 return error("mask should be an immediate value");
2517 if (*tok != CONST && *tok != SYMBOL)
2518 return error("mask is supposed to be immediate");
2519 if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
2521 if ((a0exattr & DEFINED) == 0)
2522 return error("mask immediate value should be defined");
2523 if (a0exval > 7 && a0exval < 0)
2524 return error("function code out of range (0-7)");
2525 mask = a0exval << 5;
2531 inst = (1 << 13) | fc | mask | (4 << 10);
2535 else if (*tok == ',')
2537 // PFLUSH FC, MASK, < ea >
2539 if (amode(0) == ERROR)
2542 return error(extra_stuff);
2543 if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE)
2545 inst |= am0 | a0reg;
2547 inst = (1 << 13) | fc | mask | (6 << 10);
2553 return error("unsupported addressing mode");
2557 return error(syntax_error);
2562 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2566 if (*tok != '(' && tok[2] != ')')
2567 return error(syntax_error);
2568 if (tok[1] < KW_A0 && tok[1] > KW_A7)
2569 return error("expected (An)");
2570 if ((inst & 7) == 7)
2571 // With pflushn/pflush there's no easy way to
2572 // distinguish between the two in 68040 mode.
2573 // Ideally the opcode bitfields would have been
2574 // hardcoded in 68ktab but there is aliasing
2575 // between 68030 and 68040 opcode. So we just
2576 // set the 3 lower bits to 1 in pflushn inside
2577 // 68ktab and detect it here.
2578 inst = (inst & 0xff8) | 8;
2579 inst |= (tok[1] & 7) | (5 << 8);
2581 return error(extra_stuff);
2585 return error(unsupport);
2594 int m_pflushr(WORD inst, WORD siz)
2598 WORD flg = inst; // Save flag bits
2599 inst &= ~0x3F; // Clobber flag bits in instr
2601 // Install "standard" instr size bits
2607 // OR-in register number
2609 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2611 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2617 inst |= am1 | a1reg; // Get ea1 into instr
2618 D_word(inst); // Deposit instr
2620 // Generate ea0 if requested
2624 ea1gen(siz); // Generate ea1
2629 inst |= am0 | a0reg; // Get ea0 into instr
2630 D_word(inst); // Deposit instr
2631 ea0gen(siz); // Generate ea0
2633 // Generate ea1 if requested
2638 D_word(B16(10100000, 00000000));
2644 // ploadr, ploadw (68030)
2646 int m_pload(WORD inst, WORD siz, WORD extension)
2648 // TODO: 68551 support is not added yet.
2649 // None of the ST series of computers had
2650 // a 68020 + 68551 socket and since this is
2651 // an Atari targetted assembler....
2661 if (a0reg == KW_SFC - KW_SFC)
2665 else if (a0reg == KW_DFC - KW_SFC)
2670 return error("illegal control register specified");
2673 inst = (1 << 3) | a0reg;
2676 if ((a0exattr & DEFINED) == 0)
2677 return error("constant value must be defined");
2678 inst = (2 << 3) | a0exval;
2682 inst |= extension | (1 << 13);
2690 int m_ploadr(WORD inst, WORD siz)
2692 return m_pload(inst, siz, 1 << 9);
2695 int m_ploadw(WORD inst, WORD siz)
2697 return m_pload(inst, siz, 0 << 9);
2701 // pmove (68030/68551)
2703 int m_pmove(WORD inst, WORD siz)
2707 // TODO: 68551 support is not added yet.
2708 // None of the ST series of computers had
2709 // a 68020 + 68551 socket and since this is
2710 // an Atari targetted assembler....
2711 // (same for 68EC030)
2714 inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2715 inst &= ~(1 << 8); //And mask it out
2722 else if (am1 == CREG)
2728 return error("pmove sez: Wut?");
2730 // The instruction is a quad-word (8 byte) operation
2731 // for the CPU root pointer and the supervisor root pointer.
2732 // It is a long - word operation for the translation control register
2733 // and the transparent translation registers(TT0 and TT1).
2734 // It is a word operation for the MMU status register.
2736 if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
2737 && ((siz != SIZD) && (siz != SIZN)))
2738 return error(siz_error);
2740 if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
2741 && ((siz != SIZL) && (siz != SIZN)))
2742 return error(siz_error);
2744 if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
2745 return error(siz_error);
2750 inst |= am1 | a1reg;
2753 else if (am1 == CREG)
2755 inst |= am0 | a0reg;
2759 switch (reg + KW_SFC)
2762 inst2 |= (0 << 10) + (1 << 14); break;
2764 inst2 |= (2 << 10) + (1 << 14); break;
2766 inst2 |= (3 << 10) + (1 << 14); break;
2768 inst2 |= (2 << 10) + (0 << 13); break;
2770 inst2 |= (3 << 10) + (0 << 13); break;
2773 inst2 |= (1 << 9) + (3 << 13);
2775 inst2 |= (0 << 9) + (3 << 13);
2778 return error("unsupported register");
2788 else if (am1 == CREG)
2800 int m_pmovefd(WORD inst, WORD siz)
2804 return m_pmove(inst | (1 << 8), siz);
2811 #define gen_ptrapcc(name,opcode) \
2812 int m_##name(WORD inst, WORD siz) \
2818 D_word(B8(opcode)); \
2825 D_word(B8(opcode)); \
2830 int m_##name##n(WORD inst, WORD siz) \
2834 D_word(B8(opcode)); \
2838 gen_ptrapcc(ptrapbs,00000000)
2839 gen_ptrapcc(ptrapbc,00000001)
2840 gen_ptrapcc(ptrapls,00000010)
2841 gen_ptrapcc(ptraplc,00000011)
2842 gen_ptrapcc(ptrapss,00000100)
2843 gen_ptrapcc(ptrapsc,00000101)
2844 gen_ptrapcc(ptrapas,00000110)
2845 gen_ptrapcc(ptrapac,00000111)
2846 gen_ptrapcc(ptrapws,00001000)
2847 gen_ptrapcc(ptrapwc,00001001)
2848 gen_ptrapcc(ptrapis,00001010)
2849 gen_ptrapcc(ptrapic,00001011)
2850 gen_ptrapcc(ptrapgc,00001100)
2851 gen_ptrapcc(ptrapgs,00001101)
2852 gen_ptrapcc(ptrapcs,00001110)
2853 gen_ptrapcc(ptrapcc,00001111)
2855 //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; }
2856 //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; }
2857 //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; }
2858 //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; }
2859 //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; }
2860 //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; }
2861 //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; }
2862 //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; }
2863 //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; }
2864 //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; }
2865 //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; }
2866 //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; }
2867 //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; }
2868 //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; }
2869 //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; }
2870 //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; }
2871 //int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2872 //int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2873 //int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2874 //int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2875 //int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2876 //int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2877 //int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2878 //int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2879 //int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2880 //int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2881 //int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2882 //int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2883 //int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2884 //int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2885 //int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2886 //int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2890 // ptestr, ptestw (68030)
2892 int m_ptest(WORD inst, WORD siz)
2896 if (activecpu == CPU_68030)
2897 return error("Not implemented yet.");
2898 else if (activecpu == CPU_68040)
2899 return error("Not implemented yet.");
2905 #define FPU_NOWARN 0
2906 #define FPU_P_EMUL 1
2907 #define FPU_P2_EMU 2
2912 // Generate a FPU opcode
2914 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2916 if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
2918 inst |= (1 << 9); // Bolt on FPU id
2925 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2929 case SIZB: inst |= (6 << 10); break;
2930 case SIZW: inst |= (4 << 10); break;
2931 case SIZL: inst |= (0 << 10); break;
2933 case SIZS: inst |= (1 << 10); break;
2934 case SIZD: inst |= (5 << 10); break;
2935 case SIZX: inst |= (2 << 10); break;
2940 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2944 return error("Something bad happened, possibly, in gen_fpu.");
2948 inst |= (a1reg << 7);
2955 inst |= (1 << 9); //Bolt on FPU id
2959 inst |= (a1reg << 7);
2964 if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
2965 warn("Instruction is emulated in 68040");
2972 // fabs, fsabs, fdabs (6888X, 68040)
2974 int m_fabs(WORD inst, WORD siz)
2976 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2980 int m_fsabs(WORD inst, WORD siz)
2982 if (activefpu == FPU_68040)
2983 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2985 return error("Unsupported in current FPU");
2989 int m_fdabs(WORD inst, WORD siz)
2991 if (activefpu == FPU_68040)
2992 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2994 return error("Unsupported in current FPU");
2999 // facos (6888X, 68040FPSP)
3001 int m_facos(WORD inst, WORD siz)
3003 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
3008 // fadd (6888X, 68040FPSP)
3010 int m_fadd(WORD inst, WORD siz)
3012 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
3016 int m_fsadd(WORD inst, WORD siz)
3018 if (activefpu == FPU_68040)
3019 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
3021 return error("Unsupported in current FPU");
3025 int m_fdadd(WORD inst, WORD siz)
3027 if (activefpu == FPU_68040)
3028 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
3030 return error("Unsupported in current FPU");
3035 // fasin (6888X, 68040FPSP)f
3037 int m_fasin(WORD inst, WORD siz)
3039 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
3044 // fatan (6888X, 68040FPSP)
3046 int m_fatan(WORD inst, WORD siz)
3048 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
3053 // fatanh (6888X, 68040FPSP)
3055 int m_fatanh(WORD inst, WORD siz)
3057 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
3062 // fcmp (6888X, 68040)
3064 int m_fcmp(WORD inst, WORD siz)
3066 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
3071 // fcos (6888X, 68040FPSP)
3073 int m_fcos(WORD inst, WORD siz)
3075 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
3080 // fcosh (6888X, 68040FPSP)
3082 int m_fcosh(WORD inst, WORD siz)
3084 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
3089 // fdbcc (6888X, 68040)
3091 int m_fdbcc(WORD inst, WORD siz)
3093 WORD opcode = inst & 0x3F; //Grab conditional bitfield
3103 if (a1exattr & DEFINED)
3105 if ((a1exattr & TDB) != cursect)
3106 return error(rel_error);
3108 uint32_t v = a1exval - sloc;
3110 if ((v + 0x8000) > 0x10000)
3111 return error(range_error);
3117 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
3126 // fdiv (6888X, 68040)
3128 int m_fdiv(WORD inst, WORD siz)
3130 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
3134 int m_fsdiv(WORD inst, WORD siz)
3136 if (activefpu == FPU_68040)
3137 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
3139 return error("Unsupported in current FPU");
3143 int m_fddiv(WORD inst, WORD siz)
3145 if (activefpu == FPU_68040)
3146 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3148 return error("Unsupported in current FPU");
3153 // fetox (6888X, 68040FPSP)
3155 int m_fetox(WORD inst, WORD siz)
3157 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
3162 // fetoxm1 (6888X, 68040FPSP)
3164 int m_fetoxm1(WORD inst, WORD siz)
3166 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
3171 // fgetexp (6888X, 68040FPSP)
3173 int m_fgetexp(WORD inst, WORD siz)
3175 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
3180 // fgetman (6888X, 68040FPSP)
3182 int m_fgetman(WORD inst, WORD siz)
3184 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
3189 // fint (6888X, 68040FPSP)
3191 int m_fint(WORD inst, WORD siz)
3194 // special case - fint fpx = fint fpx,fpx
3197 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
3202 // fintrz (6888X, 68040FPSP)
3204 int m_fintrz(WORD inst, WORD siz)
3207 // special case - fintrz fpx = fintrz fpx,fpx
3210 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
3215 // flog10 (6888X, 68040FPSP)
3217 int m_flog10(WORD inst, WORD siz)
3219 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
3224 // flog2 (6888X, 68040FPSP)
3226 int m_flog2(WORD inst, WORD siz)
3228 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
3233 // flogn (6888X, 68040FPSP)
3235 int m_flogn(WORD inst, WORD siz)
3237 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
3242 // flognp1 (6888X, 68040FPSP)
3244 int m_flognp1(WORD inst, WORD siz)
3246 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
3251 // fmod (6888X, 68040FPSP)
3253 int m_fmod(WORD inst, WORD siz)
3255 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
3260 // fmove (6888X, 68040)
3262 int m_fmove(WORD inst, WORD siz)
3266 if ((am0 == FREG) && (am1 < AM_USP))
3270 inst |= am1 | a1reg;
3279 case SIZB: inst |= (6 << 10); break;
3280 case SIZW: inst |= (4 << 10); break;
3281 case SIZL: inst |= (0 << 10); break;
3283 case SIZS: inst |= (1 << 10); break;
3284 case SIZD: inst |= (5 << 10); break;
3285 case SIZX: inst |= (2 << 10); break;
3286 case SIZP: inst |= (3 << 10);
3287 // In P size we have 2 cases: {#k} where k is immediate
3288 // and {Dn} where Dn=Data register
3294 inst |= bfval1 << 4;
3299 if (bfval1>63 && bfval1<-64)
3300 return error("K-factor must be between -64 and 63");
3301 inst |= bfval1 & 127;
3306 return error("Something bad happened, possibly.");
3311 // Destination specifier
3312 inst |= (a0reg << 7);
3320 else if ((am0 < AM_USP) && (am1 == FREG))
3325 inst |= am0 | a0reg;
3334 case SIZB: inst |= (6 << 10); break;
3335 case SIZW: inst |= (4 << 10); break;
3336 case SIZL: inst |= (0 << 10); break;
3338 case SIZS: inst |= (1 << 10); break;
3339 case SIZD: inst |= (5 << 10); break;
3340 case SIZX: inst |= (2 << 10); break;
3341 case SIZP: inst |= (3 << 10); break;
3343 return error("Something bad happened, possibly.");
3347 // Destination specifier
3348 inst |= (a1reg << 7);
3356 else if ((am0 == FREG) && (am1 == FREG))
3358 // register-to-register
3359 // Essentially ea to register with R/0=0
3369 return error("Invalid size");
3372 inst |= (a0reg << 10);
3374 // Destination register
3375 inst |= (a1reg << 7);
3385 // fmove (6888X, 68040)
3387 int m_fmovescr(WORD inst, WORD siz)
3389 // Move Floating-Point System Control Register (FPCR)
3393 if ((am0 == FPSCR) && (am1 < AM_USP))
3395 inst |= am1 | a1reg;
3397 inst = (1 << 13) + (1 << 15);
3403 else if ((am1 == FPSCR) && (am0 < AM_USP))
3405 inst |= am0 | a0reg;
3407 inst = (0 << 13) + (1 << 15);
3414 return error("m_fmovescr says: wut?");
3418 // fsmove/fdmove (68040)
3420 int m_fsmove(WORD inst, WORD siz)
3422 return error("Not implemented yet.");
3425 if (activefpu == FPU_68040)
3426 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3428 return error("Unsupported in current FPU");
3433 int m_fdmove(WORD inst, WORD siz)
3435 return error("Not implemented yet.");
3438 if (activefpu == FPU_68040)
3439 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3441 return error("Unsupported in current FPU");
3447 // fmovecr (6888X, 68040FPSP)
3449 int m_fmovecr(WORD inst, WORD siz)
3457 if (activefpu == FPU_68040)
3458 warn("Instruction is emulated in 68040");
3465 // fmovem (6888X, 68040)
3467 int m_fmovem(WORD inst, WORD siz)
3472 if (siz == SIZX || siz==SIZN)
3474 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3476 //fmovem.x <rlist>,ea
3477 if (fpu_reglist_left(®mask) < 0)
3481 return error("missing comma");
3486 inst |= am0 | a0reg;
3488 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3489 return error("invalid addressing mode");
3492 inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
3497 else if ((*tok >= KW_D0) && (*tok <= KW_D7))
3500 datareg = (*tok++ & 7) << 10;
3503 return error("missing comma");
3508 inst |= am0 | a0reg;
3510 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3511 return error("invalid addressing mode");
3514 inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
3525 inst |= am0 | a0reg;
3528 return error("missing comma");
3530 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3532 //fmovem.x ea,<rlist>
3533 if (fpu_reglist_right(®mask) < 0)
3537 inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
3545 datareg = (*tok++ & 7) << 10;
3547 inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
3554 else if (siz == SIZL)
3556 if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
3558 //fmovem.l <rlist>,ea
3559 regmask = (1 << 15) | (1 << 13);
3561 if (*tok == KW_FPCR)
3563 regmask |= (1 << 12);
3568 if (*tok == KW_FPSR)
3570 regmask |= (1 << 11);
3575 if (*tok == KW_FPIAR)
3577 regmask |= (1 << 10);
3582 if ((*tok == '/') || (*tok == '-'))
3589 return error("missing comma");
3594 inst |= am0 | a0reg;
3601 //fmovem.l ea,<rlist>
3605 inst |= am0 | a0reg;
3608 return error("missing comma");
3610 regmask = (1 << 15) | (0 << 13);
3613 if (*tok == KW_FPCR)
3615 regmask |= (1 << 12);
3620 if (*tok == KW_FPSR)
3622 regmask |= (1 << 11);
3627 if (*tok == KW_FPIAR)
3629 regmask |= (1 << 10);
3634 if ((*tok == '/') || (*tok == '-'))
3641 return error("extra (unexpected) text found");
3643 inst |= am0 | a0reg;
3650 return error("bad size suffix");
3657 // fmul (6888X, 68040)
3659 int m_fmul(WORD inst, WORD siz)
3661 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
3665 int m_fsmul(WORD inst, WORD siz)
3667 if (activefpu == FPU_68040)
3668 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
3670 return error("Unsupported in current FPU");
3674 int m_fdmul(WORD inst, WORD siz)
3676 if (activefpu == FPU_68040)
3677 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
3679 return error("Unsupported in current FPU");
3684 // fneg (6888X, 68040)
3686 int m_fneg(WORD inst, WORD siz)
3688 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
3692 int m_fsneg(WORD inst, WORD siz)
3694 if (activefpu == FPU_68040)
3695 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
3697 return error("Unsupported in current FPU");
3701 int m_fdneg(WORD inst, WORD siz)
3703 if (activefpu == FPU_68040)
3704 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
3706 return error("Unsupported in current FPU");
3711 // fnop (6888X, 68040)
3713 int m_fnop(WORD inst, WORD siz)
3715 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3720 // frem (6888X, 68040FPSP)
3722 int m_frem(WORD inst, WORD siz)
3724 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3729 // fscale (6888X, 68040FPSP)
3731 int m_fscale(WORD inst, WORD siz)
3733 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3738 // FScc (6888X, 68040)
3740 //int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3741 //int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3742 //int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3743 //int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3744 //int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3745 //int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3746 //int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3747 //int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3748 //int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3749 //int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3750 //int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3751 //int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3752 //int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3753 //int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3754 //int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3755 //int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3756 //int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3757 //int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3758 //int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3759 //int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3760 //int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3761 //int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3762 //int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3763 //int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3764 //int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3765 //int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3766 //int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3767 //int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3768 //int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3769 //int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3770 //int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3771 //int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3773 #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;}
3774 gen_FScc(fseq , 00000001);
3775 gen_FScc(fsne , 00001110);
3776 gen_FScc(fsgt , 00010010);
3777 gen_FScc(fsngt , 00011101);
3778 gen_FScc(fsge , 00010011);
3779 gen_FScc(fsnge , 00011100);
3780 gen_FScc(fslt , 00010100);
3781 gen_FScc(fsnlt , 00011011);
3782 gen_FScc(fsle , 00010101);
3783 gen_FScc(fsnle , 00011010);
3784 gen_FScc(fsgl , 00010110);
3785 gen_FScc(fsngl , 00011001);
3786 gen_FScc(fsgle , 00010111);
3787 gen_FScc(fsngle, 00011000);
3788 gen_FScc(fsogt , 00000010);
3789 gen_FScc(fsule , 00001101);
3790 gen_FScc(fsoge , 00000011);
3791 gen_FScc(fsult , 00001100);
3792 gen_FScc(fsolt , 00000100);
3793 gen_FScc(fsuge , 00001011);
3794 gen_FScc(fsole , 00000101);
3795 gen_FScc(fsugt , 00001010);
3796 gen_FScc(fsogl , 00000110);
3797 gen_FScc(fsueq , 00001001);
3798 gen_FScc(fsor , 00000111);
3799 gen_FScc(fsun , 00001000);
3800 gen_FScc(fsf , 00000000);
3801 gen_FScc(fst , 00001111);
3802 gen_FScc(fssf , 00010000);
3803 gen_FScc(fsst , 00011111);
3804 gen_FScc(fsseq , 00010001);
3805 gen_FScc(fssne , 00011110);
3808 // FTRAPcc (6888X, 68040)
3810 //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;}
3811 //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;}
3812 //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;}
3813 //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;}
3814 //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;}
3815 //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;}
3816 //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;}
3817 //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;}
3818 //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;}
3819 //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;}
3820 //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;}
3821 //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;}
3822 //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;}
3823 //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;}
3824 //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;}
3825 //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;}
3826 //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;}
3827 //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;}
3828 //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;}
3829 //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;}
3830 //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;}
3831 //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;}
3832 //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;}
3833 //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;}
3834 //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;}
3835 //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;}
3836 //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;}
3837 //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;}
3838 //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;}
3839 //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;}
3840 //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;}
3841 //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;}
3843 //int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3844 //int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3845 //int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3846 //int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3847 //int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3848 //int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3849 //int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3850 //int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3851 //int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3852 //int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3853 //int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3854 //int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3855 //int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3856 //int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3857 //int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3858 //int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3859 //int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3860 //int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3861 //int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3862 //int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3863 //int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3864 //int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3865 //int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3866 //int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3867 //int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3868 //int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3869 //int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3870 //int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3871 //int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3872 //int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3873 //int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3874 //int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3876 #define gen_FTRAPcc(name,opcode) \
3877 int m_##name (WORD inst, WORD siz) \
3882 D_word(B8(opcode)); \
3889 D_word(B8(opcode)); \
3894 int m_##name##n (WORD inst, WORD siz) \
3897 D_word(B8(opcode)); \
3901 gen_FTRAPcc(ftrapeq ,00000001)
3902 gen_FTRAPcc(ftrapne ,00001110)
3903 gen_FTRAPcc(ftrapgt ,00010010)
3904 gen_FTRAPcc(ftrapngt ,00011101)
3905 gen_FTRAPcc(ftrapge ,00010011)
3906 gen_FTRAPcc(ftrapnge ,00011100)
3907 gen_FTRAPcc(ftraplt ,00010100)
3908 gen_FTRAPcc(ftrapnlt ,00011011)
3909 gen_FTRAPcc(ftraple ,00010101)
3910 gen_FTRAPcc(ftrapnle ,00011010)
3911 gen_FTRAPcc(ftrapgl ,00010110)
3912 gen_FTRAPcc(ftrapngl ,00011001)
3913 gen_FTRAPcc(ftrapgle ,00010111)
3914 gen_FTRAPcc(ftrapngle ,00011000)
3915 gen_FTRAPcc(ftrapogt ,00000010)
3916 gen_FTRAPcc(ftrapule ,00001101)
3917 gen_FTRAPcc(ftrapoge ,00000011)
3918 gen_FTRAPcc(ftrapult ,00001100)
3919 gen_FTRAPcc(ftrapolt ,00000100)
3920 gen_FTRAPcc(ftrapuge ,00001011)
3921 gen_FTRAPcc(ftrapole ,00000101)
3922 gen_FTRAPcc(ftrapugt ,00001010)
3923 gen_FTRAPcc(ftrapogl ,00000110)
3924 gen_FTRAPcc(ftrapueq ,00001001)
3925 gen_FTRAPcc(ftrapor ,00000111)
3926 gen_FTRAPcc(ftrapun ,00001000)
3927 gen_FTRAPcc(ftrapf ,00000000)
3928 gen_FTRAPcc(ftrapt ,00001111)
3929 gen_FTRAPcc(ftrapsf ,00010000)
3930 gen_FTRAPcc(ftrapst ,00011111)
3931 gen_FTRAPcc(ftrapseq ,00010001)
3932 gen_FTRAPcc(ftrapsne ,00011110)
3935 // fsgldiv (6888X, 68040)
3937 int m_fsgldiv(WORD inst, WORD siz)
3939 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3944 // fsglmul (6888X, 68040)
3946 int m_fsglmul(WORD inst, WORD siz)
3948 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3953 // fsin (6888X, 68040FPSP)
3955 int m_fsin(WORD inst, WORD siz)
3957 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3962 // fsincos (6888X, 68040FPSP)
3964 int m_fsincos(WORD inst, WORD siz)
3966 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
3977 // fsin (6888X, 68040FPSP)
3979 int m_fsinh(WORD inst, WORD siz)
3981 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3986 // fsqrt (6888X, 68040)
3988 int m_fsqrt(WORD inst, WORD siz)
3990 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3994 int m_fsfsqrt(WORD inst, WORD siz)
3996 if (activefpu == FPU_68040)
3997 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
3999 return error("Unsupported in current FPU");
4003 int m_fdfsqrt(WORD inst, WORD siz)
4005 if (activefpu == FPU_68040)
4006 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
4008 return error("Unsupported in current FPU");
4013 // fsub (6888X, 68040)
4015 int m_fsub(WORD inst, WORD siz)
4017 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
4021 int m_fsfsub(WORD inst, WORD siz)
4023 if (activefpu == FPU_68040)
4024 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
4026 return error("Unsupported in current FPU");
4030 int m_fdsub(WORD inst, WORD siz)
4032 if (activefpu == FPU_68040)
4033 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
4035 return error("Unsupported in current FPU");
4040 // ftan (6888X, 68040FPSP)
4042 int m_ftan(WORD inst, WORD siz)
4044 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
4049 // ftanh (6888X, 68040FPSP)
4051 int m_ftanh(WORD inst, WORD siz)
4053 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
4058 // ftentox (6888X, 68040FPSP)
4060 int m_ftentox(WORD inst, WORD siz)
4062 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
4067 // ftst (6888X, 68040)
4069 int m_ftst(WORD inst, WORD siz)
4071 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
4076 // ftwotox (6888X, 68040FPSP)
4078 int m_ftwotox(WORD inst, WORD siz)
4080 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);