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
23 int movep = 0; // Global flag to indicate we're generating a movep instruction
25 // Function prototypes
26 int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
27 int m_self(WORD, WORD);
28 int m_abcd(WORD, WORD);
29 int m_reg(WORD, WORD);
30 int m_imm(WORD, WORD);
31 int m_imm8(WORD, WORD);
32 int m_shi(WORD, WORD);
33 int m_shr(WORD, WORD);
34 int m_bitop(WORD, WORD);
35 int m_exg(WORD, WORD);
37 int m_lea(WORD, WORD);
39 int m_dbra(WORD, WORD);
40 int m_link(WORD, WORD);
41 int m_adda(WORD, WORD);
42 int m_addq(WORD, WORD);
43 //int m_move(WORD, int);
44 int m_move(WORD, WORD);
45 int m_moveq(WORD, WORD);
46 int m_usp(WORD, WORD);
47 int m_movep(WORD, WORD);
48 int m_trap(WORD, WORD);
49 int m_movem(WORD, WORD);
50 int m_clra(WORD, WORD);
52 int m_move30(WORD, WORD); //68020/30/40/60
53 int m_br30(WORD inst, WORD siz);
54 int m_ea030(WORD inst, WORD siz);
55 int m_bfop(WORD inst, WORD siz);
56 int m_callm(WORD inst, WORD siz);
57 int m_cas(WORD inst, WORD siz);
58 int m_cas2(WORD inst, WORD siz);
59 int m_chk2(WORD inst, WORD siz);
60 int m_cmp2(WORD inst, WORD siz);
61 int m_bkpt(WORD inst, WORD siz);
62 int m_cpbr(WORD inst, WORD siz);
63 int m_cpdbr(WORD inst, WORD siz);
64 int m_divs(WORD inst, WORD siz);
65 int m_muls(WORD inst, WORD siz);
66 int m_divu(WORD inst, WORD siz);
67 int m_mulu(WORD inst, WORD siz);
68 int m_divsl(WORD inst, WORD siz);
69 int m_divul(WORD inst, WORD siz);
70 int m_move16a(WORD inst, WORD siz);
71 int m_move16b(WORD inst, WORD siz);
72 int m_pack(WORD inst, WORD siz);
73 int m_rtm(WORD inst, WORD siz);
74 int m_rtd(WORD inst, WORD siz);
75 int m_trapcc(WORD inst, WORD siz);
76 int m_cinv(WORD inst, WORD siz);
77 int m_cprest(WORD inst, WORD siz);
78 int m_movec(WORD inst, WORD siz);
79 int m_moves(WORD inst, WORD siz);
82 int m_pbcc(WORD inst, WORD siz);
83 int m_pflusha(WORD inst, WORD siz);
84 int m_pflush(WORD inst, WORD siz);
85 int m_pflushr(WORD inst, WORD siz);
86 int m_pload(WORD inst, WORD siz);
87 int m_pmove(WORD inst, WORD siz);
88 int m_pmovefd(WORD inst, WORD siz);
89 int m_ptest(WORD inst, WORD siz);
90 int m_ptrapbs(WORD inst, WORD siz);
91 int m_ptrapbc(WORD inst, WORD siz);
92 int m_ptrapls(WORD inst, WORD siz);
93 int m_ptraplc(WORD inst, WORD siz);
94 int m_ptrapss(WORD inst, WORD siz);
95 int m_ptrapsc(WORD inst, WORD siz);
96 int m_ptrapas(WORD inst, WORD siz);
97 int m_ptrapac(WORD inst, WORD siz);
98 int m_ptrapws(WORD inst, WORD siz);
99 int m_ptrapwc(WORD inst, WORD siz);
100 int m_ptrapis(WORD inst, WORD siz);
101 int m_ptrapic(WORD inst, WORD siz);
102 int m_ptrapgc(WORD inst, WORD siz);
103 int m_ptrapgs(WORD inst, WORD siz);
104 int m_ptrapcs(WORD inst, WORD siz);
105 int m_ptrapcc(WORD inst, WORD siz);
106 int m_ptrapbsn(WORD inst, WORD siz);
107 int m_ptrapbcn(WORD inst, WORD siz);
108 int m_ptraplsn(WORD inst, WORD siz);
109 int m_ptraplcn(WORD inst, WORD siz);
110 int m_ptrapssn(WORD inst, WORD siz);
111 int m_ptrapscn(WORD inst, WORD siz);
112 int m_ptrapasn(WORD inst, WORD siz);
113 int m_ptrapacn(WORD inst, WORD siz);
114 int m_ptrapwsn(WORD inst, WORD siz);
115 int m_ptrapwcn(WORD inst, WORD siz);
116 int m_ptrapisn(WORD inst, WORD siz);
117 int m_ptrapicn(WORD inst, WORD siz);
118 int m_ptrapgsn(WORD inst, WORD siz);
119 int m_ptrapgcn(WORD inst, WORD siz);
120 int m_ptrapcsn(WORD inst, WORD siz);
121 int m_ptrapccn(WORD inst, WORD siz);
124 int m_fabs(WORD inst, WORD siz);
125 int m_facos(WORD inst, WORD siz);
126 int m_fadd(WORD inst, WORD siz);
127 int m_fasin(WORD inst, WORD siz);
128 int m_fatan(WORD inst, WORD siz);
129 int m_fatanh(WORD inst, WORD siz);
130 int m_fcmp(WORD inst, WORD siz);
131 int m_fcos(WORD inst, WORD siz);
132 int m_fcosh(WORD inst, WORD siz);
133 int m_fdabs(WORD inst, WORD siz);
134 int m_fdadd(WORD inst, WORD siz);
135 int m_fdbcc(WORD inst, WORD siz);
136 int m_fddiv(WORD inst, WORD siz);
137 int m_fdfsqrt(WORD inst, WORD siz);
138 int m_fdiv(WORD inst, WORD siz);
139 int m_fdmove(WORD inst, WORD siz);
140 int m_fdmul(WORD inst, WORD siz);
141 int m_fdneg(WORD inst, WORD siz);
142 int m_fdsub(WORD inst, WORD siz);
143 int m_fetox(WORD inst, WORD siz);
144 int m_fetoxm1(WORD inst, WORD siz);
145 int m_fgetexp(WORD inst, WORD siz);
146 int m_fgetman(WORD inst, WORD siz);
147 int m_fint(WORD inst, WORD siz);
148 int m_fintrz(WORD inst, WORD siz);
149 int m_flog10(WORD inst, WORD siz);
150 int m_flog2(WORD inst, WORD siz);
151 int m_flogn(WORD inst, WORD siz);
152 int m_flognp1(WORD inst, WORD siz);
153 int m_fmod(WORD inst, WORD siz);
154 int m_fmove(WORD inst, WORD siz);
155 int m_fmovescr(WORD inst, WORD siz);
156 int m_fmovecr(WORD inst, WORD siz);
157 int m_fmovem(WORD inst, WORD siz);
158 int m_fmul(WORD inst, WORD siz);
159 int m_fneg(WORD inst, WORD siz);
160 int m_fnop(WORD inst, WORD siz);
161 int m_frem(WORD inst, WORD siz);
162 int m_fsabs(WORD inst, WORD siz);
163 int m_fsadd(WORD inst, WORD siz);
164 int m_fseq(WORD inst, WORD siz);
165 int m_fsne(WORD inst, WORD siz);
166 int m_fsgt(WORD inst, WORD siz);
167 int m_fsngt(WORD inst, WORD siz);
168 int m_fsge(WORD inst, WORD siz);
169 int m_fsnge(WORD inst, WORD siz);
170 int m_fslt(WORD inst, WORD siz);
171 int m_fsnlt(WORD inst, WORD siz);
172 int m_fsle(WORD inst, WORD siz);
173 int m_fsnle(WORD inst, WORD siz);
174 int m_fsgl(WORD inst, WORD siz);
175 int m_fsngl(WORD inst, WORD siz);
176 int m_fsgle(WORD inst, WORD siz);
177 int m_fsngle(WORD inst, WORD siz);
178 int m_fsogt(WORD inst, WORD siz);
179 int m_fsule(WORD inst, WORD siz);
180 int m_fsoge(WORD inst, WORD siz);
181 int m_fsult(WORD inst, WORD siz);
182 int m_fsolt(WORD inst, WORD siz);
183 int m_fsuge(WORD inst, WORD siz);
184 int m_fsole(WORD inst, WORD siz);
185 int m_fsugt(WORD inst, WORD siz);
186 int m_fsogl(WORD inst, WORD siz);
187 int m_fsueq(WORD inst, WORD siz);
188 int m_fsor(WORD inst, WORD siz);
189 int m_fsun(WORD inst, WORD siz);
190 int m_fsf(WORD inst, WORD siz);
191 int m_fst(WORD inst, WORD siz);
192 int m_fssf(WORD inst, WORD siz);
193 int m_fsst(WORD inst, WORD siz);
194 int m_fsseq(WORD inst, WORD siz);
195 int m_fssne(WORD inst, WORD siz);
196 int m_fscale(WORD inst, WORD siz);
197 int m_fsdiv(WORD inst, WORD siz);
198 int m_fsfsqrt(WORD inst, WORD siz);
199 int m_fsfsub(WORD inst, WORD siz);
200 int m_fsgldiv(WORD inst, WORD siz);
201 int m_fsglmul(WORD inst, WORD siz);
202 int m_fsin(WORD inst, WORD siz);
203 int m_fsincos(WORD inst, WORD siz);
204 int m_fsinh(WORD inst, WORD siz);
205 int m_fsmove(WORD inst, WORD siz);
206 int m_fsmul(WORD inst, WORD siz);
207 int m_fsneg(WORD inst, WORD siz);
208 int m_fsqrt(WORD inst, WORD siz);
209 int m_fsub(WORD inst, WORD siz);
210 int m_ftan(WORD inst, WORD siz);
211 int m_ftanh(WORD inst, WORD siz);
212 int m_ftentox(WORD inst, WORD siz);
213 int m_ftst(WORD inst, WORD siz);
214 int m_ftwotox(WORD inst, WORD siz);
215 int m_ftrapeq(WORD inst, WORD siz);
216 int m_ftrapne(WORD inst, WORD siz);
217 int m_ftrapgt(WORD inst, WORD siz);
218 int m_ftrapngt(WORD inst, WORD siz);
219 int m_ftrapge(WORD inst, WORD siz);
220 int m_ftrapnge(WORD inst, WORD siz);
221 int m_ftraplt(WORD inst, WORD siz);
222 int m_ftrapnlt(WORD inst, WORD siz);
223 int m_ftraple(WORD inst, WORD siz);
224 int m_ftrapnle(WORD inst, WORD siz);
225 int m_ftrapgl(WORD inst, WORD siz);
226 int m_ftrapngl(WORD inst, WORD siz);
227 int m_ftrapgle(WORD inst, WORD siz);
228 int m_ftrapngle(WORD inst, WORD siz);
229 int m_ftrapogt(WORD inst, WORD siz);
230 int m_ftrapule(WORD inst, WORD siz);
231 int m_ftrapoge(WORD inst, WORD siz);
232 int m_ftrapult(WORD inst, WORD siz);
233 int m_ftrapolt(WORD inst, WORD siz);
234 int m_ftrapuge(WORD inst, WORD siz);
235 int m_ftrapole(WORD inst, WORD siz);
236 int m_ftrapugt(WORD inst, WORD siz);
237 int m_ftrapogl(WORD inst, WORD siz);
238 int m_ftrapueq(WORD inst, WORD siz);
239 int m_ftrapor(WORD inst, WORD siz);
240 int m_ftrapun(WORD inst, WORD siz);
241 int m_ftrapf(WORD inst, WORD siz);
242 int m_ftrapt(WORD inst, WORD siz);
243 int m_ftrapsf(WORD inst, WORD siz);
244 int m_ftrapst(WORD inst, WORD siz);
245 int m_ftrapseq(WORD inst, WORD siz);
246 int m_ftrapsne(WORD inst, WORD siz);
247 int m_ftrapeqn(WORD inst, WORD siz);
248 int m_ftrapnen(WORD inst, WORD siz);
249 int m_ftrapgtn(WORD inst, WORD siz);
250 int m_ftrapngtn(WORD inst, WORD siz);
251 int m_ftrapgen(WORD inst, WORD siz);
252 int m_ftrapngen(WORD inst, WORD siz);
253 int m_ftrapltn(WORD inst, WORD siz);
254 int m_ftrapnltn(WORD inst, WORD siz);
255 int m_ftraplen(WORD inst, WORD siz);
256 int m_ftrapnlen(WORD inst, WORD siz);
257 int m_ftrapgln(WORD inst, WORD siz);
258 int m_ftrapngln(WORD inst, WORD siz);
259 int m_ftrapglen(WORD inst, WORD siz);
260 int m_ftrapnglen(WORD inst, WORD siz);
261 int m_ftrapogtn(WORD inst, WORD siz);
262 int m_ftrapulen(WORD inst, WORD siz);
263 int m_ftrapogen(WORD inst, WORD siz);
264 int m_ftrapultn(WORD inst, WORD siz);
265 int m_ftrapoltn(WORD inst, WORD siz);
266 int m_ftrapugen(WORD inst, WORD siz);
267 int m_ftrapolen(WORD inst, WORD siz);
268 int m_ftrapugtn(WORD inst, WORD siz);
269 int m_ftrapogln(WORD inst, WORD siz);
270 int m_ftrapueqn(WORD inst, WORD siz);
271 int m_ftraporn(WORD inst, WORD siz);
272 int m_ftrapunn(WORD inst, WORD siz);
273 int m_ftrapfn(WORD inst, WORD siz);
274 int m_ftraptn(WORD inst, WORD siz);
275 int m_ftrapsfn(WORD inst, WORD siz);
276 int m_ftrapstn(WORD inst, WORD siz);
277 int m_ftrapseqn(WORD inst, WORD siz);
278 int m_ftrapsnen(WORD inst, WORD siz);
280 // Common error messages
281 char range_error[] = "expression out of range";
282 char abs_error[] = "illegal absolute expression";
283 char seg_error[] = "bad (section) expression";
284 char rel_error[] = "illegal relative address";
285 char siz_error[] = "bad size specified";
286 char undef_error[] = "undefined expression";
287 char fwd_error[] = "forward or undefined expression";
288 char unsupport[] = "unsupported for selected CPU";
290 // Include code tables
292 { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0
294 { 0, 0L, 0L, 0x0000, 0, m_unimp } // Last entry
297 // Register number << 9
299 0, 1 << 9, 2 << 9, 3 << 9, 4 << 9, 5 << 9, 6 << 9, 7 << 9
302 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
306 1<<6, (WORD)-1, // SIZW, n/a
307 2<<6, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
311 // Byte/word/long size for MOVE instrs
315 0x3000, (WORD)-1, // Word
316 0x2000, (WORD)-1, (WORD)-1, (WORD)-1, // Long
317 0x3000 // Word (SIZN)
320 // Word/long size (0=.w, 1=.l) in bit 8
324 0, (WORD)-1, // SIZW, n/a
325 1<<8, (WORD)-1, (WORD)-1, (WORD)-1, // SIZL, n/a, n/a, n/a
329 // Byte/Word/long size (0=.w, 1=.l) in bit 9
333 1<<9, (WORD)-1, // Word
334 1<<10, (WORD)-1, (WORD)-1, (WORD)-1, // Long
338 // Addressing mode in bits 6..11 (register/mode fields are reversed)
340 00000, 01000, 02000, 03000, 04000, 05000, 06000, 07000,
341 00100, 01100, 02100, 03100, 04100, 05100, 06100, 07100,
342 00200, 01200, 02200, 03200, 04200, 05200, 06200, 07200,
343 00300, 01300, 02300, 03300, 04300, 05300, 06300, 07300,
344 00400, 01400, 02400, 03400, 04400, 05400, 06400, 07400,
345 00500, 01500, 02500, 03500, 04500, 05500, 06500, 07500,
346 00600, 01600, 02600, 03600, 04600, 05600, 06600, 07600,
347 00700, 01700, 02700, 03700, 04700, 05700, 06700, 07700
350 // Control registers lookup table
352 // MC68010/MC68020/MC68030/MC68040/CPU32
353 0x000, // Source Function Code(SFC)
354 0x001, // Destination Function Code(DFC)
355 0x800, // User Stack Pointer(USP)
356 0x801, // Vector Base Register(VBR)
357 // MC68020 / MC68030 / MC68040
358 0x002, // Cache Control Register(CACR)
359 0x802, // Cache Address Register(CAAR) (020/030 only)
360 0x803, // Master Stack Pointer(MSP)
361 0x804, // Interrupt Stack Pointer(ISP)
362 // MC68040 / MC68LC040
363 0x003, // MMU Translation Control Register(TC)
364 0x004, // Instruction Transparent Translation Register 0 (ITT0)
365 0x005, // Instruction Transparent Translation Register 1 (ITT1)
366 0x006, // Data Transparent Translation Register 0 (DTT0)
367 0x007, // Data Transparent Translation Register 1 (DTT1)
368 0x805, // MMU Status Register(MMUSR)
369 0x806, // User Root Pointer(URP)
370 0x807, // Supervisor Root Pointer(SRP)
372 0x004, // Instruction Access Control Register 0 (IACR0)
373 0x005, // Instruction Access Control Register 1 (IACR1)
374 0x006, // Data Access Control Register 0 (DACR1)
375 0x007, // Data Access Control Register 1 (DACR1)
377 0xFFF // CPU Root Pointer (CRP) - There's no movec with CRP in it, this is just a guard entry
382 int m_unimp(WORD unused1, WORD unused2)
384 return (int)error("unimplemented mnemonic");
388 //int m_badmode(void)
389 int m_badmode(WORD unused1, WORD unused2)
391 return (int)error("inappropriate addressing mode");
395 int m_self(WORD inst, WORD usused)
403 // Do one EA in bits 0..5
405 // Bits in `inst' have the following meaning:
407 // Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits
410 // If bit one is set, the OTHER ea (the one that wasn't generated by bit zero)
411 // is generated after the instruction. Regardless of bit 0's value, ea0 is
412 // always deposited in memory before ea1.
414 // If bit two is set, standard size bits are set in the instr in bits 6 and 7.
416 // If bit four is set, bit three specifies which eaXreg to place in bits 9..11
419 int m_ea(WORD inst, WORD siz)
421 WORD flg = inst; // Save flag bits
422 inst &= ~0x3F; // Clobber flag bits in instr
424 // Install "standard" instr size bits
430 // OR-in register number
432 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
434 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
440 inst |= am1 | a1reg; // Get ea1 into instr
441 D_word(inst); // Deposit instr
443 // Generate ea0 if requested
447 ea1gen(siz); // Generate ea1
452 inst |= am0 | a0reg; // Get ea0 into instr
453 D_word(inst); // Deposit instr
454 ea0gen(siz); // Generate ea0
456 // Generate ea1 if requested
466 // Check if lea x(an),an can be optimised to addq.w #x,an--otherwise fall back
469 int m_lea(WORD inst, WORD siz)
471 if (CHECK_OPTS(OPT_LEA_ADDQ)
472 && ((am0 == ADISP) && (a0reg == a1reg) && (a0exattr & DEFINED))
473 && ((a0exval > 0) && (a0exval <= 8)))
475 inst = B16(01010000, 01001000) | ((a0exval & 7) << 9) | (a0reg);
477 warn("lea size(An),An converted to addq #size,An");
481 return m_ea(inst, siz);
485 int m_ea030(WORD inst, WORD siz)
488 WORD flg = inst; // Save flag bits
489 inst &= ~0x3F; // Clobber flag bits in instr
491 // Install "standard" instr size bits
497 // OR-in register number
500 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
504 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
511 inst |= am1 | a1reg; // Get ea1 into instr
512 D_word(inst); // Deposit instr
514 // Generate ea0 if requested
518 ea1gen(siz); // Generate ea1
524 // We get here if we're doing 020+ addressing and an address
525 // register is used. For example, something like "tst a0". A bit of
526 // a corner case, so kludge it
528 else if (am0 == PCDISP)
529 //Another corner case (possibly!), so kludge ahoy
530 inst |= am0; // Get ea0 into instr
531 else if (am0 == IMMED)
532 inst |= am0 | a0reg; // Get ea0 into instr
533 else if (am0 == AM_CCR)
535 else if (am0 == AIND)
538 inst |= a0reg; // Get ea0 into instr
539 D_word(inst); // Deposit instr
540 ea0gen(siz); // Generate ea0
542 // Generate ea1 if requested
552 // Dx,Dy nnnnXXXnssnnnYYY If bit 0 of `inst' is set, install size bits in bits
555 int m_abcd(WORD inst, WORD siz)
564 inst |= a0reg | reg_9[a1reg];
574 int m_adda(WORD inst, WORD siz)
576 inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
578 ea0gen(siz); // Generate EA
585 // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr.
586 // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr.
588 int m_reg(WORD inst, WORD siz)
595 // Install other register (9..11)
596 inst |= reg_9[a1reg];
598 inst &= ~7; // Clear off crufty bits
599 inst |= a0reg; // Install first register
609 int m_imm(WORD inst, WORD siz)
621 int m_imm8(WORD inst, WORD siz)
634 int m_shr(WORD inst, WORD siz)
636 inst |= reg_9[a0reg] | a1reg | siz_6[siz];
646 int m_shi(WORD inst, WORD siz)
648 inst |= a1reg | siz_6[siz];
650 if (a0exattr & DEFINED)
653 return error(range_error);
655 inst |= (a0exval & 7) << 9;
660 AddFixup(FU_QUICK, sloc, a0expr);
669 // {bset, btst, bchg, bclr} -- #immed,ea -- Dn,ea
671 int m_bitop(WORD inst, WORD siz)
673 // Enforce instruction sizes
675 { // X,Dn must be .n or .l
676 if (siz & (SIZB | SIZW))
677 return error(siz_error);
679 else if (siz & (SIZW | SIZL)) // X,ea must be .n or .b
680 return error(siz_error);
682 // Construct instr and EAs
688 ea0gen(SIZB); // Immediate bit number
692 inst |= reg_9[a0reg];
703 int m_dbra(WORD inst, WORD siz)
711 if (a1exattr & DEFINED)
713 if ((a1exattr & TDB) != cursect)
714 return error(rel_error);
718 if (v + 0x8000 > 0x10000)
719 return error(range_error);
725 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
736 int m_exg(WORD inst, WORD siz)
742 if (am0 == DREG && am1 == DREG)
744 else if (am0 == AREG && am1 == AREG)
750 m = a1reg; // Get AREG into a1reg
758 inst |= m | reg_9[a0reg] | a1reg;
768 int m_link(WORD inst, WORD siz)
772 // Is this an error condition???
777 inst &= ~((3 << 9) | (1 << 6) | (1 << 4));
789 WORD extra_addressing[16]=
792 0, //0101 ([bd,An],Xn,od)
793 0x180, //0102 ([bc,An,Xn],od) (111 110 110 111)
795 0, //0104 ([bd,PC],Xn,od)
796 0, //0105 ([bc,PC,Xn],od)
811 // Handle MOVE <C_ALL> <C_ALTDATA>
812 // MOVE <C_ALL> <M_AREG>
814 // Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
816 int m_move(WORD inst, WORD size)
818 // Cast the passed in value to an int
821 // Try to optimize to MOVEQ
822 if (CHECK_OPTS(OPT_MOVEL_MOVEQ)
823 && (siz == SIZL) && (am0 == IMMED) && (am1 == DREG)
824 && ((a0exattr & (TDB | DEFINED)) == DEFINED)
825 && (a0exval + 0x80 < 0x100))
827 m_moveq((WORD)0x7000, (WORD)0);
830 warn("move.l #size,dx converted to moveq");
834 if ((am0 < ABASE) && (am1 < ABASE)) //68000 modes
836 inst |= siz_12[siz] | am_6[am1] | reg_9[a1reg] | am0 | a0reg;
844 ea1gen((WORD)siz | 0x8000); // Tell ea1gen we're move ea,ea
848 inst |= siz_12[siz] | reg_9[a1reg] | extra_addressing[am0 - ABASE];
864 // Handle MOVE <C_ALL030> <C_ALTDATA>
865 // MOVE <C_ALL030> <M_AREG>
867 int m_move30(WORD inst, WORD size)
869 // Cast the passed in value to an int
871 inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
886 // move USP,An -- move An,USP
888 int m_usp(WORD inst, WORD siz)
893 inst |= a1reg; // USP, An
895 inst |= a0reg; // An, USP
906 int m_moveq(WORD inst, WORD siz)
910 // Arrange for future fixup
911 if (!(a0exattr & DEFINED))
913 AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
916 else if (a0exval + 0x100 >= 0x200)
917 return error(range_error);
919 inst |= reg_9[a1reg] | (a0exval & 0xFF);
927 // movep Dn, disp(An) -- movep disp(An), Dn
929 int m_movep(WORD inst, WORD siz)
931 // Tell ea0gen to lay off the 0(a0) optimisations on this one
939 inst |= reg_9[a0reg] | a1reg;
949 inst |= reg_9[a1reg] | a0reg;
966 int m_br(WORD inst, WORD siz)
970 if (a0exattr & DEFINED)
972 if ((a0exattr & TDB) != cursect)
974 //printf("m_br(): a0exattr = %X, cursect = %X, a0exval = %X, sloc = %X\n", a0exattr, cursect, a0exval, sloc);
975 return error(rel_error);
978 v = a0exval - (sloc + 2);
980 // Optimize branch instr. size
983 if (CHECK_OPTS(OPT_BSR_BCC_S) && (v != 0) && ((v + 0x80) < 0x100))
990 warn("Bcc.w/BSR.w converted to .s");
997 if ((v + 0x8000) > 0x10000)
998 return error(range_error);
1006 if (siz == SIZB || siz == SIZS)
1008 if ((v + 0x80) >= 0x100)
1009 return error(range_error);
1016 if ((v + 0x8000) >= 0x10000)
1017 return error(range_error);
1025 else if (siz == SIZN)
1028 if (siz == SIZB || siz == SIZS)
1031 AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
1039 AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
1050 int m_addq(WORD inst, WORD siz)
1052 inst |= siz_6[siz] | am1 | a1reg;
1054 if (a0exattr & DEFINED)
1056 if ((a0exval > 8) || (a0exval == 0)) // Range in 1..8
1057 return error(range_error);
1059 inst |= (a0exval & 7) << 9;
1064 AddFixup(FU_QUICK, sloc, a0expr);
1077 int m_trap(WORD inst, WORD siz)
1081 if (a0exattr & DEFINED)
1084 return error(abs_error);
1087 return error(range_error);
1093 return error(undef_error);
1100 // movem <rlist>,ea -- movem ea,<rlist>
1102 int m_movem(WORD inst, WORD siz)
1110 return error("bad size suffix");
1117 // Handle #<expr>, ea
1120 if (abs_expr(&eval) != OK)
1123 if (eval >= 0x10000L)
1124 return error(range_error);
1130 if ((*tok >= KW_D0) && (*tok <= KW_A7))
1133 if (reglist(&rmask) < 0)
1138 return error("missing comma");
1143 inst |= am0 | a0reg;
1145 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
1146 return error("invalid addressing mode");
1148 // If APREDEC, reverse register mask
1154 for(i=0x8000; i; i>>=1, w>>=1)
1155 rmask = (WORD)((rmask << 1) | w & 1);
1164 inst |= 0x0400 | am0 | a0reg;
1167 return error("missing comma");
1170 return error("missing register list");
1177 if (abs_expr(&eval) != OK)
1180 if (eval >= 0x10000)
1181 return error(range_error);
1185 else if (reglist(&rmask) < 0)
1188 if (!(amsktab[am0] & (C_CTRL | M_APOSTINC)))
1189 return error("invalid addressing mode");
1201 // CLR.x An ==> SUBA.x An,An
1203 int m_clra(WORD inst, WORD siz)
1205 inst |= a0reg | reg_9[a0reg] | lwsiz_8[siz];
1212 ////////////////////////////////////////
1214 // 68020/30/40 instructions
1216 ////////////////////////////////////////
1221 int m_br30(WORD inst, WORD siz)
1223 if (a0exattr & DEFINED)
1225 if ((a0exattr & TDB) != cursect)
1226 return error(rel_error);
1228 VALUE v = a0exval - (sloc + 2);
1237 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1245 // bfchg, bfclr, bfexts, bfextu, bfffo, bfins, bfset
1246 // (68020, 68030, 68040)
1248 int m_bfop(WORD inst, WORD siz)
1250 //TODO: is this needed or can we put that in the mask in 68ktab???
1251 if (am0 == AREG || am0== APOSTINC || am0 == APREDEC || am0 == IMMED|| am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE || am0 == PCBASE || am0 == PCMPOST || am0 == PCMPRE)
1252 return m_badmode(inst, siz);
1254 //First instruction word - just the opcode and first EA
1255 //Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
1259 D_word((inst|am0|a0reg|am1|a1reg));
1260 ea0gen(siz); // Generate EA
1262 //Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
1263 inst = bfparam1 | bfparam2;
1266 inst |= a1reg << 12;
1269 inst |= a0reg << 12;
1278 // bkpt (68EC000, 68010, 68020, 68030, 68040, CPU32)
1280 int m_bkpt(WORD inst, WORD siz)
1284 if (a0exattr & DEFINED)
1287 return error(abs_error);
1290 return error(range_error);
1296 return error(undef_error);
1305 int m_callm(WORD inst, WORD siz)
1312 if (a0exattr & DEFINED)
1315 return error(abs_error);
1318 return error(range_error);
1324 return error(undef_error);
1334 // cas (68020, 68030, 68040)
1336 int m_cas(WORD inst, WORD siz)
1342 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1343 return error(unsupport);
1358 return error("bad size suffix");
1363 if ((*tok < KW_D0) && (*tok > KW_D7))
1364 return error("CAS accepts only data registers");
1366 inst2 = (*tok++) & 7;
1369 return error("missing comma");
1372 if ((*tok < KW_D0) && (*tok > KW_D7))
1373 return error("CAS accepts only data registers");
1375 inst2 |= ((*tok++) & 7) << 6;
1378 return error("missing comma");
1381 if ((modes = amode(1)) < 0)
1385 return error("too many ea fields");
1388 return error("extra (unexpected) text found");
1390 // Reject invalud ea modes
1391 amsk = amsktab[am0];
1393 if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
1394 return error("unsupported addressing mode");
1396 inst |= am0 | a0reg;
1406 // cas2 (68020, 68030, 68040)
1408 int m_cas2(WORD inst, WORD siz)
1412 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1413 return error(unsupport);
1428 return error("bad size suffix");
1433 if ((*tok < KW_D0) && (*tok > KW_D7))
1434 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1436 inst2 = (*tok++) & 7;
1439 return error("missing colon");
1442 if ((*tok < KW_D0) && (*tok > KW_D7))
1443 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1445 inst3 = (*tok++) & 7;
1448 return error("missing comma");
1451 if ((*tok < KW_D0) && (*tok > KW_D7))
1452 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1454 inst2 |= ((*tok++) & 7) << 6;
1457 return error("missing colon");
1460 if ((*tok < KW_D0) && (*tok > KW_D7))
1461 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1463 inst3 |= ((*tok++) & 7) << 6;
1466 return error("missing comma");
1470 return error("missing (");
1471 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1472 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1473 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1474 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1476 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1479 return error("missing (");
1482 return error("missing colon");
1486 return error("missing (");
1487 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1488 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1489 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1490 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1492 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1495 return error("missing (");
1498 return error("extra (unexpected) text found");
1509 // cmp2 (68020, 68030, 68040, CPU32)
1511 int m_cmp2(WORD inst, WORD siz)
1513 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1514 return error(unsupport);
1516 switch (siz & 0x000F)
1530 WORD flg = inst; // Save flag bits
1531 inst &= ~0x3F; // Clobber flag bits in instr
1533 // Install "standard" instr size bits
1539 // OR-in register number
1541 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1543 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1549 inst |= am1 | a1reg; // Get ea1 into instr
1550 D_word(inst); // Deposit instr
1552 // Generate ea0 if requested
1556 ea1gen(siz); // Generate ea1
1561 inst |= am0 | a0reg; // Get ea0 into instr
1562 D_word(inst); // Deposit instr
1563 ea0gen(siz); // Generate ea0
1565 // Generate ea1 if requested
1570 // If we're called from chk2 then bit 11 of size will be set. This is just
1571 // a dumb mechanism to pass this, required by the extension word. (You might
1572 // have noticed the siz & 15 thing above!)
1573 inst = (a1reg << 12) | (siz & (1 << 11));
1585 // chk2 (68020, 68030, 68040, CPU32)
1587 int m_chk2(WORD inst, WORD siz)
1589 return m_cmp2(inst, siz | (1 << 11));
1594 // cpbcc(68020, 68030)
1596 int m_cpbr(WORD inst, WORD siz)
1598 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1599 return error(unsupport);
1601 if (a0exattr & DEFINED)
1603 if ((a0exattr & TDB) != cursect)
1604 return error(rel_error);
1606 VALUE v = a0exval - (sloc + 2);
1608 // Optimize branch instr. size
1611 if ((v != 0) && ((v + 0x8000) < 0x10000))
1621 if ((v + 0x8000) >= 0x10000)
1622 return error(range_error);
1630 else if (siz == SIZN)
1637 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1645 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1654 // cpdbcc(68020, 68030)
1656 int m_cpdbr(WORD inst, WORD siz)
1658 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1659 return error(unsupport);
1661 return error("Not implemented yet.");
1670 int m_divs(WORD inst, WORD siz)
1672 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1673 return error(unsupport);
1675 WORD flg = inst; // Save flag bits
1676 inst &= ~0x3F; // Clobber flag bits in instr
1678 // Install "standard" instr size bits
1684 // OR-in register number
1686 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1688 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1694 inst |= am1 | a1reg; // Get ea1 into instr
1695 D_word(inst); // Deposit instr
1697 // Generate ea0 if requested
1701 ea1gen(siz); // Generate ea1
1706 inst |= am0 | a0reg; // Get ea0 into instr
1707 D_word(inst); // Deposit instr
1708 ea0gen(siz); // Generate ea0
1710 // Generate ea1 if requested
1715 inst = a1reg + (a2reg << 12) + (1 << 11);
1725 int m_muls(WORD inst, WORD siz)
1727 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1728 return error(unsupport);
1730 WORD flg = inst; // Save flag bits
1731 inst &= ~0x3F; // Clobber flag bits in instr
1733 // Install "standard" instr size bits
1739 // OR-in register number
1741 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1743 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1749 inst |= am1 | a1reg; // Get ea1 into instr
1750 D_word(inst); // Deposit instr
1753 inst = a1reg + (a2reg << 12) + (1 << 11);
1754 inst |= mulmode; // add size bit
1757 // Generate ea0 if requested
1761 ea1gen(siz); // Generate ea1
1766 inst |= am0 | a0reg; // Get ea0 into instr
1767 D_word(inst); // Deposit instr
1769 inst = a1reg + (a2reg << 12) + (1 << 11);
1770 inst |= mulmode; // add size bit
1773 ea0gen(siz); // Generate ea0
1775 // Generate ea1 if requested
1790 int m_divu(WORD inst, WORD siz)
1792 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1793 return error(unsupport);
1795 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1797 WORD flg = inst; // Save flag bits
1798 inst &= ~0x3F; // Clobber flag bits in instr
1800 // Install "standard" instr size bits
1806 // OR-in register number
1808 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1810 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1816 inst |= am1 | a1reg; // Get ea1 into instr
1817 D_word(inst); // Deposit instr
1819 // Generate ea0 if requested
1823 ea1gen(siz); // Generate ea1
1828 inst |= am0 | a0reg; // Get ea0 into instr
1829 D_word(inst); // Deposit instr
1830 ea0gen(siz); // Generate ea0
1832 // Generate ea1 if requested
1837 inst = a1reg + (a2reg << 12);
1847 int m_mulu(WORD inst, WORD siz)
1849 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1850 return error(unsupport);
1852 WORD flg = inst; // Save flag bits
1853 inst &= ~0x3F; // Clobber flag bits in instr
1855 // Install "standard" instr size bits
1861 // OR-in register number
1863 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1865 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1871 inst |= am1 | a1reg; // Get ea1 into instr
1872 D_word(inst); // Deposit instr
1874 // Generate ea0 if requested
1878 ea1gen(siz); // Generate ea1
1883 inst |= am0 | a0reg; // Get ea0 into instr
1884 D_word(inst); // Deposit instr
1885 ea0gen(siz); // Generate ea0
1887 // Generate ea1 if requested
1892 inst = a1reg + (a2reg << 12);
1893 inst |= mulmode; // add size bit
1903 int m_divsl(WORD inst, WORD siz)
1905 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1906 return error(unsupport);
1908 WORD flg = inst; // Save flag bits
1909 inst &= ~0x3F; // Clobber flag bits in instr
1911 // Install "standard" instr size bits
1917 // OR-in register number
1919 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1921 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1927 inst |= am1 | a1reg; // Get ea1 into instr
1928 D_word(inst); // Deposit instr
1930 // Generate ea0 if requested
1934 ea1gen(siz); // Generate ea1
1939 inst |= am0 | a0reg; // Get ea0 into instr
1940 D_word(inst); // Deposit instr
1941 ea0gen(siz); // Generate ea0
1943 // Generate ea1 if requested
1948 inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
1957 int m_divul(WORD inst, WORD siz)
1959 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1960 return error(unsupport);
1962 WORD flg = inst; // Save flag bits
1963 inst &= ~0x3F; // Clobber flag bits in instr
1965 // Install "standard" instr size bits
1971 // OR-in register number
1973 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1975 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1981 inst |= am1 | a1reg; // Get ea1 into instr
1982 D_word(inst); // Deposit instr
1984 // Generate ea0 if requested
1988 ea1gen(siz); // Generate ea1
1993 inst |= am0 | a0reg; // Get ea0 into instr
1994 D_word(inst); // Deposit instr
1995 ea0gen(siz); // Generate ea0
1997 // Generate ea1 if requested
2002 inst = a1reg + (a2reg << 12) + (1 << 10);
2010 // move16 (ax)+,(ay)+
2012 int m_move16a(WORD inst, WORD siz)
2014 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2015 return error(unsupport);
2019 inst = (1 << 15) + (a1reg << 12);
2027 // move16 with absolute address
2029 int m_move16b(WORD inst, WORD siz)
2031 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2032 return error(unsupport);
2038 if (am0 == APOSTINC)
2041 return error("Wasn't this suppose to call m_move16a???");
2044 //move16 (ax)+,(xxx).L
2049 else if (am0 == ABSL)
2053 //move16 (xxx).L,(ax)+
2059 //move16 (xxx).L,(ax)
2064 else if (am0 == AIND)
2066 //move16 (ax),(xxx).L
2081 int m_pack(WORD inst, WORD siz)
2083 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
2084 return error(unsupport);
2086 WARNING(Parsing stuff by hand here might be better)
2089 if ((am0 == DREG) && (am1 == DREG))
2091 inst |= (1 << 3) + (a0reg << 9) + (a1reg);
2093 else if ((am0 == APREDEC) && (am1 == APREDEC))
2095 inst |= (a0reg << 9) + (a1reg);
2098 return error("Only allowed combinations for pack/unpack are -(ax),-(ay) and dx,dy.");
2110 int m_rtm(WORD inst, WORD siz)
2118 else if (am0 == AREG)
2120 inst |= (1 << 3) + a0reg;
2123 return error("rtm only allows data or address registers.");
2134 int m_rtd(WORD inst, WORD siz)
2138 if (a0exattr & DEFINED)
2141 return error(abs_error);
2143 if ((a0exval + 0x8000) <= 0x7FFF)
2144 return error(range_error);
2150 return error(undef_error);
2159 int m_trapcc(WORD inst, WORD siz)
2167 else if (am0 == IMMED)
2171 if (a0exval < 0x10000)
2178 return error("Immediate value too big");
2188 return error("Invalid parameter for trapcc");
2197 int m_cinv(WORD inst, WORD siz)
2200 WARNING("cinvl ,(an) / cinvp ,(an) / cinva should work!")
2203 inst |= (0 << 6) | (a1reg);
2204 else if (am0 == KW_IC40)
2205 inst |= (2 << 6) | (a1reg);
2206 else if (am0 == KW_DC40)
2207 inst |= (1 << 6) | (a1reg);
2208 else if (am0 == KW_BC40)
2209 inst |= (3 << 6) | (a1reg);
2217 // cpRESTORE (68020, 68030)
2219 int m_cprest(WORD inst, WORD siz)
2221 if (activecpu & !(CPU_68020 | CPU_68030))
2222 return error(unsupport);
2224 inst |= am0 | a0reg;
2233 // movec (68010, 68020, 68030, 68040, CPU32)
2235 int m_movec(WORD inst, WORD siz)
2239 if (am0 == DREG || am0 == AREG)
2247 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
2252 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
2263 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
2268 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2278 // moves (68010, 68020, 68030, 68040, CPU32)
2280 int m_moves(WORD inst, WORD siz)
2282 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2283 return error(unsupport);
2289 else if (siz == SIZL)
2300 inst |= am1 | a1reg;
2302 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2305 else if (am0 == AREG)
2307 inst |= am1 | a1reg;
2309 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2316 inst |= am0 | a0reg;
2318 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2323 inst |= am0 | a0reg;
2325 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2337 int m_pbcc(WORD inst, WORD siz)
2340 return error("Not implemented yet.");
2347 int m_pflusha(WORD inst, WORD siz)
2352 inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
2359 // pflush (68030, 68040, 68060)
2361 int m_pflush(WORD inst, WORD siz)
2363 if (activecpu == CPU_68030)
2366 D_word((1 << 13) | (1 << 10) | (0 << 5) | 0);
2368 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2373 return error(unsupport);
2382 int m_pflushr(WORD inst, WORD siz)
2386 WORD flg = inst; // Save flag bits
2387 inst &= ~0x3F; // Clobber flag bits in instr
2389 // Install "standard" instr size bits
2395 // OR-in register number
2397 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2399 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2405 inst |= am1 | a1reg; // Get ea1 into instr
2406 D_word(inst); // Deposit instr
2408 // Generate ea0 if requested
2412 ea1gen(siz); // Generate ea1
2417 inst |= am0 | a0reg; // Get ea0 into instr
2418 D_word(inst); // Deposit instr
2419 ea0gen(siz); // Generate ea0
2421 // Generate ea1 if requested
2426 D_word(B16(10100000, 00000000));
2432 // ploadr, ploadw (68030)
2434 int m_pload(WORD inst, WORD siz)
2437 return error("Not implemented yet.");
2444 int m_pmove(WORD inst, WORD siz)
2450 inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2451 inst &= ~(1 << 8); //And mask it out
2458 else if (am1 == CREG)
2464 return error("pmove sez: Wut?");
2466 if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
2467 && ((siz != SIZD) && (siz != SIZN)))
2468 return error(siz_error);
2470 if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
2471 && ((siz != SIZL) && (siz != SIZN)))
2472 return error(siz_error);
2474 if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
2475 return error(siz_error);
2477 WARNING(Not all addressing modes are legal here!)
2485 else if (am1 == CREG)
2494 case (KW_URP - KW_SFC):
2495 inst2 |= (3 << 10) + (2 << 13); break;
2496 case (KW_SRP - KW_SFC):
2497 inst2 |= (2 << 10) + (2 << 13); break;
2498 case (KW_TC - KW_SFC):
2499 inst2 |= (0 << 10) + (2 << 13); break;
2500 case (KW_TT0 - KW_SFC):
2501 inst2 |= (2 << 10) + (0 << 13); break;
2502 case (KW_TT1 - KW_SFC):
2503 inst2 |= (3 << 10) + (0 << 13); break;
2504 case (KW_MMUSR - KW_SFC):
2505 inst2 |= (3 << 10) + (3 << 13); break;
2506 case (KW_CRP - KW_SFC) : //68851 only
2507 inst2 |= (3 << 10) + (2 << 13); break;
2519 int m_pmovefd(WORD inst, WORD siz)
2523 return m_pmove(inst | (1 << 8), siz);
2530 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; }
2531 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; }
2532 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; }
2533 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; }
2534 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; }
2535 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; }
2536 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; }
2537 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; }
2538 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; }
2539 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; }
2540 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; }
2541 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; }
2542 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; }
2543 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; }
2544 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; }
2545 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; }
2546 int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2547 int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2548 int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2549 int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2550 int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2551 int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2552 int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2553 int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2554 int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2555 int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2556 int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2557 int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2558 int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2559 int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2560 int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2561 int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2565 // ptestr, ptestw (68030)
2567 int m_ptest(WORD inst, WORD siz)
2571 if (activecpu == CPU_68030)
2572 return error("Not implemented yet.");
2573 else if (activecpu == CPU_68040)
2574 return error("Not implemented yet.");
2580 #define FPU_NOWARN 0
2581 #define FPU_P_EMUL 1
2582 #define FPU_P2_EMU 2
2587 // Generate a FPU opcode
2589 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2591 if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
2593 inst |= (1 << 9); // Bolt on FPU id
2600 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2604 case SIZB: inst |= (6 << 10); break;
2605 case SIZW: inst |= (4 << 10); break;
2606 case SIZL: inst |= (0 << 10); break;
2608 case SIZS: inst |= (1 << 10); break;
2609 case SIZD: inst |= (5 << 10); break;
2610 case SIZX: inst |= (2 << 10); break;
2615 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2619 return error("Something bad happened, possibly, in gen_fpu.");
2623 inst |= (a1reg << 7);
2630 inst |= (1 << 9); //Bolt on FPU id
2634 inst |= (a1reg << 7);
2639 if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
2640 warn("Instruction is emulated in 68040");
2647 // fabs, fsabs, fdabs (6888X, 68040)
2649 int m_fabs(WORD inst, WORD siz)
2651 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2655 int m_fsabs(WORD inst, WORD siz)
2657 if (activefpu == FPU_68040)
2658 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2660 return error("Unsupported in current FPU");
2664 int m_fdabs(WORD inst, WORD siz)
2666 if (activefpu == FPU_68040)
2667 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2669 return error("Unsupported in current FPU");
2674 // facos (6888X, 68040FPSP)
2676 int m_facos(WORD inst, WORD siz)
2678 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
2683 // fadd (6888X, 68040FPSP)
2685 int m_fadd(WORD inst, WORD siz)
2687 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
2691 int m_fsadd(WORD inst, WORD siz)
2693 if (activefpu == FPU_68040)
2694 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
2696 return error("Unsupported in current FPU");
2700 int m_fdadd(WORD inst, WORD siz)
2702 if (activefpu == FPU_68040)
2703 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
2705 return error("Unsupported in current FPU");
2710 // fasin (6888X, 68040FPSP)f
2712 int m_fasin(WORD inst, WORD siz)
2714 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
2719 // fatan (6888X, 68040FPSP)
2721 int m_fatan(WORD inst, WORD siz)
2723 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
2728 // fatanh (6888X, 68040FPSP)
2730 int m_fatanh(WORD inst, WORD siz)
2732 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
2737 // fcmp (6888X, 68040)
2739 int m_fcmp(WORD inst, WORD siz)
2741 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
2746 // fcos (6888X, 68040FPSP)
2748 int m_fcos(WORD inst, WORD siz)
2750 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
2755 // fcosh (6888X, 68040FPSP)
2757 int m_fcosh(WORD inst, WORD siz)
2759 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
2764 // fdbcc (6888X, 68040)
2766 int m_fdbcc(WORD inst, WORD siz)
2768 WORD opcode = inst & 0x3F; //Grab conditional bitfield
2778 if (a1exattr & DEFINED)
2780 if ((a1exattr & TDB) != cursect)
2781 return error(rel_error);
2783 VALUE v = a1exval - sloc;
2785 if ((v + 0x8000) > 0x10000)
2786 return error(range_error);
2792 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
2801 // fdiv (6888X, 68040)
2803 int m_fdiv(WORD inst, WORD siz)
2805 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
2809 int m_fsdiv(WORD inst, WORD siz)
2811 if (activefpu == FPU_68040)
2812 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
2814 return error("Unsupported in current FPU");
2818 int m_fddiv(WORD inst, WORD siz)
2820 if (activefpu == FPU_68040)
2821 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
2823 return error("Unsupported in current FPU");
2828 // fetox (6888X, 68040FPSP)
2830 int m_fetox(WORD inst, WORD siz)
2832 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
2837 // fetoxm1 (6888X, 68040FPSP)
2839 int m_fetoxm1(WORD inst, WORD siz)
2841 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
2846 // fgetexp (6888X, 68040FPSP)
2848 int m_fgetexp(WORD inst, WORD siz)
2850 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
2855 // fgetman (6888X, 68040FPSP)
2857 int m_fgetman(WORD inst, WORD siz)
2859 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
2864 // fint (6888X, 68040FPSP)
2866 int m_fint(WORD inst, WORD siz)
2869 // special case - fint fpx = fint fpx,fpx
2872 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
2877 // fintrz (6888X, 68040FPSP)
2879 int m_fintrz(WORD inst, WORD siz)
2882 // special case - fintrz fpx = fintrz fpx,fpx
2885 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
2890 // flog10 (6888X, 68040FPSP)
2892 int m_flog10(WORD inst, WORD siz)
2894 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
2899 // flog2 (6888X, 68040FPSP)
2901 int m_flog2(WORD inst, WORD siz)
2903 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
2908 // flogn (6888X, 68040FPSP)
2910 int m_flogn(WORD inst, WORD siz)
2912 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
2917 // flognp1 (6888X, 68040FPSP)
2919 int m_flognp1(WORD inst, WORD siz)
2921 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
2926 // fmod (6888X, 68040FPSP)
2928 int m_fmod(WORD inst, WORD siz)
2930 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
2935 // fmove (6888X, 68040)
2937 int m_fmove(WORD inst, WORD siz)
2941 if ((am0 == FREG) && (am1 < AM_USP))
2945 inst |= am1 | a1reg;
2951 WARNING("K-factor logic is totally bogus - fix!")
2956 case SIZB: inst |= (6 << 10); break;
2957 case SIZW: inst |= (4 << 10); break;
2958 case SIZL: inst |= (0 << 10); break;
2960 case SIZS: inst |= (1 << 10); break;
2961 case SIZD: inst |= (5 << 10); break;
2962 case SIZX: inst |= (2 << 10); break;
2963 case SIZP: inst |= (3 << 10);
2967 inst |= (bfparam1 & 0x7FF) >> 2;
2970 return error("Something bad happened, possibly.");
2974 // Immediate {} value
2975 if (bf0exval >= (1 << 6))
2976 return error("K-factor must be between 0 and 31");
2978 if (!bfparam1 && (siz == SIZP))
2981 // Destination specifier
2982 inst |= (a0reg << 7);
2990 else if ((am0 < AM_USP) && (am1 == FREG))
2995 inst |= am0 | a0reg;
3004 case SIZB: inst |= (6 << 10); break;
3005 case SIZW: inst |= (4 << 10); break;
3006 case SIZL: inst |= (0 << 10); break;
3008 case SIZS: inst |= (1 << 10); break;
3009 case SIZD: inst |= (5 << 10); break;
3010 case SIZX: inst |= (2 << 10); break;
3011 case SIZP: inst |= (3 << 10); break;
3013 return error("Something bad happened, possibly.");
3017 // Destination specifier
3018 inst |= (a1reg << 7);
3026 else if ((am0 == FREG) && (am1 == FREG))
3028 // register-to-register
3029 // Essentially ea to register with R/0=0
3039 return error("Invalid size");
3042 inst |= (a0reg << 10);
3044 // Destination register
3045 inst |= (a1reg << 7);
3055 // fmove (6888X, 68040)
3057 int m_fmovescr(WORD inst, WORD siz)
3059 // Move Floating-Point System Control Register (FPCR)
3063 if ((am0 == FPSCR) && (am1 < AM_USP))
3065 inst |= am1 | a1reg;
3067 inst = (1 << 13) + (1 << 15);
3073 else if ((am1 == FPSCR) && (am0 < AM_USP))
3075 inst |= am0 | a0reg;
3077 inst = (0 << 13) + (1 << 15);
3084 return error("m_fmovescr says: wut?");
3089 // fsmove/fdmove (68040)
3091 int m_fsmove(WORD inst, WORD siz)
3093 return error("Not implemented yet.");
3096 if (activefpu == FPU_68040)
3097 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3099 return error("Unsupported in current FPU");
3104 int m_fdmove(WORD inst, WORD siz)
3106 return error("Not implemented yet.");
3109 if (activefpu == FPU_68040)
3110 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3112 return error("Unsupported in current FPU");
3118 // fmovecr (6888X, 68040FPSP)
3120 int m_fmovecr(WORD inst, WORD siz)
3128 if (activefpu == FPU_68040)
3129 warn("Instruction is emulated in 68040");
3136 // fmovem (6888X, 68040)
3138 int m_fmovem(WORD inst, WORD siz)
3143 if (siz == SIZX || siz==SIZN)
3145 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3147 //fmovem.x <rlist>,ea
3148 if (fpu_reglist_left(®mask) < 0)
3152 return error("missing comma");
3157 inst |= am0 | a0reg;
3159 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3160 return error("invalid addressing mode");
3163 inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
3168 else if ((*tok >= KW_D0) && (*tok <= KW_D7))
3171 datareg = (*tok++ & 7) << 10;
3174 return error("missing comma");
3179 inst |= am0 | a0reg;
3181 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3182 return error("invalid addressing mode");
3185 inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
3196 inst |= am0 | a0reg;
3199 return error("missing comma");
3201 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3203 //fmovem.x ea,<rlist>
3204 if (fpu_reglist_right(®mask) < 0)
3208 inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
3216 datareg = (*tok++ & 7) << 10;
3218 inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
3225 else if (siz == SIZL)
3227 if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
3229 //fmovem.l <rlist>,ea
3230 regmask = (1 << 15) | (1 << 13);
3232 if (*tok == KW_FPCR)
3234 regmask |= (1 << 12);
3239 if (*tok == KW_FPSR)
3241 regmask |= (1 << 11);
3246 if (*tok == KW_FPIAR)
3248 regmask |= (1 << 10);
3253 if ((*tok == '/') || (*tok == '-'))
3260 return error("missing comma");
3265 inst |= am0 | a0reg;
3272 //fmovem.l ea,<rlist>
3276 inst |= am0 | a0reg;
3279 return error("missing comma");
3281 regmask = (1 << 15) | (0 << 13);
3284 if (*tok == KW_FPCR)
3286 regmask |= (1 << 12);
3291 if (*tok == KW_FPSR)
3293 regmask |= (1 << 11);
3298 if (*tok == KW_FPIAR)
3300 regmask |= (1 << 10);
3305 if ((*tok == '/') || (*tok == '-'))
3312 return error("extra (unexpected) text found");
3314 inst |= am0 | a0reg;
3321 return error("bad size suffix");
3328 // fmul (6888X, 68040)
3330 int m_fmul(WORD inst, WORD siz)
3332 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
3336 int m_fsmul(WORD inst, WORD siz)
3338 if (activefpu == FPU_68040)
3339 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
3341 return error("Unsupported in current FPU");
3345 int m_fdmul(WORD inst, WORD siz)
3347 if (activefpu == FPU_68040)
3348 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
3350 return error("Unsupported in current FPU");
3355 // fneg (6888X, 68040)
3357 int m_fneg(WORD inst, WORD siz)
3359 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
3363 int m_fsneg(WORD inst, WORD siz)
3365 if (activefpu == FPU_68040)
3366 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
3368 return error("Unsupported in current FPU");
3372 int m_fdneg(WORD inst, WORD siz)
3374 if (activefpu == FPU_68040)
3375 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
3377 return error("Unsupported in current FPU");
3382 // fnop (6888X, 68040)
3384 int m_fnop(WORD inst, WORD siz)
3386 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3391 // frem (6888X, 68040FPSP)
3393 int m_frem(WORD inst, WORD siz)
3395 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3400 // fscale (6888X, 68040FPSP)
3402 int m_fscale(WORD inst, WORD siz)
3404 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3409 // FScc (6888X, 68040)
3411 int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3412 int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3413 int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3414 int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3415 int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3416 int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3417 int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3418 int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3419 int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3420 int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3421 int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3422 int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3423 int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3424 int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3425 int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3426 int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3427 int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3428 int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3429 int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3430 int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3431 int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3432 int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3433 int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3434 int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3435 int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3436 int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3437 int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3438 int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3439 int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3440 int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3441 int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3442 int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3446 // FTRAPcc (6888X, 68040)
3448 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;}
3449 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;}
3450 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;}
3451 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;}
3452 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;}
3453 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;}
3454 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;}
3455 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;}
3456 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;}
3457 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;}
3458 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;}
3459 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;}
3460 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;}
3461 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;}
3462 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;}
3463 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;}
3464 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;}
3465 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;}
3466 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;}
3467 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;}
3468 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;}
3469 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;}
3470 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;}
3471 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;}
3472 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;}
3473 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;}
3474 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;}
3475 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;}
3476 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;}
3477 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;}
3478 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;}
3479 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;}
3481 int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3482 int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3483 int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3484 int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3485 int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3486 int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3487 int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3488 int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3489 int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3490 int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3491 int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3492 int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3493 int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3494 int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3495 int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3496 int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3497 int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3498 int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3499 int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3500 int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3501 int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3502 int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3503 int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3504 int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3505 int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3506 int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3507 int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3508 int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3509 int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3510 int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3511 int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3512 int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3516 // fsgldiv (6888X, 68040)
3518 int m_fsgldiv(WORD inst, WORD siz)
3520 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3525 // fsglmul (6888X, 68040)
3527 int m_fsglmul(WORD inst, WORD siz)
3529 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3534 // fsin (6888X, 68040FPSP)
3536 int m_fsin(WORD inst, WORD siz)
3538 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3543 // fsincos (6888X, 68040FPSP)
3545 int m_fsincos(WORD inst, WORD siz)
3547 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
3558 // fsin (6888X, 68040FPSP)
3560 int m_fsinh(WORD inst, WORD siz)
3562 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3567 // fsqrt (6888X, 68040)
3569 int m_fsqrt(WORD inst, WORD siz)
3571 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3575 int m_fsfsqrt(WORD inst, WORD siz)
3577 if (activefpu == FPU_68040)
3578 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
3580 return error("Unsupported in current FPU");
3584 int m_fdfsqrt(WORD inst, WORD siz)
3586 if (activefpu == FPU_68040)
3587 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
3589 return error("Unsupported in current FPU");
3594 // fsub (6888X, 68040)
3596 int m_fsub(WORD inst, WORD siz)
3598 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
3602 int m_fsfsub(WORD inst, WORD siz)
3604 if (activefpu == FPU_68040)
3605 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
3607 return error("Unsupported in current FPU");
3611 int m_fdsub(WORD inst, WORD siz)
3613 if (activefpu == FPU_68040)
3614 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
3616 return error("Unsupported in current FPU");
3621 // ftan (6888X, 68040FPSP)
3623 int m_ftan(WORD inst, WORD siz)
3625 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
3630 // ftanh (6888X, 68040FPSP)
3632 int m_ftanh(WORD inst, WORD siz)
3634 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
3639 // ftentox (6888X, 68040FPSP)
3641 int m_ftentox(WORD inst, WORD siz)
3643 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
3648 // ftst (6888X, 68040)
3650 int m_ftst(WORD inst, WORD siz)
3652 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
3657 // ftwotox (6888X, 68040FPSP)
3659 int m_ftwotox(WORD inst, WORD siz)
3661 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);