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);
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);
125 int m_fabs(WORD inst, WORD siz);
126 int m_facos(WORD inst, WORD siz);
127 int m_fadd(WORD inst, WORD siz);
128 int m_fasin(WORD inst, WORD siz);
129 int m_fatan(WORD inst, WORD siz);
130 int m_fatanh(WORD inst, WORD siz);
131 int m_fcmp(WORD inst, WORD siz);
132 int m_fcos(WORD inst, WORD siz);
133 int m_fcosh(WORD inst, WORD siz);
134 int m_fdabs(WORD inst, WORD siz);
135 int m_fdadd(WORD inst, WORD siz);
136 int m_fdbcc(WORD inst, WORD siz);
137 int m_fddiv(WORD inst, WORD siz);
138 int m_fdfsqrt(WORD inst, WORD siz);
139 int m_fdiv(WORD inst, WORD siz);
140 int m_fdmove(WORD inst, WORD siz);
141 int m_fdmul(WORD inst, WORD siz);
142 int m_fdneg(WORD inst, WORD siz);
143 int m_fdsub(WORD inst, WORD siz);
144 int m_fetox(WORD inst, WORD siz);
145 int m_fetoxm1(WORD inst, WORD siz);
146 int m_fgetexp(WORD inst, WORD siz);
147 int m_fgetman(WORD inst, WORD siz);
148 int m_fint(WORD inst, WORD siz);
149 int m_fintrz(WORD inst, WORD siz);
150 int m_flog10(WORD inst, WORD siz);
151 int m_flog2(WORD inst, WORD siz);
152 int m_flogn(WORD inst, WORD siz);
153 int m_flognp1(WORD inst, WORD siz);
154 int m_fmod(WORD inst, WORD siz);
155 int m_fmove(WORD inst, WORD siz);
156 int m_fmovescr(WORD inst, WORD siz);
157 int m_fmovecr(WORD inst, WORD siz);
158 int m_fmovem(WORD inst, WORD siz);
159 int m_fmul(WORD inst, WORD siz);
160 int m_fneg(WORD inst, WORD siz);
161 int m_fnop(WORD inst, WORD siz);
162 int m_frem(WORD inst, WORD siz);
163 int m_fsabs(WORD inst, WORD siz);
164 int m_fsadd(WORD inst, WORD siz);
165 int m_fseq(WORD inst, WORD siz);
166 int m_fsne(WORD inst, WORD siz);
167 int m_fsgt(WORD inst, WORD siz);
168 int m_fsngt(WORD inst, WORD siz);
169 int m_fsge(WORD inst, WORD siz);
170 int m_fsnge(WORD inst, WORD siz);
171 int m_fslt(WORD inst, WORD siz);
172 int m_fsnlt(WORD inst, WORD siz);
173 int m_fsle(WORD inst, WORD siz);
174 int m_fsnle(WORD inst, WORD siz);
175 int m_fsgl(WORD inst, WORD siz);
176 int m_fsngl(WORD inst, WORD siz);
177 int m_fsgle(WORD inst, WORD siz);
178 int m_fsngle(WORD inst, WORD siz);
179 int m_fsogt(WORD inst, WORD siz);
180 int m_fsule(WORD inst, WORD siz);
181 int m_fsoge(WORD inst, WORD siz);
182 int m_fsult(WORD inst, WORD siz);
183 int m_fsolt(WORD inst, WORD siz);
184 int m_fsuge(WORD inst, WORD siz);
185 int m_fsole(WORD inst, WORD siz);
186 int m_fsugt(WORD inst, WORD siz);
187 int m_fsogl(WORD inst, WORD siz);
188 int m_fsueq(WORD inst, WORD siz);
189 int m_fsor(WORD inst, WORD siz);
190 int m_fsun(WORD inst, WORD siz);
191 int m_fsf(WORD inst, WORD siz);
192 int m_fst(WORD inst, WORD siz);
193 int m_fssf(WORD inst, WORD siz);
194 int m_fsst(WORD inst, WORD siz);
195 int m_fsseq(WORD inst, WORD siz);
196 int m_fssne(WORD inst, WORD siz);
197 int m_fscale(WORD inst, WORD siz);
198 int m_fsdiv(WORD inst, WORD siz);
199 int m_fsfsqrt(WORD inst, WORD siz);
200 int m_fsfsub(WORD inst, WORD siz);
201 int m_fsgldiv(WORD inst, WORD siz);
202 int m_fsglmul(WORD inst, WORD siz);
203 int m_fsin(WORD inst, WORD siz);
204 int m_fsincos(WORD inst, WORD siz);
205 int m_fsinh(WORD inst, WORD siz);
206 int m_fsmove(WORD inst, WORD siz);
207 int m_fsmul(WORD inst, WORD siz);
208 int m_fsneg(WORD inst, WORD siz);
209 int m_fsqrt(WORD inst, WORD siz);
210 int m_fsub(WORD inst, WORD siz);
211 int m_ftan(WORD inst, WORD siz);
212 int m_ftanh(WORD inst, WORD siz);
213 int m_ftentox(WORD inst, WORD siz);
214 int m_ftst(WORD inst, WORD siz);
215 int m_ftwotox(WORD inst, WORD siz);
216 int m_ftrapeq(WORD inst, WORD siz);
217 int m_ftrapne(WORD inst, WORD siz);
218 int m_ftrapgt(WORD inst, WORD siz);
219 int m_ftrapngt(WORD inst, WORD siz);
220 int m_ftrapge(WORD inst, WORD siz);
221 int m_ftrapnge(WORD inst, WORD siz);
222 int m_ftraplt(WORD inst, WORD siz);
223 int m_ftrapnlt(WORD inst, WORD siz);
224 int m_ftraple(WORD inst, WORD siz);
225 int m_ftrapnle(WORD inst, WORD siz);
226 int m_ftrapgl(WORD inst, WORD siz);
227 int m_ftrapngl(WORD inst, WORD siz);
228 int m_ftrapgle(WORD inst, WORD siz);
229 int m_ftrapngle(WORD inst, WORD siz);
230 int m_ftrapogt(WORD inst, WORD siz);
231 int m_ftrapule(WORD inst, WORD siz);
232 int m_ftrapoge(WORD inst, WORD siz);
233 int m_ftrapult(WORD inst, WORD siz);
234 int m_ftrapolt(WORD inst, WORD siz);
235 int m_ftrapuge(WORD inst, WORD siz);
236 int m_ftrapole(WORD inst, WORD siz);
237 int m_ftrapugt(WORD inst, WORD siz);
238 int m_ftrapogl(WORD inst, WORD siz);
239 int m_ftrapueq(WORD inst, WORD siz);
240 int m_ftrapor(WORD inst, WORD siz);
241 int m_ftrapun(WORD inst, WORD siz);
242 int m_ftrapf(WORD inst, WORD siz);
243 int m_ftrapt(WORD inst, WORD siz);
244 int m_ftrapsf(WORD inst, WORD siz);
245 int m_ftrapst(WORD inst, WORD siz);
246 int m_ftrapseq(WORD inst, WORD siz);
247 int m_ftrapsne(WORD inst, WORD siz);
248 int m_ftrapeqn(WORD inst, WORD siz);
249 int m_ftrapnen(WORD inst, WORD siz);
250 int m_ftrapgtn(WORD inst, WORD siz);
251 int m_ftrapngtn(WORD inst, WORD siz);
252 int m_ftrapgen(WORD inst, WORD siz);
253 int m_ftrapngen(WORD inst, WORD siz);
254 int m_ftrapltn(WORD inst, WORD siz);
255 int m_ftrapnltn(WORD inst, WORD siz);
256 int m_ftraplen(WORD inst, WORD siz);
257 int m_ftrapnlen(WORD inst, WORD siz);
258 int m_ftrapgln(WORD inst, WORD siz);
259 int m_ftrapngln(WORD inst, WORD siz);
260 int m_ftrapglen(WORD inst, WORD siz);
261 int m_ftrapnglen(WORD inst, WORD siz);
262 int m_ftrapogtn(WORD inst, WORD siz);
263 int m_ftrapulen(WORD inst, WORD siz);
264 int m_ftrapogen(WORD inst, WORD siz);
265 int m_ftrapultn(WORD inst, WORD siz);
266 int m_ftrapoltn(WORD inst, WORD siz);
267 int m_ftrapugen(WORD inst, WORD siz);
268 int m_ftrapolen(WORD inst, WORD siz);
269 int m_ftrapugtn(WORD inst, WORD siz);
270 int m_ftrapogln(WORD inst, WORD siz);
271 int m_ftrapueqn(WORD inst, WORD siz);
272 int m_ftraporn(WORD inst, WORD siz);
273 int m_ftrapunn(WORD inst, WORD siz);
274 int m_ftrapfn(WORD inst, WORD siz);
275 int m_ftraptn(WORD inst, WORD siz);
276 int m_ftrapsfn(WORD inst, WORD siz);
277 int m_ftrapstn(WORD inst, WORD siz);
278 int m_ftrapseqn(WORD inst, WORD siz);
279 int m_ftrapsnen(WORD inst, WORD siz);
281 // Common error messages
282 char range_error[] = "expression out of range";
283 char abs_error[] = "illegal absolute expression";
284 char seg_error[] = "bad (section) expression";
285 char rel_error[] = "illegal relative address";
286 char siz_error[] = "bad size specified";
287 char undef_error[] = "undefined expression";
288 char fwd_error[] = "forward or undefined expression";
289 char unsupport[] = "unsupported for selected CPU";
291 // Include code tables
293 { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0
295 { 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry
298 // Register number << 9
300 0, 1 << 9, 2 << 9, 3 << 9, 4 << 9, 5 << 9, 6 << 9, 7 << 9
303 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
307 1<<6, (WORD)-1, // SIZW, n/a
308 2<<6, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
312 // Byte/word/long size for MOVE instrs
316 0x3000, (WORD)-1, // Word
317 0x2000, (WORD)-1, (WORD)-1, (WORD)-1, // Long
318 0x3000 // Word (SIZN)
321 // Word/long size (0=.w, 1=.l) in bit 8
325 0, (WORD)-1, // SIZW, n/a
326 1<<8, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
330 // Byte/Word/long size (0=.w, 1=.l) in bit 9
334 1<<9, (WORD)-1, // Word
335 1<<10, (WORD)-1, (WORD)-1, (WORD)-1, // Long
339 // Addressing mode in bits 6..11 (register/mode fields are reversed)
341 00000, 01000, 02000, 03000, 04000, 05000, 06000, 07000,
342 00100, 01100, 02100, 03100, 04100, 05100, 06100, 07100,
343 00200, 01200, 02200, 03200, 04200, 05200, 06200, 07200,
344 00300, 01300, 02300, 03300, 04300, 05300, 06300, 07300,
345 00400, 01400, 02400, 03400, 04400, 05400, 06400, 07400,
346 00500, 01500, 02500, 03500, 04500, 05500, 06500, 07500,
347 00600, 01600, 02600, 03600, 04600, 05600, 06600, 07600,
348 00700, 01700, 02700, 03700, 04700, 05700, 06700, 07700
351 // Control registers lookup table
353 // MC68010/MC68020/MC68030/MC68040/CPU32
354 0x000, // Source Function Code(SFC)
355 0x001, // Destination Function Code(DFC)
356 0x800, // User Stack Pointer(USP)
357 0x801, // Vector Base Register(VBR)
358 // MC68020 / MC68030 / MC68040
359 0x002, // Cache Control Register(CACR)
360 0x802, // Cache Address Register(CAAR) (020/030 only)
361 0x803, // Master Stack Pointer(MSP)
362 0x804, // Interrupt Stack Pointer(ISP)
363 // MC68040 / MC68LC040
364 0x003, // MMU Translation Control Register(TC)
365 0x004, // Instruction Transparent Translation Register 0 (ITT0)
366 0x005, // Instruction Transparent Translation Register 1 (ITT1)
367 0x006, // Data Transparent Translation Register 0 (DTT0)
368 0x007, // Data Transparent Translation Register 1 (DTT1)
369 0x805, // MMU Status Register(MMUSR)
370 0x806, // User Root Pointer(URP)
371 0x807, // Supervisor Root Pointer(SRP)
373 0x004, // Instruction Access Control Register 0 (IACR0)
374 0x005, // Instruction Access Control Register 1 (IACR1)
375 0x006, // Data Access Control Register 0 (DACR1)
376 0x007, // Data Access Control Register 1 (DACR1)
378 0xFFF // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
383 int m_unimp(WORD unused1, WORD unused2)
385 return (int)error("unimplemented mnemonic");
389 //int m_badmode(void)
390 int m_badmode(WORD unused1, WORD unused2)
392 return (int)error("inappropriate addressing mode");
396 int m_self(WORD inst, WORD usused)
404 // Do one EA in bits 0..5
406 // Bits in `inst' have the following meaning:
408 // Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits
411 // If bit one is set, the OTHER ea (the one that wasn't generated by bit zero)
412 // is generated after the instruction. Regardless of bit 0's value, ea0 is
413 // always deposited in memory before ea1.
415 // If bit two is set, standard size bits are set in the instr in bits 6 and 7.
417 // If bit four is set, bit three specifies which eaXreg to place in bits 9..11
420 int m_ea(WORD inst, WORD siz)
422 WORD flg = inst; // Save flag bits
423 inst &= ~0x3F; // Clobber flag bits in instr
425 // Install "standard" instr size bits
431 // OR-in register number
433 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
435 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
441 inst |= am1 | a1reg; // Get ea1 into instr
442 D_word(inst); // Deposit instr
444 // Generate ea0 if requested
448 ea1gen(siz); // Generate ea1
453 inst |= am0 | a0reg; // Get ea0 into instr
454 D_word(inst); // Deposit instr
455 ea0gen(siz); // Generate ea0
457 // Generate ea1 if requested
467 // Check if lea x(an),an can be optimised to addq.w #x,an--otherwise fall back
470 int m_lea(WORD inst, WORD siz)
472 if (optim_flags[OPT_LEA_ADDQ]
473 && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
474 && ((a0exval > 0) && (a0exval <= 8)))
476 inst = B16(01010000, 01001000) | ((a0exval & 7) << 9) | (a0reg);
478 warn("lea size(An),An converted to addq #size,An");
482 return m_ea(inst, siz);
486 int m_ea030(WORD inst, WORD siz)
489 WORD flg = inst; // Save flag bits
490 inst &= ~0x3F; // Clobber flag bits in instr
492 // Install "standard" instr size bits
498 // OR-in register number
501 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
505 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
512 inst |= am1 | a1reg; // Get ea1 into instr
513 D_word(inst); // Deposit instr
515 // Generate ea0 if requested
519 ea1gen(siz); // Generate ea1
525 // We get here if we're doing 020+ addressing and an address
526 // register is used. For example, something like "tst a0". A bit of
527 // a corner case, so kludge it
529 else if (am0 == PCDISP)
530 //Another corner case (possibly!), so kludge ahoy
531 inst |= am0; // Get ea0 into instr
532 else if (am0 == IMMED)
533 inst |= am0 | a0reg; // Get ea0 into instr
534 else if (am0 == AM_CCR)
536 else if (am0 == AIND)
539 inst |= a0reg; // Get ea0 into instr
540 D_word(inst); // Deposit instr
541 ea0gen(siz); // Generate ea0
543 // Generate ea1 if requested
553 // Dx,Dy nnnnXXXnssnnnYYY If bit 0 of `inst' is set, install size bits in bits
556 int m_abcd(WORD inst, WORD siz)
565 inst |= a0reg | reg_9[a1reg];
575 int m_adda(WORD inst, WORD siz)
577 inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
579 ea0gen(siz); // Generate EA
586 // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr.
587 // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr.
589 int m_reg(WORD inst, WORD siz)
596 // Install other register (9..11)
597 inst |= reg_9[a1reg];
599 inst &= ~7; // Clear off crufty bits
600 inst |= a0reg; // Install first register
610 int m_imm(WORD inst, WORD siz)
622 int m_imm8(WORD inst, WORD siz)
635 int m_shr(WORD inst, WORD siz)
637 inst |= reg_9[a0reg] | a1reg | siz_6[siz];
647 int m_shi(WORD inst, WORD siz)
649 inst |= a1reg | siz_6[siz];
651 if (a0exattr & DEFINED)
654 return error(range_error);
656 inst |= (a0exval & 7) << 9;
661 AddFixup(FU_QUICK, sloc, a0expr);
670 // {bset, btst, bchg, bclr} -- #immed,ea -- Dn,ea
672 int m_bitop(WORD inst, WORD siz)
674 // Enforce instruction sizes
676 { // X,Dn must be .n or .l
677 if (siz & (SIZB | SIZW))
678 return error(siz_error);
680 else if (siz & (SIZW | SIZL)) // X,ea must be .n or .b
681 return error(siz_error);
683 // Construct instr and EAs
689 ea0gen(SIZB); // Immediate bit number
693 inst |= reg_9[a0reg];
704 int m_dbra(WORD inst, WORD siz)
712 if (a1exattr & DEFINED)
714 if ((a1exattr & TDB) != cursect)
715 return error(rel_error);
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 if (optim_flags[OPT_MOVEL_MOVEQ]
824 && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
825 && ((a0exattr & (TDB | DEFINED)) == DEFINED)
826 && (a0exval + 0x80 < 0x100))
828 m_moveq((WORD)0x7000, (WORD)0);
831 warn("move.l #size,dx converted to moveq");
835 if ((am0 < ABASE) && (am1 < ABASE)) //68000 modes
837 inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
845 ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
849 inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0 - ABASE];
865 // Handle MOVE <C_ALL030> <C_ALTDATA>
866 // MOVE <C_ALL030> <M_AREG>
868 int m_move30(WORD inst, WORD size)
870 // Cast the passed in value to an int
872 inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
887 // move USP,An -- move An,USP
889 int m_usp(WORD inst, WORD siz)
894 inst |= a1reg; // USP, An
896 inst |= a0reg; // An, USP
907 int m_moveq(WORD inst, WORD siz)
911 // Arrange for future fixup
912 if (!(a0exattr & DEFINED))
914 AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
917 else if (a0exval + 0x100 >= 0x200)
918 return error(range_error);
920 inst |= reg_9[a1reg] | (a0exval & 0xFF);
928 // movep Dn, disp(An) -- movep disp(An), Dn
930 int m_movep(WORD inst, WORD siz)
932 // Tell ea0gen to lay off the 0(a0) optimisations on this one
940 inst |= reg_9[a0reg] | a1reg;
950 inst |= reg_9[a1reg] | a0reg;
967 int m_br(WORD inst, WORD siz)
971 if (a0exattr & DEFINED)
973 if ((a0exattr & TDB) != cursect)
975 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
976 return error(rel_error);
979 v = a0exval - (sloc + 2);
981 // Optimize branch instr. size
984 if (optim_flags[OPT_BSR_BCC_S] && (v != 0) && ((v + 0x80) < 0x100))
991 warn("Bcc.w/BSR.w converted to .s");
998 if ((v + 0x8000) > 0x10000)
999 return error(range_error);
1007 if (siz == SIZB || siz == SIZS)
1009 if ((v + 0x80) >= 0x100)
1010 return error(range_error);
1017 if ((v + 0x8000) >= 0x10000)
1018 return error(range_error);
1026 else if (siz == SIZN)
1029 if (siz == SIZB || siz == SIZS)
1032 AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
1040 AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
1051 int m_addq(WORD inst, WORD siz)
1053 inst |= siz_6[siz] | am1 | a1reg;
1055 if (a0exattr & DEFINED)
1057 if ((a0exval > 8) || (a0exval == 0)) // Range in 1..8
1058 return error(range_error);
1060 inst |= (a0exval & 7) << 9;
1065 AddFixup(FU_QUICK, sloc, a0expr);
1078 int m_trap(WORD inst, WORD siz)
1082 if (a0exattr & DEFINED)
1085 return error(abs_error);
1088 return error(range_error);
1094 return error(undef_error);
1101 // movem <rlist>,ea -- movem ea,<rlist>
1103 int m_movem(WORD inst, WORD siz)
1111 return error("bad size suffix");
1118 // Handle #<expr>, ea
1121 if (abs_expr(&eval) != OK)
1124 if (eval >= 0x10000L)
1125 return error(range_error);
1131 if ((*tok >= KW_D0) && (*tok <= KW_A7))
1134 if (reglist(&rmask) < 0)
1139 return error("missing comma");
1144 inst |= am0 | a0reg;
1146 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
1147 return error("invalid addressing mode");
1149 // If APREDEC, reverse register mask
1155 for(i=0x8000; i; i>>=1, w>>=1)
1156 rmask = (WORD)((rmask << 1) | w & 1);
1165 inst |= 0x0400 | am0 | a0reg;
1168 return error("missing comma");
1171 return error("missing register list");
1178 if (abs_expr(&eval) != OK)
1181 if (eval >= 0x10000)
1182 return error(range_error);
1186 else if (reglist(&rmask) < 0)
1189 if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
1190 return error("invalid addressing mode");
1202 // CLR.x An ==> SUBA.x An,An
1204 int m_clra(WORD inst, WORD siz)
1206 inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
1213 ////////////////////////////////////////
1215 // 68020/30/40 instructions
1217 ////////////////////////////////////////
1222 int m_br30(WORD inst, WORD siz)
1224 if (a0exattr & DEFINED)
1226 if ((a0exattr & TDB) != cursect)
1227 return error(rel_error);
1229 VALUE v = a0exval - (sloc + 2);
1238 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1246 // bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
1247 // (68020, 68030, 68040)
1249 int m_bfop(WORD inst, WORD siz)
1251 //TODO: is this needed or can we put that in the mask in 68ktab???
1252 if (am0 == AREG || am0== APOSTINC || am0 == APREDEC || am0 == IMMED|| am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE || am0 == PCBASE || am0 == PCMPOST || am0 == PCMPRE)
1253 return m_badmode(inst, siz);
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?
1260 D_word((inst|am0|a0reg|am1|a1reg));
1261 ea0gen(siz); // Generate EA
1263 //Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
1264 inst = bfparam1 | bfparam2;
1267 inst |= a1reg << 12;
1270 inst |= a0reg << 12;
1279 // bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
1281 int m_bkpt(WORD inst, WORD siz)
1285 if (a0exattr & DEFINED)
1288 return error(abs_error);
1291 return error(range_error);
1297 return error(undef_error);
1306 int m_callm(WORD inst, WORD siz)
1313 if (a0exattr & DEFINED)
1316 return error(abs_error);
1319 return error(range_error);
1325 return error(undef_error);
1335 // cas (68020, 68030, 68040)
1337 int m_cas(WORD inst, WORD siz)
1343 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1344 return error(unsupport);
1359 return error("bad size suffix");
1364 if ((*tok < KW_D0) && (*tok > KW_D7))
1365 return error("CAS accepts only data registers");
1367 inst2 = (*tok++) & 7;
1370 return error("missing comma");
1373 if ((*tok < KW_D0) && (*tok > KW_D7))
1374 return error("CAS accepts only data registers");
1376 inst2 |= ((*tok++) & 7) << 6;
1379 return error("missing comma");
1382 if ((modes = amode(1)) < 0)
1386 return error("too many ea fields");
1389 return error("extra (unexpected) text found");
1391 // Reject invalud ea modes
1392 amsk = amsktab[am0];
1394 if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
1395 return error("unsupported addressing mode");
1397 inst |= am0 | a0reg;
1407 // cas2 (68020, 68030, 68040)
1409 int m_cas2(WORD inst, WORD siz)
1413 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1414 return error(unsupport);
1429 return error("bad size suffix");
1434 if ((*tok < KW_D0) && (*tok > KW_D7))
1435 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1437 inst2 = (*tok++) & 7;
1440 return error("missing colon");
1443 if ((*tok < KW_D0) && (*tok > KW_D7))
1444 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1446 inst3 = (*tok++) & 7;
1449 return error("missing comma");
1452 if ((*tok < KW_D0) && (*tok > KW_D7))
1453 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1455 inst2 |= ((*tok++) & 7) << 6;
1458 return error("missing colon");
1461 if ((*tok < KW_D0) && (*tok > KW_D7))
1462 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1464 inst3 |= ((*tok++) & 7) << 6;
1467 return error("missing comma");
1471 return error("missing (");
1472 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1473 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1474 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1475 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1477 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1480 return error("missing (");
1483 return error("missing colon");
1487 return error("missing (");
1488 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1489 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1490 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1491 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1493 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1496 return error("missing (");
1499 return error("extra (unexpected) text found");
1510 // cmp2 (68020, 68030, 68040, CPU32)
1512 int m_cmp2(WORD inst, WORD siz)
1514 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1515 return error(unsupport);
1517 switch (siz & 0x000F)
1531 WORD flg = inst; // Save flag bits
1532 inst &= ~0x3F; // Clobber flag bits in instr
1534 // Install "standard" instr size bits
1540 // OR-in register number
1542 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1544 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1550 inst |= am1 | a1reg; // Get ea1 into instr
1551 D_word(inst); // Deposit instr
1553 // Generate ea0 if requested
1557 ea1gen(siz); // Generate ea1
1562 inst |= am0 | a0reg; // Get ea0 into instr
1563 D_word(inst); // Deposit instr
1564 ea0gen(siz); // Generate ea0
1566 // Generate ea1 if requested
1571 // If we're called from chk2 then bit 11 of size will be set. This is just
1572 // a dumb mechanism to pass this, required by the extension word. (You might
1573 // have noticed the siz & 15 thing above!)
1574 inst = (a1reg << 12) | (siz & (1 << 11));
1586 // chk2 (68020, 68030, 68040, CPU32)
1588 int m_chk2(WORD inst, WORD siz)
1590 return m_cmp2(inst, siz | (1 << 11));
1595 // cpbcc(68020, 68030)
1597 int m_cpbr(WORD inst, WORD siz)
1599 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1600 return error(unsupport);
1602 if (a0exattr & DEFINED)
1604 if ((a0exattr & TDB) != cursect)
1605 return error(rel_error);
1607 VALUE v = a0exval - (sloc + 2);
1609 // Optimize branch instr. size
1612 if ((v != 0) && ((v + 0x8000) < 0x10000))
1622 if ((v + 0x8000) >= 0x10000)
1623 return error(range_error);
1631 else if (siz == SIZN)
1638 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1646 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1655 // cpdbcc(68020, 68030)
1657 int m_cpdbr(WORD inst, WORD siz)
1659 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1660 return error(unsupport);
1662 return error("Not implemented yet.");
1671 int m_divs(WORD inst, WORD siz)
1673 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1674 return error(unsupport);
1676 WORD flg = inst; // Save flag bits
1677 inst &= ~0x3F; // Clobber flag bits in instr
1679 // Install "standard" instr size bits
1685 // OR-in register number
1687 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1689 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1695 inst |= am1 | a1reg; // Get ea1 into instr
1696 D_word(inst); // Deposit instr
1698 // Generate ea0 if requested
1702 ea1gen(siz); // Generate ea1
1707 inst |= am0 | a0reg; // Get ea0 into instr
1708 D_word(inst); // Deposit instr
1709 ea0gen(siz); // Generate ea0
1711 // Generate ea1 if requested
1716 inst = a1reg + (a2reg << 12) + (1 << 11);
1726 int m_muls(WORD inst, WORD siz)
1728 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1729 return error(unsupport);
1731 WORD flg = inst; // Save flag bits
1732 inst &= ~0x3F; // Clobber flag bits in instr
1734 // Install "standard" instr size bits
1740 // OR-in register number
1742 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1744 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1750 inst |= am1 | a1reg; // Get ea1 into instr
1751 D_word(inst); // Deposit instr
1754 inst = a1reg + (a2reg << 12) + (1 << 11);
1755 inst |= mulmode; // add size bit
1758 // Generate ea0 if requested
1762 ea1gen(siz); // Generate ea1
1767 inst |= am0 | a0reg; // Get ea0 into instr
1768 D_word(inst); // Deposit instr
1770 inst = a1reg + (a2reg << 12) + (1 << 11);
1771 inst |= mulmode; // add size bit
1774 ea0gen(siz); // Generate ea0
1776 // Generate ea1 if requested
1791 int m_divu(WORD inst, WORD siz)
1793 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1794 return error(unsupport);
1796 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1798 WORD flg = inst; // Save flag bits
1799 inst &= ~0x3F; // Clobber flag bits in instr
1801 // Install "standard" instr size bits
1807 // OR-in register number
1809 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1811 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1817 inst |= am1 | a1reg; // Get ea1 into instr
1818 D_word(inst); // Deposit instr
1820 // Generate ea0 if requested
1824 ea1gen(siz); // Generate ea1
1829 inst |= am0 | a0reg; // Get ea0 into instr
1830 D_word(inst); // Deposit instr
1831 ea0gen(siz); // Generate ea0
1833 // Generate ea1 if requested
1838 inst = a1reg + (a2reg << 12);
1848 int m_mulu(WORD inst, WORD siz)
1850 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1851 return error(unsupport);
1853 WORD flg = inst; // Save flag bits
1854 inst &= ~0x3F; // Clobber flag bits in instr
1856 // Install "standard" instr size bits
1862 // OR-in register number
1864 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1866 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1872 inst |= am1 | a1reg; // Get ea1 into instr
1873 D_word(inst); // Deposit instr
1875 // Generate ea0 if requested
1879 ea1gen(siz); // Generate ea1
1884 inst |= am0 | a0reg; // Get ea0 into instr
1885 D_word(inst); // Deposit instr
1886 ea0gen(siz); // Generate ea0
1888 // Generate ea1 if requested
1893 inst = a1reg + (a2reg << 12);
1894 inst |= mulmode; // add size bit
1904 int m_divsl(WORD inst, WORD siz)
1906 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1907 return error(unsupport);
1909 WORD flg = inst; // Save flag bits
1910 inst &= ~0x3F; // Clobber flag bits in instr
1912 // Install "standard" instr size bits
1918 // OR-in register number
1920 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1922 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1928 inst |= am1 | a1reg; // Get ea1 into instr
1929 D_word(inst); // Deposit instr
1931 // Generate ea0 if requested
1935 ea1gen(siz); // Generate ea1
1940 inst |= am0 | a0reg; // Get ea0 into instr
1941 D_word(inst); // Deposit instr
1942 ea0gen(siz); // Generate ea0
1944 // Generate ea1 if requested
1949 inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
1958 int m_divul(WORD inst, WORD siz)
1960 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1961 return error(unsupport);
1963 WORD flg = inst; // Save flag bits
1964 inst &= ~0x3F; // Clobber flag bits in instr
1966 // Install "standard" instr size bits
1972 // OR-in register number
1974 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1976 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1982 inst |= am1 | a1reg; // Get ea1 into instr
1983 D_word(inst); // Deposit instr
1985 // Generate ea0 if requested
1989 ea1gen(siz); // Generate ea1
1994 inst |= am0 | a0reg; // Get ea0 into instr
1995 D_word(inst); // Deposit instr
1996 ea0gen(siz); // Generate ea0
1998 // Generate ea1 if requested
2003 inst = a1reg + (a2reg << 12) + (1 << 10);
2011 // move16 (ax)+,(ay)+
2013 int m_move16a(WORD inst, WORD siz)
2015 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2016 return error(unsupport);
2020 inst = (1 << 15) + (a1reg << 12);
2028 // move16 with absolute address
2030 int m_move16b(WORD inst, WORD siz)
2032 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2033 return error(unsupport);
2039 if (am0 == APOSTINC)
2042 return error("Wasn't this suppose to call m_move16a???");
2045 //move16 (ax)+,(xxx).L
2050 else if (am0 == ABSL)
2054 //move16 (xxx).L,(ax)+
2060 //move16 (xxx).L,(ax)
2065 else if (am0 == AIND)
2067 //move16 (ax),(xxx).L
2082 int m_pack(WORD inst, WORD siz)
2084 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
2085 return error(unsupport);
2087 WARNING(Parsing stuff by hand here might be better)
2090 if ((am0 == DREG) && (am1 == DREG))
2092 inst |= (1 << 3) + (a0reg << 9) + (a1reg);
2094 else if ((am0 == APREDEC) && (am1 == APREDEC))
2096 inst |= (a0reg << 9) + (a1reg);
2099 return error("Only allowed combinations for pack/unpack are -(ax),-(ay) and dx,dy.");
2111 int m_rtm(WORD inst, WORD siz)
2119 else if (am0 == AREG)
2121 inst |= (1 << 3) + a0reg;
2124 return error("rtm only allows data or address registers.");
2135 int m_rtd(WORD inst, WORD siz)
2139 if (a0exattr & DEFINED)
2142 return error(abs_error);
2144 if ((a0exval + 0x8000) <= 0x7FFF)
2145 return error(range_error);
2151 return error(undef_error);
2160 int m_trapcc(WORD inst, WORD siz)
2168 else if (am0 == IMMED)
2172 if (a0exval < 0x10000)
2179 return error("Immediate value too big");
2189 return error("Invalid parameter for trapcc");
2198 int m_cinv(WORD inst, WORD siz)
2201 WARNING("cinvl ,(an) / cinvp ,(an) / cinva should work!")
2204 inst |= (0 << 6) | (a1reg);
2205 else if (am0 == KW_IC40)
2206 inst |= (2 << 6) | (a1reg);
2207 else if (am0 == KW_DC40)
2208 inst |= (1 << 6) | (a1reg);
2209 else if (am0 == KW_BC40)
2210 inst |= (3 << 6) | (a1reg);
2218 // cpRESTORE (68020, 68030)
2220 int m_cprest(WORD inst, WORD siz)
2222 if (activecpu & !(CPU_68020 | CPU_68030))
2223 return error(unsupport);
2225 inst |= am0 | a0reg;
2234 // movec (68010, 68020, 68030, 68040, CPU32)
2236 int m_movec(WORD inst, WORD siz)
2240 if (am0 == DREG || am0 == AREG)
2248 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
2253 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
2264 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
2269 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2279 // moves (68010, 68020, 68030, 68040, CPU32)
2281 int m_moves(WORD inst, WORD siz)
2283 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2284 return error(unsupport);
2290 else if (siz == SIZL)
2301 inst |= am1 | a1reg;
2303 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2306 else if (am0 == AREG)
2308 inst |= am1 | a1reg;
2310 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2317 inst |= am0 | a0reg;
2319 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2324 inst |= am0 | a0reg;
2326 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2338 int m_pbcc(WORD inst, WORD siz)
2341 return error("Not implemented yet.");
2348 int m_pflusha(WORD inst, WORD siz)
2353 inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
2360 // pflush (68030, 68040, 68060)
2362 int m_pflush(WORD inst, WORD siz)
2364 if (activecpu == CPU_68030)
2367 D_word((1 << 13) | (1 << 10) | (0 << 5) | 0);
2369 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2374 return error(unsupport);
2383 int m_pflushr(WORD inst, WORD siz)
2387 WORD flg = inst; // Save flag bits
2388 inst &= ~0x3F; // Clobber flag bits in instr
2390 // Install "standard" instr size bits
2396 // OR-in register number
2398 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2400 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2406 inst |= am1 | a1reg; // Get ea1 into instr
2407 D_word(inst); // Deposit instr
2409 // Generate ea0 if requested
2413 ea1gen(siz); // Generate ea1
2418 inst |= am0 | a0reg; // Get ea0 into instr
2419 D_word(inst); // Deposit instr
2420 ea0gen(siz); // Generate ea0
2422 // Generate ea1 if requested
2427 D_word(B16(10100000, 00000000));
2433 // ploadr, ploadw (68030)
2435 int m_pload(WORD inst, WORD siz)
2438 return error("Not implemented yet.");
2445 int m_pmove(WORD inst, WORD siz)
2451 inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2452 inst &= ~(1 << 8); //And mask it out
2459 else if (am1 == CREG)
2465 return error("pmove sez: Wut?");
2467 if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
2468 && ((siz != SIZD) && (siz != SIZN)))
2469 return error(siz_error);
2471 if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
2472 && ((siz != SIZL) && (siz != SIZN)))
2473 return error(siz_error);
2475 if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
2476 return error(siz_error);
2478 WARNING(Not all addressing modes are legal here!)
2486 else if (am1 == CREG)
2495 case (KW_URP - KW_SFC):
2496 inst2 |= (3 << 10) + (2 << 13); break;
2497 case (KW_SRP - KW_SFC):
2498 inst2 |= (2 << 10) + (2 << 13); break;
2499 case (KW_TC - KW_SFC):
2500 inst2 |= (0 << 10) + (2 << 13); break;
2501 case (KW_TT0 - KW_SFC):
2502 inst2 |= (2 << 10) + (0 << 13); break;
2503 case (KW_TT1 - KW_SFC):
2504 inst2 |= (3 << 10) + (0 << 13); break;
2505 case (KW_MMUSR - KW_SFC):
2506 inst2 |= (3 << 10) + (3 << 13); break;
2507 case (KW_CRP - KW_SFC) : //68851 only
2508 inst2 |= (3 << 10) + (2 << 13); break;
2520 int m_pmovefd(WORD inst, WORD siz)
2524 return m_pmove(inst | (1 << 8), siz);
2531 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; }
2532 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; }
2533 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; }
2534 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; }
2535 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; }
2536 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; }
2537 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; }
2538 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; }
2539 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; }
2540 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; }
2541 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; }
2542 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; }
2543 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; }
2544 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; }
2545 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; }
2546 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; }
2547 int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2548 int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2549 int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2550 int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2551 int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2552 int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2553 int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2554 int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2555 int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2556 int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2557 int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2558 int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2559 int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2560 int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2561 int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2562 int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2566 // ptestr, ptestw (68030)
2568 int m_ptest(WORD inst, WORD siz)
2572 if (activecpu == CPU_68030)
2573 return error("Not implemented yet.");
2574 else if (activecpu == CPU_68040)
2575 return error("Not implemented yet.");
2581 #define FPU_NOWARN 0
2582 #define FPU_P_EMUL 1
2583 #define FPU_P2_EMU 2
2588 // Generate a FPU opcode
2590 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2592 if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
2594 inst |= (1 << 9); // Bolt on FPU id
2601 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2605 case SIZB: inst |= (6 << 10); break;
2606 case SIZW: inst |= (4 << 10); break;
2607 case SIZL: inst |= (0 << 10); break;
2609 case SIZS: inst |= (1 << 10); break;
2610 case SIZD: inst |= (5 << 10); break;
2611 case SIZX: inst |= (2 << 10); break;
2616 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2620 return error("Something bad happened, possibly, in gen_fpu.");
2624 inst |= (a1reg << 7);
2631 inst |= (1 << 9); //Bolt on FPU id
2635 inst |= (a1reg << 7);
2640 if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
2641 warn("Instruction is emulated in 68040");
2648 // fabs, fsabs, fdabs (6888X, 68040)
2650 int m_fabs(WORD inst, WORD siz)
2652 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2656 int m_fsabs(WORD inst, WORD siz)
2658 if (activefpu == FPU_68040)
2659 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2661 return error("Unsupported in current FPU");
2665 int m_fdabs(WORD inst, WORD siz)
2667 if (activefpu == FPU_68040)
2668 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2670 return error("Unsupported in current FPU");
2675 // facos (6888X, 68040FPSP)
2677 int m_facos(WORD inst, WORD siz)
2679 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
2684 // fadd (6888X, 68040FPSP)
2686 int m_fadd(WORD inst, WORD siz)
2688 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
2692 int m_fsadd(WORD inst, WORD siz)
2694 if (activefpu == FPU_68040)
2695 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
2697 return error("Unsupported in current FPU");
2701 int m_fdadd(WORD inst, WORD siz)
2703 if (activefpu == FPU_68040)
2704 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
2706 return error("Unsupported in current FPU");
2711 // fasin (6888X, 68040FPSP)f
2713 int m_fasin(WORD inst, WORD siz)
2715 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
2720 // fatan (6888X, 68040FPSP)
2722 int m_fatan(WORD inst, WORD siz)
2724 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
2729 // fatanh (6888X, 68040FPSP)
2731 int m_fatanh(WORD inst, WORD siz)
2733 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
2738 // fcmp (6888X, 68040)
2740 int m_fcmp(WORD inst, WORD siz)
2742 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
2747 // fcos (6888X, 68040FPSP)
2749 int m_fcos(WORD inst, WORD siz)
2751 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
2756 // fcosh (6888X, 68040FPSP)
2758 int m_fcosh(WORD inst, WORD siz)
2760 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
2765 // fdbcc (6888X, 68040)
2767 int m_fdbcc(WORD inst, WORD siz)
2769 WORD opcode = inst & 0x3F; //Grab conditional bitfield
2779 if (a1exattr & DEFINED)
2781 if ((a1exattr & TDB) != cursect)
2782 return error(rel_error);
2784 VALUE v = a1exval - sloc;
2786 if ((v + 0x8000) > 0x10000)
2787 return error(range_error);
2793 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
2802 // fdiv (6888X, 68040)
2804 int m_fdiv(WORD inst, WORD siz)
2806 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
2810 int m_fsdiv(WORD inst, WORD siz)
2812 if (activefpu == FPU_68040)
2813 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
2815 return error("Unsupported in current FPU");
2819 int m_fddiv(WORD inst, WORD siz)
2821 if (activefpu == FPU_68040)
2822 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
2824 return error("Unsupported in current FPU");
2829 // fetox (6888X, 68040FPSP)
2831 int m_fetox(WORD inst, WORD siz)
2833 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
2838 // fetoxm1 (6888X, 68040FPSP)
2840 int m_fetoxm1(WORD inst, WORD siz)
2842 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
2847 // fgetexp (6888X, 68040FPSP)
2849 int m_fgetexp(WORD inst, WORD siz)
2851 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
2856 // fgetman (6888X, 68040FPSP)
2858 int m_fgetman(WORD inst, WORD siz)
2860 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
2865 // fint (6888X, 68040FPSP)
2867 int m_fint(WORD inst, WORD siz)
2870 // special case - fint fpx = fint fpx,fpx
2873 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
2878 // fintrz (6888X, 68040FPSP)
2880 int m_fintrz(WORD inst, WORD siz)
2883 // special case - fintrz fpx = fintrz fpx,fpx
2886 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
2891 // flog10 (6888X, 68040FPSP)
2893 int m_flog10(WORD inst, WORD siz)
2895 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
2900 // flog2 (6888X, 68040FPSP)
2902 int m_flog2(WORD inst, WORD siz)
2904 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
2909 // flogn (6888X, 68040FPSP)
2911 int m_flogn(WORD inst, WORD siz)
2913 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
2918 // flognp1 (6888X, 68040FPSP)
2920 int m_flognp1(WORD inst, WORD siz)
2922 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
2927 // fmod (6888X, 68040FPSP)
2929 int m_fmod(WORD inst, WORD siz)
2931 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
2936 // fmove (6888X, 68040)
2938 int m_fmove(WORD inst, WORD siz)
2942 if ((am0 == FREG) && (am1 < AM_USP))
2946 inst |= am1 | a1reg;
2952 WARNING("K-factor logic is totally bogus - fix!")
2957 case SIZB: inst |= (6 << 10); break;
2958 case SIZW: inst |= (4 << 10); break;
2959 case SIZL: inst |= (0 << 10); break;
2961 case SIZS: inst |= (1 << 10); break;
2962 case SIZD: inst |= (5 << 10); break;
2963 case SIZX: inst |= (2 << 10); break;
2964 case SIZP: inst |= (3 << 10);
2968 inst |= (bfparam1 & 0x7FF) >> 2;
2971 return error("Something bad happened, possibly.");
2975 // Immediate {} value
2976 if (bf0exval >= (1 << 6))
2977 return error("K-factor must be between 0 and 31");
2979 if (!bfparam1 && (siz == SIZP))
2982 // Destination specifier
2983 inst |= (a0reg << 7);
2991 else if ((am0 < AM_USP) && (am1 == FREG))
2996 inst |= am0 | a0reg;
3005 case SIZB: inst |= (6 << 10); break;
3006 case SIZW: inst |= (4 << 10); break;
3007 case SIZL: inst |= (0 << 10); break;
3009 case SIZS: inst |= (1 << 10); break;
3010 case SIZD: inst |= (5 << 10); break;
3011 case SIZX: inst |= (2 << 10); break;
3012 case SIZP: inst |= (3 << 10); break;
3014 return error("Something bad happened, possibly.");
3018 // Destination specifier
3019 inst |= (a1reg << 7);
3027 else if ((am0 == FREG) && (am1 == FREG))
3029 // register-to-register
3030 // Essentially ea to register with R/0=0
3040 return error("Invalid size");
3043 inst |= (a0reg << 10);
3045 // Destination register
3046 inst |= (a1reg << 7);
3056 // fmove (6888X, 68040)
3058 int m_fmovescr(WORD inst, WORD siz)
3060 // Move Floating-Point System Control Register (FPCR)
3064 if ((am0 == FPSCR) && (am1 < AM_USP))
3066 inst |= am1 | a1reg;
3068 inst = (1 << 13) + (1 << 15);
3074 else if ((am1 == FPSCR) && (am0 < AM_USP))
3076 inst |= am0 | a0reg;
3078 inst = (0 << 13) + (1 << 15);
3085 return error("m_fmovescr says: wut?");
3090 // fsmove/fdmove (68040)
3092 int m_fsmove(WORD inst, WORD siz)
3094 return error("Not implemented yet.");
3097 if (activefpu == FPU_68040)
3098 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3100 return error("Unsupported in current FPU");
3105 int m_fdmove(WORD inst, WORD siz)
3107 return error("Not implemented yet.");
3110 if (activefpu == FPU_68040)
3111 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3113 return error("Unsupported in current FPU");
3119 // fmovecr (6888X, 68040FPSP)
3121 int m_fmovecr(WORD inst, WORD siz)
3129 if (activefpu == FPU_68040)
3130 warn("Instruction is emulated in 68040");
3137 // fmovem (6888X, 68040)
3139 int m_fmovem(WORD inst, WORD siz)
3144 if (siz == SIZX || siz==SIZN)
3146 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3148 //fmovem.x <rlist>,ea
3149 if (fpu_reglist_left(®mask) < 0)
3153 return error("missing comma");
3158 inst |= am0 | a0reg;
3160 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3161 return error("invalid addressing mode");
3164 inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
3169 else if ((*tok >= KW_D0) && (*tok <= KW_D7))
3172 datareg = (*tok++ & 7) << 10;
3175 return error("missing comma");
3180 inst |= am0 | a0reg;
3182 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3183 return error("invalid addressing mode");
3186 inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
3197 inst |= am0 | a0reg;
3200 return error("missing comma");
3202 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3204 //fmovem.x ea,<rlist>
3205 if (fpu_reglist_right(®mask) < 0)
3209 inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
3217 datareg = (*tok++ & 7) << 10;
3219 inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
3226 else if (siz == SIZL)
3228 if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
3230 //fmovem.l <rlist>,ea
3231 regmask = (1 << 15) | (1 << 13);
3233 if (*tok == KW_FPCR)
3235 regmask |= (1 << 12);
3240 if (*tok == KW_FPSR)
3242 regmask |= (1 << 11);
3247 if (*tok == KW_FPIAR)
3249 regmask |= (1 << 10);
3254 if ((*tok == '/') || (*tok == '-'))
3261 return error("missing comma");
3266 inst |= am0 | a0reg;
3273 //fmovem.l ea,<rlist>
3277 inst |= am0 | a0reg;
3280 return error("missing comma");
3282 regmask = (1 << 15) | (0 << 13);
3285 if (*tok == KW_FPCR)
3287 regmask |= (1 << 12);
3292 if (*tok == KW_FPSR)
3294 regmask |= (1 << 11);
3299 if (*tok == KW_FPIAR)
3301 regmask |= (1 << 10);
3306 if ((*tok == '/') || (*tok == '-'))
3313 return error("extra (unexpected) text found");
3315 inst |= am0 | a0reg;
3322 return error("bad size suffix");
3329 // fmul (6888X, 68040)
3331 int m_fmul(WORD inst, WORD siz)
3333 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
3337 int m_fsmul(WORD inst, WORD siz)
3339 if (activefpu == FPU_68040)
3340 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
3342 return error("Unsupported in current FPU");
3346 int m_fdmul(WORD inst, WORD siz)
3348 if (activefpu == FPU_68040)
3349 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
3351 return error("Unsupported in current FPU");
3356 // fneg (6888X, 68040)
3358 int m_fneg(WORD inst, WORD siz)
3360 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
3364 int m_fsneg(WORD inst, WORD siz)
3366 if (activefpu == FPU_68040)
3367 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
3369 return error("Unsupported in current FPU");
3373 int m_fdneg(WORD inst, WORD siz)
3375 if (activefpu == FPU_68040)
3376 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
3378 return error("Unsupported in current FPU");
3383 // fnop (6888X, 68040)
3385 int m_fnop(WORD inst, WORD siz)
3387 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3392 // frem (6888X, 68040FPSP)
3394 int m_frem(WORD inst, WORD siz)
3396 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3401 // fscale (6888X, 68040FPSP)
3403 int m_fscale(WORD inst, WORD siz)
3405 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3410 // FScc (6888X, 68040)
3412 int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3413 int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3414 int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3415 int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3416 int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3417 int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3418 int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3419 int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3420 int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3421 int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3422 int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3423 int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3424 int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3425 int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3426 int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3427 int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3428 int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3429 int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3430 int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3431 int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3432 int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3433 int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3434 int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3435 int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3436 int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3437 int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3438 int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3439 int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3440 int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3441 int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3442 int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3443 int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3447 // FTRAPcc (6888X, 68040)
3449 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;}
3450 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;}
3451 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;}
3452 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;}
3453 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;}
3454 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;}
3455 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;}
3456 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;}
3457 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;}
3458 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;}
3459 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;}
3460 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;}
3461 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;}
3462 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;}
3463 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;}
3464 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;}
3465 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;}
3466 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;}
3467 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;}
3468 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;}
3469 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;}
3470 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;}
3471 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;}
3472 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;}
3473 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;}
3474 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;}
3475 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;}
3476 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;}
3477 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;}
3478 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;}
3479 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;}
3480 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;}
3482 int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3483 int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3484 int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3485 int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3486 int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3487 int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3488 int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3489 int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3490 int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3491 int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3492 int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3493 int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3494 int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3495 int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3496 int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3497 int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3498 int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3499 int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3500 int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3501 int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3502 int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3503 int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3504 int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3505 int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3506 int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3507 int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3508 int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3509 int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3510 int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3511 int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3512 int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3513 int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3517 // fsgldiv (6888X, 68040)
3519 int m_fsgldiv(WORD inst, WORD siz)
3521 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3526 // fsglmul (6888X, 68040)
3528 int m_fsglmul(WORD inst, WORD siz)
3530 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3535 // fsin (6888X, 68040FPSP)
3537 int m_fsin(WORD inst, WORD siz)
3539 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3544 // fsincos (6888X, 68040FPSP)
3546 int m_fsincos(WORD inst, WORD siz)
3548 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
3559 // fsin (6888X, 68040FPSP)
3561 int m_fsinh(WORD inst, WORD siz)
3563 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3568 // fsqrt (6888X, 68040)
3570 int m_fsqrt(WORD inst, WORD siz)
3572 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3576 int m_fsfsqrt(WORD inst, WORD siz)
3578 if (activefpu == FPU_68040)
3579 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
3581 return error("Unsupported in current FPU");
3585 int m_fdfsqrt(WORD inst, WORD siz)
3587 if (activefpu == FPU_68040)
3588 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
3590 return error("Unsupported in current FPU");
3595 // fsub (6888X, 68040)
3597 int m_fsub(WORD inst, WORD siz)
3599 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
3603 int m_fsfsub(WORD inst, WORD siz)
3605 if (activefpu == FPU_68040)
3606 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
3608 return error("Unsupported in current FPU");
3612 int m_fdsub(WORD inst, WORD siz)
3614 if (activefpu == FPU_68040)
3615 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
3617 return error("Unsupported in current FPU");
3622 // ftan (6888X, 68040FPSP)
3624 int m_ftan(WORD inst, WORD siz)
3626 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
3631 // ftanh (6888X, 68040FPSP)
3633 int m_ftanh(WORD inst, WORD siz)
3635 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
3640 // ftentox (6888X, 68040FPSP)
3642 int m_ftentox(WORD inst, WORD siz)
3644 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
3649 // ftst (6888X, 68040)
3651 int m_ftst(WORD inst, WORD siz)
3653 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
3658 // ftwotox (6888X, 68040FPSP)
3660 int m_ftwotox(WORD inst, WORD siz)
3662 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);