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)
1414 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1415 return error(unsupport);
1430 return error("bad size suffix");
1435 if ((*tok < KW_D0) && (*tok > KW_D7))
1436 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1438 inst2 = (*tok++) & 7;
1441 return error("missing colon");
1444 if ((*tok < KW_D0) && (*tok > KW_D7))
1445 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1447 inst3 = (*tok++) & 7;
1450 return error("missing comma");
1453 if ((*tok < KW_D0) && (*tok > KW_D7))
1454 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1456 inst2 |= ((*tok++) & 7) << 6;
1459 return error("missing colon");
1462 if ((*tok < KW_D0) && (*tok > KW_D7))
1463 return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
1465 inst3 |= ((*tok++) & 7) << 6;
1468 return error("missing comma");
1472 return error("missing (");
1473 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1474 inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
1475 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1476 inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
1478 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1481 return error("missing (");
1484 return error("missing colon");
1488 return error("missing (");
1489 if ((*tok >= KW_D0) && (*tok <= KW_D7))
1490 inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
1491 else if ((*tok >= KW_A0) && (*tok <= KW_A7))
1492 inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
1494 return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
1497 return error("missing (");
1500 return error("extra (unexpected) text found");
1511 // cmp2 (68020, 68030, 68040, CPU32)
1513 int m_cmp2(WORD inst, WORD siz)
1515 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1516 return error(unsupport);
1518 switch (siz & 0x000F)
1532 WORD flg = inst; // Save flag bits
1533 inst &= ~0x3F; // Clobber flag bits in instr
1535 // Install "standard" instr size bits
1541 // OR-in register number
1543 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1545 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1551 inst |= am1 | a1reg; // Get ea1 into instr
1552 D_word(inst); // Deposit instr
1554 // Generate ea0 if requested
1558 ea1gen(siz); // Generate ea1
1563 inst |= am0 | a0reg; // Get ea0 into instr
1564 D_word(inst); // Deposit instr
1565 ea0gen(siz); // Generate ea0
1567 // Generate ea1 if requested
1572 // If we're called from chk2 then bit 11 of size will be set. This is just
1573 // a dumb mechanism to pass this, required by the extension word. (You might
1574 // have noticed the siz & 15 thing above!)
1575 inst = (a1reg << 12) | (siz & (1 << 11));
1587 // chk2 (68020, 68030, 68040, CPU32)
1589 int m_chk2(WORD inst, WORD siz)
1591 return m_cmp2(inst, siz | (1 << 11));
1596 // cpbcc(68020, 68030)
1598 int m_cpbr(WORD inst, WORD siz)
1600 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1601 return error(unsupport);
1603 if (a0exattr & DEFINED)
1605 if ((a0exattr & TDB) != cursect)
1606 return error(rel_error);
1608 VALUE v = a0exval - (sloc + 2);
1610 // Optimize branch instr. size
1613 if ((v != 0) && ((v + 0x8000) < 0x10000))
1617 WARNING(check what s "optional coprocessor-defined extension words!")
1624 if ((v + 0x8000) >= 0x10000)
1625 return error(range_error);
1628 WARNING(check what s "optional coprocessor-defined extension words!")
1634 else if (siz == SIZN)
1641 AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
1649 AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
1658 // cpdbcc(68020, 68030)
1660 int m_cpdbr(WORD inst, WORD siz)
1662 if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
1663 return error(unsupport);
1665 return error("Not implemented yet.");
1674 int m_divs(WORD inst, WORD siz)
1676 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1677 return error(unsupport);
1679 WORD flg = inst; // Save flag bits
1680 inst &= ~0x3F; // Clobber flag bits in instr
1682 // Install "standard" instr size bits
1688 // OR-in register number
1690 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1692 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1698 inst |= am1 | a1reg; // Get ea1 into instr
1699 D_word(inst); // Deposit instr
1701 // Generate ea0 if requested
1705 ea1gen(siz); // Generate ea1
1710 inst |= am0 | a0reg; // Get ea0 into instr
1711 D_word(inst); // Deposit instr
1712 ea0gen(siz); // Generate ea0
1714 // Generate ea1 if requested
1719 inst = a1reg + (a2reg << 12) + (1 << 11);
1729 int m_muls(WORD inst, WORD siz)
1731 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1732 return error(unsupport);
1734 WORD flg = inst; // Save flag bits
1735 inst &= ~0x3F; // Clobber flag bits in instr
1737 // Install "standard" instr size bits
1743 // OR-in register number
1745 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1747 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1753 inst |= am1 | a1reg; // Get ea1 into instr
1754 D_word(inst); // Deposit instr
1756 // Generate ea0 if requested
1760 ea1gen(siz); // Generate ea1
1765 inst |= am0 | a0reg; // Get ea0 into instr
1766 D_word(inst); // Deposit instr
1767 ea0gen(siz); // Generate ea0
1769 // Generate ea1 if requested
1774 inst = a1reg + (a2reg << 12) + (1 << 11);
1775 inst |= mulmode; // add size bit
1785 int m_divu(WORD inst, WORD siz)
1787 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1788 return error(unsupport);
1790 //WARNING("divu.l d0,d1 is actually divul.l d0,d1:d1!!!")
1792 WORD flg = inst; // Save flag bits
1793 inst &= ~0x3F; // Clobber flag bits in instr
1795 // Install "standard" instr size bits
1801 // OR-in register number
1803 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1805 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1811 inst |= am1 | a1reg; // Get ea1 into instr
1812 D_word(inst); // Deposit instr
1814 // Generate ea0 if requested
1818 ea1gen(siz); // Generate ea1
1823 inst |= am0 | a0reg; // Get ea0 into instr
1824 D_word(inst); // Deposit instr
1825 ea0gen(siz); // Generate ea0
1827 // Generate ea1 if requested
1832 inst = a1reg + (a2reg << 12);
1842 int m_mulu(WORD inst, WORD siz)
1844 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1845 return error(unsupport);
1847 WORD flg = inst; // Save flag bits
1848 inst &= ~0x3F; // Clobber flag bits in instr
1850 // Install "standard" instr size bits
1856 // OR-in register number
1858 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1860 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1866 inst |= am1 | a1reg; // Get ea1 into instr
1867 D_word(inst); // Deposit instr
1869 // Generate ea0 if requested
1873 ea1gen(siz); // Generate ea1
1878 inst |= am0 | a0reg; // Get ea0 into instr
1879 D_word(inst); // Deposit instr
1880 ea0gen(siz); // Generate ea0
1882 // Generate ea1 if requested
1887 inst = a1reg + (a2reg << 12);
1888 inst |= mulmode; // add size bit
1898 int m_divsl(WORD inst, WORD siz)
1900 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1901 return error(unsupport);
1903 WORD flg = inst; // Save flag bits
1904 inst &= ~0x3F; // Clobber flag bits in instr
1906 // Install "standard" instr size bits
1912 // OR-in register number
1914 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1916 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1922 inst |= am1 | a1reg; // Get ea1 into instr
1923 D_word(inst); // Deposit instr
1925 // Generate ea0 if requested
1929 ea1gen(siz); // Generate ea1
1934 inst |= am0 | a0reg; // Get ea0 into instr
1935 D_word(inst); // Deposit instr
1936 ea0gen(siz); // Generate ea0
1938 // Generate ea1 if requested
1943 inst = a1reg + (a2reg << 12) + (1 << 11) + (1 << 10);
1952 int m_divul(WORD inst, WORD siz)
1954 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
1955 return error(unsupport);
1957 WORD flg = inst; // Save flag bits
1958 inst &= ~0x3F; // Clobber flag bits in instr
1960 // Install "standard" instr size bits
1966 // OR-in register number
1968 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
1970 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
1976 inst |= am1 | a1reg; // Get ea1 into instr
1977 D_word(inst); // Deposit instr
1979 // Generate ea0 if requested
1983 ea1gen(siz); // Generate ea1
1988 inst |= am0 | a0reg; // Get ea0 into instr
1989 D_word(inst); // Deposit instr
1990 ea0gen(siz); // Generate ea0
1992 // Generate ea1 if requested
1997 inst = a1reg + (a2reg << 12) + (1 << 10);
2005 // move16 (ax)+,(ay)+
2007 int m_move16a(WORD inst, WORD siz)
2009 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2010 return error(unsupport);
2014 inst = (1 << 15) + (a1reg << 12);
2022 // move16 with absolute address
2024 int m_move16b(WORD inst, WORD siz)
2026 if ((activecpu & (CPU_68040 | CPU_68060)) == 0)
2027 return error(unsupport);
2033 if (am0 == APOSTINC)
2036 return error("Wasn't this suppose to call m_move16a???");
2039 //move16 (ax)+,(xxx).L
2044 else if (am0 == ABSL)
2048 //move16 (xxx).L,(ax)+
2054 //move16 (xxx).L,(ax)
2059 else if (am0 == AIND)
2061 //move16 (ax),(xxx).L
2076 int m_pack(WORD inst, WORD siz)
2078 if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
2079 return error(unsupport);
2081 WARNING(Parsing stuff by hand here might be better)
2084 if ((am0 == DREG) && (am1 == DREG))
2086 inst |= (1 << 3) + (a0reg << 9) + (a1reg);
2088 else if ((am0 == APREDEC) && (am1 == APREDEC))
2090 inst |= (a0reg << 9) + (a1reg);
2093 return error("Only allowed combinations for pack/unpack are -(ax),-(ay) and dx,dy.");
2105 int m_rtm(WORD inst, WORD siz)
2113 else if (am0 == AREG)
2115 inst |= (1 << 3) + a0reg;
2118 return error("rtm only allows data or address registers.");
2129 int m_rtd(WORD inst, WORD siz)
2133 if (a0exattr & DEFINED)
2136 return error(abs_error);
2138 if ((a0exval + 0x8000) <= 0x7FFF)
2139 return error(range_error);
2145 return error(undef_error);
2154 int m_trapcc(WORD inst, WORD siz)
2162 else if (am0 == IMMED)
2166 if (a0exval < 0x10000)
2173 return error("Immediate value too big");
2183 return error("Invalid parameter for trapcc");
2192 int m_cinv(WORD inst, WORD siz)
2195 WARNING("cinvl ,(an) / cinvp ,(an) / cinva should work!")
2198 inst |= (0 << 6) | (a1reg);
2199 else if (am0 == KW_IC40)
2200 inst |= (2 << 6) | (a1reg);
2201 else if (am0 == KW_DC40)
2202 inst |= (1 << 6) | (a1reg);
2203 else if (am0 == KW_BC40)
2204 inst |= (3 << 6) | (a1reg);
2212 // cpRESTORE (68020, 68030)
2214 int m_cprest(WORD inst, WORD siz)
2216 if (activecpu & !(CPU_68020 | CPU_68030))
2217 return error(unsupport);
2219 inst |= am0 | a0reg;
2228 // movec (68010, 68020, 68030, 68040, CPU32)
2230 int m_movec(WORD inst, WORD siz)
2234 if (am0 == DREG || am0 == AREG)
2242 inst = (0 << 15) + (a0reg << 12) + CREGlut[a1reg];
2247 inst = (1 << 15) + (a0reg << 12) + CREGlut[a1reg];
2258 inst = (0 << 15) + (a1reg << 12) + CREGlut[a0reg];
2263 inst = (1 << 15) + (a1reg << 12) + CREGlut[a0reg];
2273 // moves (68010, 68020, 68030, 68040, CPU32)
2275 int m_moves(WORD inst, WORD siz)
2277 if (activecpu & !(CPU_68020 | CPU_68030 | CPU_68040))
2278 return error(unsupport);
2284 else if (siz == SIZL)
2295 inst |= am1 | a1reg;
2297 inst = (a0reg << 12) | (1 << 11) | (0 << 15);
2300 else if (am0 == AREG)
2302 inst |= am1 | a1reg;
2304 inst = (a0reg << 12) | (1 << 11) | (1 << 15);
2311 inst |= am0 | a0reg;
2313 inst = (a1reg << 12) | (0 << 11) | (0 << 15);
2318 inst |= am0 | a0reg;
2320 inst = (a1reg << 12) | (0 << 11) | (1 << 15);
2332 int m_pbcc(WORD inst, WORD siz)
2335 return error("Not implemented yet.");
2342 int m_pflusha(WORD inst, WORD siz)
2347 inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
2354 // pflush (68030, 68040, 68060)
2356 int m_pflush(WORD inst, WORD siz)
2358 if (activecpu == CPU_68030)
2361 D_word((1 << 13) | (1 << 10) | (0 << 5) | 0);
2363 else if (activecpu == CPU_68040 || activecpu == CPU_68060)
2368 return error(unsupport);
2377 int m_pflushr(WORD inst, WORD siz)
2381 WORD flg = inst; // Save flag bits
2382 inst &= ~0x3F; // Clobber flag bits in instr
2384 // Install "standard" instr size bits
2390 // OR-in register number
2392 inst |= reg_9[a1reg]; // ea1reg in bits 9..11
2394 inst |= reg_9[a0reg]; // ea0reg in bits 9..11
2400 inst |= am1 | a1reg; // Get ea1 into instr
2401 D_word(inst); // Deposit instr
2403 // Generate ea0 if requested
2407 ea1gen(siz); // Generate ea1
2412 inst |= am0 | a0reg; // Get ea0 into instr
2413 D_word(inst); // Deposit instr
2414 ea0gen(siz); // Generate ea0
2416 // Generate ea1 if requested
2421 D_word(B16(10100000, 00000000));
2426 // ploadr, ploadw (68030)
2428 int m_pload(WORD inst, WORD siz)
2431 return error("Not implemented yet.");
2438 int m_pmove(WORD inst, WORD siz)
2444 inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
2445 inst &= ~(1 << 8); //And mask it out
2452 else if (am1 == CREG)
2458 return error("pmove sez: Wut?");
2460 if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
2461 && ((siz != SIZD) && (siz != SIZN)))
2462 return error(siz_error);
2464 if (((reg == (KW_TC - KW_SFC)) || (reg == (KW_TT0 - KW_SFC)) || (reg == (KW_TT1 - KW_SFC)))
2465 && ((siz != SIZL) && (siz != SIZN)))
2466 return error(siz_error);
2468 if ((reg == (KW_MMUSR - KW_SFC)) && ((siz != SIZW) && (siz != SIZN)))
2469 return error(siz_error);
2471 WARNING(Not all addressing modes are legal here!)
2479 else if (am1 == CREG)
2488 case (KW_URP - KW_SFC):
2489 inst2 |= (3 << 10) + (2 << 13); break;
2490 case (KW_SRP - KW_SFC):
2491 inst2 |= (2 << 10) + (2 << 13); break;
2492 case (KW_TC - KW_SFC):
2493 inst2 |= (0 << 10) + (2 << 13); break;
2494 case (KW_TT0 - KW_SFC):
2495 inst2 |= (2 << 10) + (0 << 13); break;
2496 case (KW_TT1 - KW_SFC):
2497 inst2 |= (3 << 10) + (0 << 13); break;
2498 case (KW_MMUSR - KW_SFC):
2499 inst2 |= (3 << 10) + (3 << 13); break;
2500 case (KW_CRP - KW_SFC) : //68851 only
2501 inst2 |= (3 << 10) + (2 << 13); break;
2513 int m_pmovefd(WORD inst, WORD siz)
2517 return m_pmove(inst | (1 << 8), siz);
2524 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; }
2525 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; }
2526 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; }
2527 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; }
2528 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; }
2529 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; }
2530 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; }
2531 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; }
2532 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; }
2533 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; }
2534 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; }
2535 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; }
2536 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; }
2537 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; }
2538 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; }
2539 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; }
2540 int m_ptrapbsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000000)); return OK; }
2541 int m_ptrapbcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000001)); return OK; }
2542 int m_ptraplsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000010)); return OK; }
2543 int m_ptraplcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000011)); return OK; }
2544 int m_ptrapssn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000100)); return OK; }
2545 int m_ptrapscn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000101)); return OK; }
2546 int m_ptrapasn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000110)); return OK; }
2547 int m_ptrapacn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00000111)); return OK; }
2548 int m_ptrapwsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001000)); return OK; }
2549 int m_ptrapwcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001001)); return OK; }
2550 int m_ptrapisn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001010)); return OK; }
2551 int m_ptrapicn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001011)); return OK; }
2552 int m_ptrapgsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001100)); return OK; }
2553 int m_ptrapgcn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001101)); return OK; }
2554 int m_ptrapcsn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001110)); return OK; }
2555 int m_ptrapccn(WORD inst, WORD siz) { CHECKNO20; D_word(inst); D_word(B8(00001111)); return OK; }
2559 // ptestr, ptestw (68030)
2561 int m_ptest(WORD inst, WORD siz)
2565 if (activecpu == CPU_68030)
2566 return error("Not implemented yet.");
2567 else if (activecpu == CPU_68040)
2568 return error("Not implemented yet.");
2574 #define FPU_NOWARN 0
2575 #define FPU_P_EMUL 1
2576 #define FPU_P2_EMU 2
2581 // Generate a FPU opcode
2583 static inline int gen_fpu(WORD inst, WORD siz, WORD opmode, WORD emul)
2585 if (am0 < AM_NONE) // Check first operand for ea or fp - is this right?
2587 inst |= (1 << 9); // Bolt on FPU id
2594 inst = 1 << 14; // R/M field (we have ea so have to set this to 1)
2598 case SIZB: inst |= (6 << 10); break;
2599 case SIZW: inst |= (4 << 10); break;
2600 case SIZL: inst |= (0 << 10); break;
2602 case SIZS: inst |= (1 << 10); break;
2603 case SIZD: inst |= (5 << 10); break;
2604 case SIZX: inst |= (2 << 10); break;
2609 warn("This encoding will cause an unimplemented data type exception in the MC68040 to allow emulation in software.");
2613 return error("Something bad happened, possibly, in gen_fpu.");
2617 inst |= (a1reg << 7);
2624 inst |= (1 << 9); //Bolt on FPU id
2628 inst |= (a1reg << 7);
2633 if ((emul & FPU_FPSP) && (activefpu == FPU_68040))
2634 warn("Instruction is emulated in 68040");
2641 // fabs, fsabs, fdabs (6888X, 68040)
2643 int m_fabs(WORD inst, WORD siz)
2645 return gen_fpu(inst, siz, B8(00011000), FPU_P_EMUL);
2649 int m_fsabs(WORD inst, WORD siz)
2651 if (activefpu == FPU_68040)
2652 return gen_fpu(inst, siz, B8(01011000), FPU_P_EMUL);
2654 return error("Unsupported in current FPU");
2658 int m_fdabs(WORD inst, WORD siz)
2660 if (activefpu == FPU_68040)
2661 return gen_fpu(inst, siz, B8(01011100), FPU_P_EMUL);
2663 return error("Unsupported in current FPU");
2668 // facos (6888X, 68040FPSP)
2670 int m_facos(WORD inst, WORD siz)
2672 return gen_fpu(inst, siz, B8(00011100), FPU_FPSP);
2677 // fadd (6888X, 68040FPSP)
2679 int m_fadd(WORD inst, WORD siz)
2681 return gen_fpu(inst, siz, B8(00100010), FPU_P_EMUL);
2685 int m_fsadd(WORD inst, WORD siz)
2687 if (activefpu == FPU_68040)
2688 return gen_fpu(inst, siz, B8(01100010), FPU_P_EMUL);
2690 return error("Unsupported in current FPU");
2694 int m_fdadd(WORD inst, WORD siz)
2696 if (activefpu == FPU_68040)
2697 return gen_fpu(inst, siz, B8(01100110), FPU_P_EMUL);
2699 return error("Unsupported in current FPU");
2704 // fasin (6888X, 68040FPSP)f
2706 int m_fasin(WORD inst, WORD siz)
2708 return gen_fpu(inst, siz, B8(00001100), FPU_FPSP);
2713 // fatan (6888X, 68040FPSP)
2715 int m_fatan(WORD inst, WORD siz)
2717 return gen_fpu(inst, siz, B8(00001010), FPU_FPSP);
2722 // fatanh (6888X, 68040FPSP)
2724 int m_fatanh(WORD inst, WORD siz)
2726 return gen_fpu(inst, siz, B8(00001101), FPU_FPSP);
2731 // fcmp (6888X, 68040)
2733 int m_fcmp(WORD inst, WORD siz)
2735 return gen_fpu(inst, siz, B8(00111000), FPU_P_EMUL);
2740 // fcos (6888X, 68040FPSP)
2742 int m_fcos(WORD inst, WORD siz)
2744 return gen_fpu(inst, siz, B8(00011101), FPU_FPSP);
2749 // fcosh (6888X, 68040FPSP)
2751 int m_fcosh(WORD inst, WORD siz)
2753 return gen_fpu(inst, siz, B8(00011001), FPU_FPSP);
2758 // fdbcc (6888X, 68040)
2760 int m_fdbcc(WORD inst, WORD siz)
2762 WORD opcode = inst & 0x3F; //Grab conditional bitfield
2772 if (a1exattr & DEFINED)
2774 if ((a1exattr & TDB) != cursect)
2775 return error(rel_error);
2777 VALUE v = a1exval - sloc;
2779 if ((v + 0x8000) > 0x10000)
2780 return error(range_error);
2786 AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
2795 // fdiv (6888X, 68040)
2797 int m_fdiv(WORD inst, WORD siz)
2799 return gen_fpu(inst, siz, B8(00100000), FPU_P_EMUL);
2803 int m_fsdiv(WORD inst, WORD siz)
2805 if (activefpu == FPU_68040)
2806 return gen_fpu(inst, siz, B8(01100000), FPU_P_EMUL);
2808 return error("Unsupported in current FPU");
2812 int m_fddiv(WORD inst, WORD siz)
2814 if (activefpu == FPU_68040)
2815 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
2817 return error("Unsupported in current FPU");
2822 // fetox (6888X, 68040FPSP)
2824 int m_fetox(WORD inst, WORD siz)
2826 return gen_fpu(inst, siz, B8(00010000), FPU_FPSP);
2831 // fetoxm1 (6888X, 68040FPSP)
2833 int m_fetoxm1(WORD inst, WORD siz)
2835 return gen_fpu(inst, siz, B8(00001000), FPU_FPSP);
2840 // fgetexp (6888X, 68040FPSP)
2842 int m_fgetexp(WORD inst, WORD siz)
2844 return gen_fpu(inst, siz, B8(00011110), FPU_FPSP);
2849 // fgetman (6888X, 68040FPSP)
2851 int m_fgetman(WORD inst, WORD siz)
2853 return gen_fpu(inst, siz, B8(00011111), FPU_FPSP);
2858 // fint (6888X, 68040FPSP)
2860 int m_fint(WORD inst, WORD siz)
2863 // special case - fint fpx = fint fpx,fpx
2866 return gen_fpu(inst, siz, B8(00000001), FPU_FPSP);
2871 // fintrz (6888X, 68040FPSP)
2873 int m_fintrz(WORD inst, WORD siz)
2876 // special case - fintrz fpx = fintrz fpx,fpx
2879 return gen_fpu(inst, siz, B8(00000011), FPU_FPSP);
2884 // flog10 (6888X, 68040FPSP)
2886 int m_flog10(WORD inst, WORD siz)
2888 return gen_fpu(inst, siz, B8(00010101), FPU_FPSP);
2893 // flog2 (6888X, 68040FPSP)
2895 int m_flog2(WORD inst, WORD siz)
2897 return gen_fpu(inst, siz, B8(00010110), FPU_FPSP);
2902 // flogn (6888X, 68040FPSP)
2904 int m_flogn(WORD inst, WORD siz)
2906 return gen_fpu(inst, siz, B8(00010100), FPU_FPSP);
2911 // flognp1 (6888X, 68040FPSP)
2913 int m_flognp1(WORD inst, WORD siz)
2915 return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
2920 // fmod (6888X, 68040FPSP)
2922 int m_fmod(WORD inst, WORD siz)
2924 return gen_fpu(inst, siz, B8(00100001), FPU_FPSP);
2929 // fmove (6888X, 68040)
2931 int m_fmove(WORD inst, WORD siz)
2935 if ((am0 == FREG) && (am1 < AM_USP))
2938 inst |= am1 | a1reg;
2944 WARNING("K-factor logic is totally bogus - fix!")
2949 case SIZB: inst |= (6 << 10); break;
2950 case SIZW: inst |= (4 << 10); break;
2951 case SIZL: inst |= (0 << 10); break;
2953 case SIZS: inst |= (1 << 10); break;
2954 case SIZD: inst |= (5 << 10); break;
2955 case SIZX: inst |= (2 << 10); break;
2956 case SIZP: inst |= (3 << 10);
2960 inst |= (bfparam1 & 0x7FF) >> 2;
2963 return error("Something bad happened, possibly.");
2967 // Immediate {} value
2968 if (bf0exval >= (1 << 6))
2969 return error("K-factor must be between 0 and 31");
2971 if (!bfparam1 && (siz == SIZP))
2974 // Destination specifier
2975 inst |= (a0reg << 7);
2983 else if ((am0 < AM_USP) && (am1 == FREG))
2986 inst |= am0 | a0reg;
2995 case SIZB: inst |= (6 << 10); break;
2996 case SIZW: inst |= (4 << 10); break;
2997 case SIZL: inst |= (0 << 10); break;
2999 case SIZS: inst |= (1 << 10); break;
3000 case SIZD: inst |= (5 << 10); break;
3001 case SIZX: inst |= (2 << 10); break;
3002 case SIZP: inst |= (3 << 10); break;
3004 return error("Something bad happened, possibly.");
3008 // Destination specifier
3009 inst |= (a1reg << 7);
3017 else if ((am0 == FREG) && (am1 == FREG))
3027 return error("Invalid size");
3030 inst |= (a0reg << 10);
3032 // Destination register
3033 inst |= (a1reg << 7);
3043 // fmove (6888X, 68040)
3045 int m_fmovescr(WORD inst, WORD siz)
3047 // Move Floating-Point System Control Register (FPCR)
3051 if ((am0 == FPSCR) && (am1 < AM_USP))
3053 inst |= am1 | a1reg;
3055 inst = (1 << 13) + (1 << 15);
3061 else if ((am1 == FPSCR) && (am0 < AM_USP))
3063 inst |= am0 | a0reg;
3065 inst = (0 << 13) + (1 << 15);
3072 return error("m_fmovescr says: wut?");
3077 // fsmove/fdmove (68040)
3079 int m_fsmove(WORD inst, WORD siz)
3081 return error("Not implemented yet.");
3084 if (activefpu == FPU_68040)
3085 return gen_fpu(inst, siz, B8(01100100), FPU_P_EMUL);
3087 return error("Unsupported in current FPU");
3092 int m_fdmove(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");
3106 // fmovecr (6888X, 68040FPSP)
3108 int m_fmovecr(WORD inst, WORD siz)
3116 if (activefpu == FPU_68040)
3117 warn("Instruction is emulated in 68040");
3124 // fmovem (6888X, 68040)
3126 int m_fmovem(WORD inst, WORD siz)
3133 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3135 // fmovem.x <rlist>,ea
3136 if (fpu_reglist_left(®mask) < 0)
3140 return error("missing comma");
3145 inst |= am0 | a0reg;
3147 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3148 return error("invalid addressing mode");
3151 inst = (1 << 15) | (1 << 14) | (1 << 13) | (0 << 11) | regmask;
3156 else if ((*tok >= KW_D0) && (*tok <= KW_D7))
3159 datareg = (*tok++ & 7) << 10;
3162 return error("missing comma");
3167 inst |= am0 | a0reg;
3169 if (!(amsktab[am0] & (C_ALTCTRL | M_APREDEC)))
3170 return error("invalid addressing mode");
3173 inst = (1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (datareg << 4);
3184 inst |= am0 | a0reg;
3187 return error("missing comma");
3189 if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
3191 //fmovem.x ea,<rlist>
3192 if (fpu_reglist_right(®mask) < 0)
3196 inst = (1 << 15) | (1 << 14) | (0 << 13) | (2 << 11) | regmask;
3204 datareg = (*tok++ & 7) << 10;
3206 inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
3213 else if ((siz == SIZL) || (siz==SIZN))
3215 if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
3217 //fmovem.l <rlist>,ea
3218 regmask = (1 << 15) | (1 << 13);
3220 if (*tok == KW_FPCR)
3222 regmask |= (1 << 12);
3227 if (*tok == KW_FPSR)
3229 regmask |= (1 << 11);
3234 if (*tok == KW_FPIAR)
3236 regmask |= (1 << 10);
3241 if ((*tok == '/') || (*tok == '-'))
3248 return error("missing comma");
3253 inst |= am0 | a0reg;
3260 //fmovem.l ea,<rlist>
3264 inst |= am0 | a0reg;
3267 return error("missing comma");
3269 regmask = (1 << 15) | (0 << 13);
3272 if (*tok == KW_FPCR)
3274 regmask |= (1 << 12);
3279 if (*tok == KW_FPSR)
3281 regmask |= (1 << 11);
3286 if (*tok == KW_FPIAR)
3288 regmask |= (1 << 10);
3293 if ((*tok == '/') || (*tok == '-'))
3300 return error("extra (unexpected) text found");
3302 inst |= am0 | a0reg;
3309 return error("bad size suffix");
3316 // fmul (6888X, 68040)
3318 int m_fmul(WORD inst, WORD siz)
3320 return gen_fpu(inst, siz, B8(00100011), FPU_P_EMUL);
3324 int m_fsmul(WORD inst, WORD siz)
3326 if (activefpu == FPU_68040)
3327 return gen_fpu(inst, siz, B8(01100011), FPU_P_EMUL);
3329 return error("Unsupported in current FPU");
3333 int m_fdmul(WORD inst, WORD siz)
3335 if (activefpu == FPU_68040)
3336 return gen_fpu(inst, siz, B8(01100111), FPU_P_EMUL);
3338 return error("Unsupported in current FPU");
3343 // fneg (6888X, 68040)
3345 int m_fneg(WORD inst, WORD siz)
3347 return gen_fpu(inst, siz, B8(00011010), FPU_P_EMUL);
3351 int m_fsneg(WORD inst, WORD siz)
3353 if (activefpu == FPU_68040)
3354 return gen_fpu(inst, siz, B8(01011010), FPU_P_EMUL);
3356 return error("Unsupported in current FPU");
3360 int m_fdneg(WORD inst, WORD siz)
3362 if (activefpu == FPU_68040)
3363 return gen_fpu(inst, siz, B8(01011110), FPU_P_EMUL);
3365 return error("Unsupported in current FPU");
3370 // fnop (6888X, 68040)
3372 int m_fnop(WORD inst, WORD siz)
3374 return gen_fpu(inst, siz, B8(00000000), FPU_P_EMUL);
3379 // frem (6888X, 68040FPSP)
3381 int m_frem(WORD inst, WORD siz)
3383 return gen_fpu(inst, siz, B8(00100101), FPU_FPSP);
3388 // fscale (6888X, 68040FPSP)
3390 int m_fscale(WORD inst, WORD siz)
3392 return gen_fpu(inst, siz, B8(00100110), FPU_FPSP);
3397 // FScc (6888X, 68040)
3399 int m_fseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000001)); return OK;}
3400 int m_fsne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001110)); return OK;}
3401 int m_fsgt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010010)); return OK;}
3402 int m_fsngt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011101)); return OK;}
3403 int m_fsge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010011)); return OK;}
3404 int m_fsnge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011100)); return OK;}
3405 int m_fslt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010100)); return OK;}
3406 int m_fsnlt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011011)); return OK;}
3407 int m_fsle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010101)); return OK;}
3408 int m_fsnle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011010)); return OK;}
3409 int m_fsgl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010110)); return OK;}
3410 int m_fsngl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011001)); return OK;}
3411 int m_fsgle (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010111)); return OK;}
3412 int m_fsngle(WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011000)); return OK;}
3413 int m_fsogt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000010)); return OK;}
3414 int m_fsule (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001101)); return OK;}
3415 int m_fsoge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000011)); return OK;}
3416 int m_fsult (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001100)); return OK;}
3417 int m_fsolt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000100)); return OK;}
3418 int m_fsuge (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001011)); return OK;}
3419 int m_fsole (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000101)); return OK;}
3420 int m_fsugt (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001010)); return OK;}
3421 int m_fsogl (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000110)); return OK;}
3422 int m_fsueq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001001)); return OK;}
3423 int m_fsor (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000111)); return OK;}
3424 int m_fsun (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001000)); return OK;}
3425 int m_fsf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00000000)); return OK;}
3426 int m_fst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00001111)); return OK;}
3427 int m_fssf (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010000)); return OK;}
3428 int m_fsst (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011111)); return OK;}
3429 int m_fsseq (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00010001)); return OK;}
3430 int m_fssne (WORD inst, WORD siz) { inst|=am0|a0reg; D_word(inst); ea0gen(siz); D_word(B8(00011110)); return OK;}
3434 // FTRAPcc (6888X, 68040)
3436 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;}
3437 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;}
3438 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;}
3439 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;}
3440 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;}
3441 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;}
3442 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;}
3443 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;}
3444 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;}
3445 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;}
3446 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;}
3447 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;}
3448 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;}
3449 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;}
3450 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;}
3451 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;}
3452 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;}
3453 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;}
3454 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;}
3455 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;}
3456 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;}
3457 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;}
3458 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;}
3459 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;}
3460 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;}
3461 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;}
3462 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;}
3463 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;}
3464 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;}
3465 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;}
3466 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;}
3467 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;}
3469 int m_ftrapeqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000001)); return OK;}
3470 int m_ftrapnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001110)); return OK;}
3471 int m_ftrapgtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010010)); return OK;}
3472 int m_ftrapngtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011101)); return OK;}
3473 int m_ftrapgen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010011)); return OK;}
3474 int m_ftrapngen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011100)); return OK;}
3475 int m_ftrapltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010100)); return OK;}
3476 int m_ftrapnltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011011)); return OK;}
3477 int m_ftraplen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010101)); return OK;}
3478 int m_ftrapnlen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011010)); return OK;}
3479 int m_ftrapgln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010110)); return OK;}
3480 int m_ftrapngln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011001)); return OK;}
3481 int m_ftrapglen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010111)); return OK;}
3482 int m_ftrapnglen(WORD inst, WORD siz) { D_word(inst); D_word(B8(00011000)); return OK;}
3483 int m_ftrapogtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000010)); return OK;}
3484 int m_ftrapulen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001101)); return OK;}
3485 int m_ftrapogen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000011)); return OK;}
3486 int m_ftrapultn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001100)); return OK;}
3487 int m_ftrapoltn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000100)); return OK;}
3488 int m_ftrapugen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001011)); return OK;}
3489 int m_ftrapolen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000101)); return OK;}
3490 int m_ftrapugtn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001010)); return OK;}
3491 int m_ftrapogln (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000110)); return OK;}
3492 int m_ftrapueqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001001)); return OK;}
3493 int m_ftraporn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000111)); return OK;}
3494 int m_ftrapunn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001000)); return OK;}
3495 int m_ftrapfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00000000)); return OK;}
3496 int m_ftraptn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00001111)); return OK;}
3497 int m_ftrapsfn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010000)); return OK;}
3498 int m_ftrapstn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011111)); return OK;}
3499 int m_ftrapseqn (WORD inst, WORD siz) { D_word(inst); D_word(B8(00010001)); return OK;}
3500 int m_ftrapsnen (WORD inst, WORD siz) { D_word(inst); D_word(B8(00011110)); return OK;}
3504 // fsgldiv (6888X, 68040)
3506 int m_fsgldiv(WORD inst, WORD siz)
3508 return gen_fpu(inst, siz, B8(00100100), FPU_P_EMUL);
3513 // fsglmul (6888X, 68040)
3515 int m_fsglmul(WORD inst, WORD siz)
3517 return gen_fpu(inst, siz, B8(00100111), FPU_P_EMUL);
3522 // fsin (6888X, 68040FPSP)
3524 int m_fsin(WORD inst, WORD siz)
3526 return gen_fpu(inst, siz, B8(00001110), FPU_FPSP);
3531 // fsincos (6888X, 68040FPSP)
3533 int m_fsincos(WORD inst, WORD siz)
3535 if (gen_fpu(inst, siz, B8(00110000), FPU_FPSP) == OK)
3546 // fsin (6888X, 68040FPSP)
3548 int m_fsinh(WORD inst, WORD siz)
3550 return gen_fpu(inst, siz, B8(00000010), FPU_FPSP);
3555 // fsqrt (6888X, 68040)
3557 int m_fsqrt(WORD inst, WORD siz)
3559 return gen_fpu(inst, siz, B8(00000100), FPU_P_EMUL);
3563 int m_fsfsqrt(WORD inst, WORD siz)
3565 if (activefpu == FPU_68040)
3566 return gen_fpu(inst, siz, B8(01000001), FPU_P_EMUL);
3568 return error("Unsupported in current FPU");
3572 int m_fdfsqrt(WORD inst, WORD siz)
3574 if (activefpu == FPU_68040)
3575 return gen_fpu(inst, siz, B8(01000101), FPU_P_EMUL);
3577 return error("Unsupported in current FPU");
3582 // fsub (6888X, 68040)
3584 int m_fsub(WORD inst, WORD siz)
3586 return gen_fpu(inst, siz, B8(00101000), FPU_P_EMUL);
3590 int m_fsfsub(WORD inst, WORD siz)
3592 if (activefpu == FPU_68040)
3593 return gen_fpu(inst, siz, B8(01101000), FPU_P_EMUL);
3595 return error("Unsupported in current FPU");
3599 int m_fdsub(WORD inst, WORD siz)
3601 if (activefpu == FPU_68040)
3602 return gen_fpu(inst, siz, B8(01101100), FPU_P_EMUL);
3604 return error("Unsupported in current FPU");
3609 // ftan (6888X, 68040FPSP)
3611 int m_ftan(WORD inst, WORD siz)
3613 return gen_fpu(inst, siz, B8(00001111), FPU_FPSP);
3618 // ftanh (6888X, 68040FPSP)
3620 int m_ftanh(WORD inst, WORD siz)
3622 return gen_fpu(inst, siz, B8(00001001), FPU_FPSP);
3627 // ftentox (6888X, 68040FPSP)
3629 int m_ftentox(WORD inst, WORD siz)
3631 return gen_fpu(inst, siz, B8(00010010), FPU_FPSP);
3636 // ftst (6888X, 68040)
3638 int m_ftst(WORD inst, WORD siz)
3640 return gen_fpu(inst, siz, B8(00111010), FPU_P_EMUL);
3645 // ftwotox (6888X, 68040FPSP)
3647 int m_ftwotox(WORD inst, WORD siz)
3649 return gen_fpu(inst, siz, B8(00010001), FPU_FPSP);