1 /*
2 * UAE - The Un*x Amiga Emulator - CPU core
3 *
4 * MC68000 emulation generator
5 *
6 * This is a fairly stupid program that generates a lot of case labels that
7 * can be #included in a switch statement.
8 * As an alternative, it can generate functions that handle specific
9 * MC68000 instructions, plus a prototype header file and a function pointer
10 * array to look up the function for an opcode.
11 * Error checking is bad, an illegal table68k file will cause the program to
12 * call abort().
13 * The generated code is sometimes sub-optimal, an optimizing compiler should
14 * take care of this.
15 *
16 * The source for the insn timings is Markt & Technik's Amiga Magazin 8/1992.
17 *
18 * Copyright 1995, 1996, 1997, 1998, 1999, 2000 Bernd Schmidt
19 *
20 * Adaptation to Hatari and better cpu timings by Thomas Huth
21 * Adaptation to Virtual Jaguar by James Hammons
22 *
23 * This file is distributed under the GNU Public License, version 3 or at
24 * your option any later version. Read the file GPLv3 for details.
25 *
26 */
27
28
29 /* 2007/03/xx [NP] Use add_cycles.pl to set 'CurrentInstrCycles' in each opcode. */
30 /* 2007/04/09 [NP] Correct CLR : on 68000, CLR reads the memory before clearing it (but we should */
31 /* not add cycles for reading). This means CLR can give 2 wait states (one for */
32 /* read and one for right) (clr.b $fa1b.w in Decade's Demo Main Menu). */
33 /* 2007/04/14 [NP] - Although dest -(an) normally takes 2 cycles, this is not the case for move : */
34 /* move dest (an), (an)+ and -(an) all take the same time (curi->dmode == Apdi) */
35 /* (Syntax Terror Demo Reset). */
36 /* - Scc takes 6 cycles instead of 4 if the result is true (Ventura Demo Loader). */
37 /* - Store the family of the current opcode into OpcodeFamily : used to check */
38 /* instruction pairing on ST into m68000.c */
39 /* 2007/04/17 [NP] Add support for cycle accurate MULU (No Cooper Greeting Screen). */
40 /* 2007/04/24 [NP] BCLR #n,Dx takes 12 cycles instead of 14 if n<16 (ULM Demo Menu). */
41 /* 2007/04/25 [NP] On ST, d8(An,Xn) and d8(PC,Xn) take 2 cycles more than the official 68000's */
42 /* table (ULM Demo Menu). */
43 /* 2007/11/12 [NP] Add refill_prefetch for i_ADD to fix Transbeauce 2 demo self modified code. */
44 /* Ugly hack, we need better prefetch emulation (switch to winuae gencpu.c) */
45 /* 2007/11/25 [NP] In i_DBcc, in case of address error, last_addr_for_exception_3 should be */
46 /* pc+4, not pc+2 (Transbeauce 2 demo) (e.g. 'dbf d0,#$fff5'). */
47 /* This means the value pushed on the frame stack should be the address of the */
48 /* instruction following the one generating the address error. */
49 /* FIXME : this should be the case for i_BSR and i_BCC too (need to check on */
50 /* a real 68000). */
51 /* 2007/11/28 [NP] Backport DIVS/DIVU cycles exact routines from WinUAE (original work by Jorge */
52 /* Cwik, pasti@fxatari.com). */
53 /* 2007/12/08 [NP] In case of CHK/CHK2 exception, PC stored on the stack wasn't pointing to the */
54 /* next instruction but to the current CHK/CHK2 instruction (Transbeauce 2 demo). */
55 /* We need to call 'sync_m68k_pc' before calling 'Exception'. */
56 /* 2007/12/09 [NP] CHK.L (e.g. $4700) doesn't exist on 68000 and should be considered as an illegal*/
57 /* instruction (Transbeauce 2 demo) -> change in table68k. */
58 /* 2008/01/24 [NP] BCLR Dy,Dx takes 8 cycles instead of 10 if Dy<16 (Fullshade in Anomaly Demos). */
59 /* 2008/01/26 [NP] On ST, d8(An,Xn) takes 2 cycles more when used with ADDA/SUBA (ULM Demo Menu) */
60 /* but not when used with MOVE (e.g. 'move.l 0(a5,d1),(a4)' takes 26 cycles and so */
61 /* can pair with a lsr) (Anomaly Demo Intro). */
62 /* 2008/04/26 [NP] Handle sz_byte for Areg in genamode, as 'move.b a1,(a0)' ($1089) is possible */
63 /* on ST (fix Blood Money on Superior 65) */
64 /* 2010/04/05 [NP] On ST, d8(An,Xn) takes 2 cycles more (which can generate pairing). */
65 /* Use BusCyclePenalty to properly handle the 2/4 cycles added in that case when */
66 /* addressing mode is Ad8r or PC8r (ULM Demo Menu, Anomaly Demo Intro, DHS */
67 /* Sommarhack 2010) (see m68000.h) */
68
69
70 //const char GenCpu_fileid[] = "Hatari gencpu.c : " __DATE__ " " __TIME__;
71
72 #include <ctype.h>
73 #include <string.h>
74
75 #include "sysdeps.h"
76 #include "readcpu.h"
77
78 #define BOOL_TYPE "int"
79
80 static FILE *headerfile;
81 static FILE *stblfile;
82
83 static int using_prefetch;
84 static int using_exception_3;
85 static int cpu_level;
86
87 char exactCpuCycles[256]; /* Space to store return string for exact cpu cycles */
88
89 long nCurInstrCycPos; /* Stores where we have to patch in the current cycles value */
90
91 /* For the current opcode, the next lower level that will have different code.
92 * Initialized to -1 for each opcode. If it remains unchanged, indicates we
93 * are done with that opcode. */
94 static int next_cpu_level;
95 static int *opcode_map;
96 static int *opcode_next_clev;
97 static int *opcode_last_postfix;
98 static unsigned long *counts;
99
100
read_counts(void)101 static void read_counts (void)
102 {
103 FILE *file;
104 unsigned long opcode, count, total;
105 char name[20];
106 int nr = 0;
107 memset (counts, 0, 65536 * sizeof *counts);
108
109 file = fopen ("frequent.68k", "r");
110 if (file) {
111 if (fscanf (file, "Total: %lu\n", &total) == EOF) {
112 perror("read_counts");
113 }
114 while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) {
115 opcode_next_clev[nr] = 4;
116 opcode_last_postfix[nr] = -1;
117 opcode_map[nr++] = opcode;
118 counts[opcode] = count;
119 }
120 fclose (file);
121 }
122 if (nr == nr_cpuop_funcs)
123 return;
124 for (opcode = 0; opcode < 0x10000; opcode++) {
125 if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
126 && counts[opcode] == 0)
127 {
128 opcode_next_clev[nr] = 4;
129 opcode_last_postfix[nr] = -1;
130 opcode_map[nr++] = opcode;
131 counts[opcode] = count;
132 }
133 }
134 if (nr != nr_cpuop_funcs)
135 abort ();
136 }
137
138 static char endlabelstr[80];
139 static int endlabelno = 0;
140 static int need_endlabel;
141
142 static int n_braces = 0;
143 static int m68k_pc_offset = 0;
144 static int insn_n_cycles;
145
start_brace(void)146 static void start_brace (void)
147 {
148 n_braces++;
149 printf ("{");
150 }
151
close_brace(void)152 static void close_brace (void)
153 {
154 assert (n_braces > 0);
155 n_braces--;
156 printf ("}");
157 }
158
finish_braces(void)159 static void finish_braces (void)
160 {
161 while (n_braces > 0)
162 close_brace ();
163 }
164
pop_braces(int to)165 static void pop_braces (int to)
166 {
167 while (n_braces > to)
168 close_brace ();
169 }
170
bit_size(int size)171 static int bit_size (int size)
172 {
173 switch (size) {
174 case sz_byte: return 8;
175 case sz_word: return 16;
176 case sz_long: return 32;
177 default: abort ();
178 }
179 return 0;
180 }
181
bit_mask(int size)182 static const char *bit_mask (int size)
183 {
184 switch (size) {
185 case sz_byte: return "0xff";
186 case sz_word: return "0xffff";
187 case sz_long: return "0xffffffff";
188 default: abort ();
189 }
190 return 0;
191 }
192
gen_nextilong(void)193 static const char *gen_nextilong (void)
194 {
195 static char buffer[80];
196 int r = m68k_pc_offset;
197 m68k_pc_offset += 4;
198
199 insn_n_cycles += 8;
200
201 if (using_prefetch)
202 sprintf (buffer, "get_ilong_prefetch(%d)", r);
203 else
204 sprintf (buffer, "get_ilong(%d)", r);
205 return buffer;
206 }
207
gen_nextiword(void)208 static const char *gen_nextiword (void)
209 {
210 static char buffer[80];
211 int r = m68k_pc_offset;
212 m68k_pc_offset += 2;
213
214 insn_n_cycles += 4;
215
216 if (using_prefetch)
217 sprintf (buffer, "get_iword_prefetch(%d)", r);
218 else
219 sprintf (buffer, "get_iword(%d)", r);
220 return buffer;
221 }
222
gen_nextibyte(void)223 static const char *gen_nextibyte (void)
224 {
225 static char buffer[80];
226 int r = m68k_pc_offset;
227 m68k_pc_offset += 2;
228
229 insn_n_cycles += 4;
230
231 if (using_prefetch)
232 sprintf (buffer, "get_ibyte_prefetch(%d)", r);
233 else
234 sprintf (buffer, "get_ibyte(%d)", r);
235 return buffer;
236 }
237
fill_prefetch_0(void)238 static void fill_prefetch_0 (void)
239 {
240 if (using_prefetch)
241 printf ("fill_prefetch_0 ();\n");
242 }
243
fill_prefetch_2(void)244 static void fill_prefetch_2 (void)
245 {
246 if (using_prefetch)
247 printf ("fill_prefetch_2 ();\n");
248 }
249
sync_m68k_pc(void)250 static void sync_m68k_pc(void)
251 {
252 if (m68k_pc_offset == 0)
253 return;
254
255 printf("m68k_incpc(%d);\n", m68k_pc_offset);
256
257 switch (m68k_pc_offset)
258 {
259 case 0:
260 /*fprintf (stderr, "refilling prefetch at 0\n"); */
261 break;
262 case 2:
263 fill_prefetch_2();
264 break;
265 default:
266 fill_prefetch_0();
267 break;
268 }
269
270 m68k_pc_offset = 0;
271 }
272
273 /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
274 * the calling routine handles Apdi and Aipi modes.
275 * gb-- movem == 2 means the same thing but for a MOVE16 instruction */
genamode(amodes mode,const char * reg,wordsizes size,const char * name,int getv,int movem)276 static void genamode(amodes mode, const char * reg, wordsizes size,
277 const char * name, int getv, int movem)
278 {
279 start_brace();
280 switch (mode)
281 {
282 case Dreg:
283 if (movem)
284 abort ();
285 if (getv == 1)
286 switch (size) {
287 case sz_byte:
288 printf ("\tint8_t %s = m68k_dreg(regs, %s);\n", name, reg);
289 break;
290 case sz_word:
291 printf ("\tint16_t %s = m68k_dreg(regs, %s);\n", name, reg);
292 break;
293 case sz_long:
294 printf ("\tint32_t %s = m68k_dreg(regs, %s);\n", name, reg);
295 break;
296 default:
297 abort ();
298 }
299 return;
300 case Areg:
301 if (movem)
302 abort ();
303 if (getv == 1)
304 switch (size) {
305 case sz_byte: // [NP] Areg with .b is possible in MOVE source */
306 printf ("\tint8_t %s = m68k_areg(regs, %s);\n", name, reg);
307 break;
308 case sz_word:
309 printf ("\tint16_t %s = m68k_areg(regs, %s);\n", name, reg);
310 break;
311 case sz_long:
312 printf ("\tint32_t %s = m68k_areg(regs, %s);\n", name, reg);
313 break;
314 default:
315 abort ();
316 }
317 return;
318 case Aind:
319 printf ("\tuint32_t %sa = m68k_areg(regs, %s);\n", name, reg);
320 break;
321 case Aipi:
322 printf ("\tuint32_t %sa = m68k_areg(regs, %s);\n", name, reg);
323 break;
324 case Apdi:
325 insn_n_cycles += 2;
326 switch (size) {
327 case sz_byte:
328 if (movem)
329 printf ("\tuint32_t %sa = m68k_areg(regs, %s);\n", name, reg);
330 else
331 printf ("\tuint32_t %sa = m68k_areg(regs, %s) - areg_byteinc[%s];\n", name, reg, reg);
332 break;
333 case sz_word:
334 printf ("\tuint32_t %sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 2);
335 break;
336 case sz_long:
337 printf ("\tuint32_t %sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 4);
338 break;
339 default:
340 abort ();
341 }
342 break;
343 case Ad16:
344 printf ("\tuint32_t %sa = m68k_areg(regs, %s) + (int32_t)(int16_t)%s;\n", name, reg, gen_nextiword ());
345 break;
346 case Ad8r:
347 insn_n_cycles += 2;
348 if (cpu_level > 1) {
349 if (next_cpu_level < 1)
350 next_cpu_level = 1;
351 sync_m68k_pc ();
352 start_brace ();
353 /* This would ordinarily be done in gen_nextiword, which we bypass. */
354 insn_n_cycles += 4;
355 printf ("\tuint32_t %sa = get_disp_ea_020(m68k_areg(regs, %s), next_iword());\n", name, reg);
356 } else {
357 printf ("\tuint32_t %sa = get_disp_ea_000(m68k_areg(regs, %s), %s);\n", name, reg, gen_nextiword ());
358 }
359 printf ("\tBusCyclePenalty += 2;\n");
360
361 break;
362 case PC16:
363 printf ("\tuint32_t %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset);
364 printf ("\t%sa += (int32_t)(int16_t)%s;\n", name, gen_nextiword ());
365 break;
366 case PC8r:
367 insn_n_cycles += 2;
368 if (cpu_level > 1) {
369 if (next_cpu_level < 1)
370 next_cpu_level = 1;
371 sync_m68k_pc ();
372 start_brace ();
373 /* This would ordinarily be done in gen_nextiword, which we bypass. */
374 insn_n_cycles += 4;
375 printf ("\tuint32_t tmppc = m68k_getpc();\n");
376 printf ("\tuint32_t %sa = get_disp_ea_020(tmppc, next_iword());\n", name);
377 } else {
378 printf ("\tuint32_t tmppc = m68k_getpc() + %d;\n", m68k_pc_offset);
379 printf ("\tuint32_t %sa = get_disp_ea_000(tmppc, %s);\n", name, gen_nextiword ());
380 }
381 printf ("\tBusCyclePenalty += 2;\n");
382
383 break;
384 case absw:
385 printf ("\tuint32_t %sa = (int32_t)(int16_t)%s;\n", name, gen_nextiword ());
386 break;
387 case absl:
388 printf ("\tuint32_t %sa = %s;\n", name, gen_nextilong ());
389 break;
390 case imm:
391 if (getv != 1)
392 abort ();
393 switch (size) {
394 case sz_byte:
395 printf ("\tint8_t %s = %s;\n", name, gen_nextibyte ());
396 break;
397 case sz_word:
398 printf ("\tint16_t %s = %s;\n", name, gen_nextiword ());
399 break;
400 case sz_long:
401 printf ("\tint32_t %s = %s;\n", name, gen_nextilong ());
402 break;
403 default:
404 abort ();
405 }
406 return;
407 case imm0:
408 if (getv != 1)
409 abort ();
410 printf ("\tint8_t %s = %s;\n", name, gen_nextibyte ());
411 return;
412 case imm1:
413 if (getv != 1)
414 abort ();
415 printf ("\tint16_t %s = %s;\n", name, gen_nextiword ());
416 return;
417 case imm2:
418 if (getv != 1)
419 abort ();
420 printf ("\tint32_t %s = %s;\n", name, gen_nextilong ());
421 return;
422 case immi:
423 if (getv != 1)
424 abort ();
425 printf ("\tuint32_t %s = %s;\n", name, reg);
426 return;
427 default:
428 abort ();
429 }
430
431 /* We get here for all non-reg non-immediate addressing modes to
432 * actually fetch the value. */
433
434 if (using_exception_3 && getv != 0 && size != sz_byte) {
435 printf ("\tif ((%sa & 1) != 0) {\n", name);
436 printf ("\t\tlast_fault_for_exception_3 = %sa;\n", name);
437 printf ("\t\tlast_op_for_exception_3 = opcode;\n");
438 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + %d;\n", m68k_pc_offset);
439 printf ("\t\tException(3, 0, M68000_EXC_SRC_CPU);\n");
440 printf ("\t\tgoto %s;\n", endlabelstr);
441 printf ("\t}\n");
442 need_endlabel = 1;
443 start_brace ();
444 }
445
446 if (getv == 1) {
447 switch (size) {
448 case sz_byte: insn_n_cycles += 4; break;
449 case sz_word: insn_n_cycles += 4; break;
450 case sz_long: insn_n_cycles += 8; break;
451 default: abort ();
452 }
453 start_brace ();
454 switch (size) {
455 case sz_byte: printf ("\tint8_t %s = m68k_read_memory_8(%sa);\n", name, name); break;
456 case sz_word: printf ("\tint16_t %s = m68k_read_memory_16(%sa);\n", name, name); break;
457 case sz_long: printf ("\tint32_t %s = m68k_read_memory_32(%sa);\n", name, name); break;
458 default: abort ();
459 }
460 }
461
462 /* We now might have to fix up the register for pre-dec or post-inc
463 * addressing modes. */
464 if (!movem)
465 switch (mode) {
466 case Aipi:
467 switch (size) {
468 case sz_byte:
469 printf ("\tm68k_areg(regs, %s) += areg_byteinc[%s];\n", reg, reg);
470 break;
471 case sz_word:
472 printf ("\tm68k_areg(regs, %s) += 2;\n", reg);
473 break;
474 case sz_long:
475 printf ("\tm68k_areg(regs, %s) += 4;\n", reg);
476 break;
477 default:
478 abort ();
479 }
480 break;
481 case Apdi:
482 printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name);
483 break;
484 default:
485 break;
486 }
487 }
488
genastore(const char * from,amodes mode,const char * reg,wordsizes size,const char * to)489 static void genastore (const char *from, amodes mode, const char *reg,
490 wordsizes size, const char *to)
491 {
492 switch (mode) {
493 case Dreg:
494 switch (size) {
495 case sz_byte:
496 printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from);
497 break;
498 case sz_word:
499 printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from);
500 break;
501 case sz_long:
502 printf ("\tm68k_dreg(regs, %s) = (%s);\n", reg, from);
503 break;
504 default:
505 abort ();
506 }
507 break;
508 case Areg:
509 switch (size) {
510 case sz_word:
511 fprintf (stderr, "Foo\n");
512 printf ("\tm68k_areg(regs, %s) = (int32_t)(int16_t)(%s);\n", reg, from);
513 break;
514 case sz_long:
515 printf ("\tm68k_areg(regs, %s) = (%s);\n", reg, from);
516 break;
517 default:
518 abort ();
519 }
520 break;
521 case Aind:
522 case Aipi:
523 case Apdi:
524 case Ad16:
525 case Ad8r:
526 case absw:
527 case absl:
528 case PC16:
529 case PC8r:
530 if (using_prefetch)
531 sync_m68k_pc ();
532 switch (size) {
533 case sz_byte:
534 insn_n_cycles += 4;
535 printf ("\tm68k_write_memory_8(%sa,%s);\n", to, from);
536 break;
537 case sz_word:
538 insn_n_cycles += 4;
539 if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
540 abort ();
541 printf ("\tm68k_write_memory_16(%sa,%s);\n", to, from);
542 break;
543 case sz_long:
544 insn_n_cycles += 8;
545 if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
546 abort ();
547 printf ("\tm68k_write_memory_32(%sa,%s);\n", to, from);
548 break;
549 default:
550 abort ();
551 }
552 break;
553 case imm:
554 case imm0:
555 case imm1:
556 case imm2:
557 case immi:
558 abort ();
559 break;
560 default:
561 abort ();
562 }
563 }
564
565
genmovemel(uint16_t opcode)566 static void genmovemel (uint16_t opcode)
567 {
568 char getcode[100];
569 int bMovemLong = (table68k[opcode].size == sz_long);
570 int size = bMovemLong ? 4 : 2;
571
572 if (bMovemLong) {
573 strcpy (getcode, "m68k_read_memory_32(srca)");
574 } else {
575 strcpy (getcode, "(int32_t)(int16_t)m68k_read_memory_16(srca)");
576 }
577
578 printf ("\tuint16_t mask = %s;\n", gen_nextiword ());
579 printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
580 printf ("\tretcycles = 0;\n");
581 genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
582 start_brace ();
583 printf ("\twhile (dmask) { m68k_dreg(regs, movem_index1[dmask]) = %s;"
584 " srca += %d; dmask = movem_next[dmask]; retcycles+=%d; }\n",
585 getcode, size, (bMovemLong ? 8 : 4));
586 printf ("\twhile (amask) { m68k_areg(regs, movem_index1[amask]) = %s;"
587 " srca += %d; amask = movem_next[amask]; retcycles+=%d; }\n",
588 getcode, size, (bMovemLong ? 8 : 4));
589
590 if (table68k[opcode].dmode == Aipi)
591 printf ("\tm68k_areg(regs, dstreg) = srca;\n");
592
593 /* Better cycles - experimental! (Thothy) */
594 switch(table68k[opcode].dmode)
595 {
596 case Aind: insn_n_cycles=12; break;
597 case Aipi: insn_n_cycles=12; break;
598 case Ad16: insn_n_cycles=16; break;
599 case Ad8r: insn_n_cycles=18; break;
600 case absw: insn_n_cycles=16; break;
601 case absl: insn_n_cycles=20; break;
602 case PC16: insn_n_cycles=16; break;
603 case PC8r: insn_n_cycles=18; break;
604 }
605 sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles);
606 }
607
genmovemle(uint16_t opcode)608 static void genmovemle (uint16_t opcode)
609 {
610 char putcode[100];
611 int bMovemLong = (table68k[opcode].size == sz_long);
612 int size = bMovemLong ? 4 : 2;
613
614 if (bMovemLong) {
615 strcpy (putcode, "m68k_write_memory_32(srca,");
616 } else {
617 strcpy (putcode, "m68k_write_memory_16(srca,");
618 }
619
620 printf ("\tuint16_t mask = %s;\n", gen_nextiword ());
621 printf ("\tretcycles = 0;\n");
622 genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
623 if (using_prefetch)
624 sync_m68k_pc ();
625
626 start_brace ();
627 if (table68k[opcode].dmode == Apdi) {
628 printf ("\tuint16_t amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
629 printf ("\twhile (amask) { srca -= %d; %s m68k_areg(regs, movem_index2[amask]));"
630 " amask = movem_next[amask]; retcycles+=%d; }\n",
631 size, putcode, (bMovemLong ? 8 : 4));
632 printf ("\twhile (dmask) { srca -= %d; %s m68k_dreg(regs, movem_index2[dmask]));"
633 " dmask = movem_next[dmask]; retcycles+=%d; }\n",
634 size, putcode, (bMovemLong ? 8 : 4));
635 printf ("\tm68k_areg(regs, dstreg) = srca;\n");
636 } else {
637 printf ("\tuint16_t dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
638 printf ("\twhile (dmask) { %s m68k_dreg(regs, movem_index1[dmask])); srca += %d;"
639 " dmask = movem_next[dmask]; retcycles+=%d; }\n",
640 putcode, size, (bMovemLong ? 8 : 4));
641 printf ("\twhile (amask) { %s m68k_areg(regs, movem_index1[amask])); srca += %d;"
642 " amask = movem_next[amask]; retcycles+=%d; }\n",
643 putcode, size, (bMovemLong ? 8 : 4));
644 }
645
646 /* Better cycles - experimental! (Thothy) */
647 switch(table68k[opcode].dmode)
648 {
649 case Aind: insn_n_cycles=8; break;
650 case Apdi: insn_n_cycles=8; break;
651 case Ad16: insn_n_cycles=12; break;
652 case Ad8r: insn_n_cycles=14; break;
653 case absw: insn_n_cycles=12; break;
654 case absl: insn_n_cycles=16; break;
655 }
656 sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles);
657 }
658
659
duplicate_carry(void)660 static void duplicate_carry (void)
661 {
662 printf ("\tCOPY_CARRY;\n");
663 }
664
665 typedef enum
666 {
667 flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn,
668 flag_av, flag_sv
669 }
670 flagtypes;
671
genflags_normal(flagtypes type,wordsizes size,const char * value,const char * src,const char * dst)672 static void genflags_normal (flagtypes type, wordsizes size, const char *value,
673 const char *src, const char *dst)
674 {
675 char vstr[100], sstr[100], dstr[100];
676 char usstr[100], udstr[100];
677 char unsstr[100], undstr[100];
678
679 switch (size) {
680 case sz_byte:
681 strcpy (vstr, "((int8_t)(");
682 strcpy (usstr, "((uint8_t)(");
683 break;
684 case sz_word:
685 strcpy (vstr, "((int16_t)(");
686 strcpy (usstr, "((uint16_t)(");
687 break;
688 case sz_long:
689 strcpy (vstr, "((int32_t)(");
690 strcpy (usstr, "((uint32_t)(");
691 break;
692 default:
693 abort ();
694 }
695 strcpy (unsstr, usstr);
696
697 strcpy (sstr, vstr);
698 strcpy (dstr, vstr);
699 strcat (vstr, value);
700 strcat (vstr, "))");
701 strcat (dstr, dst);
702 strcat (dstr, "))");
703 strcat (sstr, src);
704 strcat (sstr, "))");
705
706 strcpy (udstr, usstr);
707 strcat (udstr, dst);
708 strcat (udstr, "))");
709 strcat (usstr, src);
710 strcat (usstr, "))");
711
712 strcpy (undstr, unsstr);
713 strcat (unsstr, "-");
714 strcat (undstr, "~");
715 strcat (undstr, dst);
716 strcat (undstr, "))");
717 strcat (unsstr, src);
718 strcat (unsstr, "))");
719
720 switch (type) {
721 case flag_logical_noclobber:
722 case flag_logical:
723 case flag_zn:
724 case flag_av:
725 case flag_sv:
726 case flag_addx:
727 case flag_subx:
728 break;
729
730 case flag_add:
731 start_brace ();
732 printf ("uint32_t %s = %s + %s;\n", value, dstr, sstr);
733 break;
734 case flag_sub:
735 case flag_cmp:
736 start_brace ();
737 printf ("uint32_t %s = %s - %s;\n", value, dstr, sstr);
738 break;
739 }
740
741 switch (type) {
742 case flag_logical_noclobber:
743 case flag_logical:
744 case flag_zn:
745 break;
746
747 case flag_add:
748 case flag_sub:
749 case flag_addx:
750 case flag_subx:
751 case flag_cmp:
752 case flag_av:
753 case flag_sv:
754 start_brace ();
755 printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr);
756 printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr);
757 printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr);
758 break;
759 }
760
761 switch (type) {
762 case flag_logical:
763 printf ("\tCLEAR_CZNV;\n");
764 printf ("\tSET_ZFLG (%s == 0);\n", vstr);
765 printf ("\tSET_NFLG (%s < 0);\n", vstr);
766 break;
767 case flag_logical_noclobber:
768 printf ("\tSET_ZFLG (%s == 0);\n", vstr);
769 printf ("\tSET_NFLG (%s < 0);\n", vstr);
770 break;
771 case flag_av:
772 printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
773 break;
774 case flag_sv:
775 printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
776 break;
777 case flag_zn:
778 printf ("\tSET_ZFLG (GET_ZFLG & (%s == 0));\n", vstr);
779 printf ("\tSET_NFLG (%s < 0);\n", vstr);
780 break;
781 case flag_add:
782 printf ("\tSET_ZFLG (%s == 0);\n", vstr);
783 printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
784 printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr);
785 duplicate_carry ();
786 printf ("\tSET_NFLG (flgn != 0);\n");
787 break;
788 case flag_sub:
789 printf ("\tSET_ZFLG (%s == 0);\n", vstr);
790 printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
791 printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
792 duplicate_carry ();
793 printf ("\tSET_NFLG (flgn != 0);\n");
794 break;
795 case flag_addx:
796 printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */
797 printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */
798 duplicate_carry ();
799 break;
800 case flag_subx:
801 printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */
802 printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */
803 duplicate_carry ();
804 break;
805 case flag_cmp:
806 printf ("\tSET_ZFLG (%s == 0);\n", vstr);
807 printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n");
808 printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
809 printf ("\tSET_NFLG (flgn != 0);\n");
810 break;
811 }
812 }
813
genflags(flagtypes type,wordsizes size,const char * value,const char * src,const char * dst)814 static void genflags (flagtypes type, wordsizes size, const char *value,
815 const char *src, const char *dst)
816 {
817 /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have
818 them in the appropriate m68k.h files and use just one copy of this
819 code here. The API can be changed if necessary. */
820 #ifdef OPTIMIZED_FLAGS
821 switch (type) {
822 case flag_add:
823 case flag_sub:
824 start_brace ();
825 printf ("\tuint32_t %s;\n", value);
826 break;
827
828 default:
829 break;
830 }
831
832 /* At least some of those casts are fairly important! */
833 switch (type) {
834 case flag_logical_noclobber:
835 printf ("\t{uint32_t oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n");
836 if (strcmp (value, "0") == 0) {
837 printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n");
838 } else {
839 switch (size) {
840 case sz_byte: printf ("\toptflag_testb ((int8_t)(%s));\n", value); break;
841 case sz_word: printf ("\toptflag_testw ((int16_t)(%s));\n", value); break;
842 case sz_long: printf ("\toptflag_testl ((int32_t)(%s));\n", value); break;
843 }
844 printf ("\tIOR_CZNV (oldcznv);\n");
845 }
846 printf ("\t}\n");
847 return;
848 case flag_logical:
849 if (strcmp (value, "0") == 0) {
850 printf ("\tSET_CZNV (FLAGVAL_Z);\n");
851 } else {
852 switch (size) {
853 case sz_byte: printf ("\toptflag_testb ((int8_t)(%s));\n", value); break;
854 case sz_word: printf ("\toptflag_testw ((int16_t)(%s));\n", value); break;
855 case sz_long: printf ("\toptflag_testl ((int32_t)(%s));\n", value); break;
856 }
857 }
858 return;
859
860 case flag_add:
861 switch (size) {
862 case sz_byte: printf ("\toptflag_addb (%s, (int8_t)(%s), (int8_t)(%s));\n", value, src, dst); break;
863 case sz_word: printf ("\toptflag_addw (%s, (int16_t)(%s), (int16_t)(%s));\n", value, src, dst); break;
864 case sz_long: printf ("\toptflag_addl (%s, (int32_t)(%s), (int32_t)(%s));\n", value, src, dst); break;
865 }
866 return;
867
868 case flag_sub:
869 switch (size) {
870 case sz_byte: printf ("\toptflag_subb (%s, (int8_t)(%s), (int8_t)(%s));\n", value, src, dst); break;
871 case sz_word: printf ("\toptflag_subw (%s, (int16_t)(%s), (int16_t)(%s));\n", value, src, dst); break;
872 case sz_long: printf ("\toptflag_subl (%s, (int32_t)(%s), (int32_t)(%s));\n", value, src, dst); break;
873 }
874 return;
875
876 case flag_cmp:
877 switch (size) {
878 case sz_byte: printf ("\toptflag_cmpb ((int8_t)(%s), (int8_t)(%s));\n", src, dst); break;
879 case sz_word: printf ("\toptflag_cmpw ((int16_t)(%s), (int16_t)(%s));\n", src, dst); break;
880 case sz_long: printf ("\toptflag_cmpl ((int32_t)(%s), (int32_t)(%s));\n", src, dst); break;
881 }
882 return;
883
884 default:
885 break;
886 }
887 #endif
888
889 genflags_normal (type, size, value, src, dst);
890 }
891
force_range_for_rox(const char * var,wordsizes size)892 static void force_range_for_rox (const char *var, wordsizes size)
893 {
894 /* Could do a modulo operation here... which one is faster? */
895 switch (size) {
896 case sz_long:
897 printf ("\tif (%s >= 33) %s -= 33;\n", var, var);
898 break;
899 case sz_word:
900 printf ("\tif (%s >= 34) %s -= 34;\n", var, var);
901 printf ("\tif (%s >= 17) %s -= 17;\n", var, var);
902 break;
903 case sz_byte:
904 printf ("\tif (%s >= 36) %s -= 36;\n", var, var);
905 printf ("\tif (%s >= 18) %s -= 18;\n", var, var);
906 printf ("\tif (%s >= 9) %s -= 9;\n", var, var);
907 break;
908 }
909 }
910
cmask(wordsizes size)911 static const char *cmask (wordsizes size)
912 {
913 switch (size) {
914 case sz_byte: return "0x80";
915 case sz_word: return "0x8000";
916 case sz_long: return "0x80000000";
917 default: abort ();
918 }
919 }
920
source_is_imm1_8(struct instr * i)921 static int source_is_imm1_8 (struct instr *i)
922 {
923 return i->stype == 3;
924 }
925
926
927
gen_opcode(unsigned long int opcode)928 static void gen_opcode (unsigned long int opcode)
929 {
930 struct instr *curi = table68k + opcode;
931 insn_n_cycles = 4;
932
933 /* Store the family of the instruction (used to check for pairing on ST)
934 * and leave some space for patching in the current cycles later */
935 printf ("\tOpcodeFamily = %d; CurrentInstrCycles = \n", curi->mnemo);
936 nCurInstrCycPos = ftell(stdout) - 5;
937
938 start_brace ();
939 m68k_pc_offset = 2;
940
941 switch (curi->plev) {
942 case 0: /* not privileged */
943 break;
944 case 1: /* unprivileged only on 68000 */
945 if (cpu_level == 0)
946 break;
947 if (next_cpu_level < 0)
948 next_cpu_level = 0;
949
950 /* fall through */
951 case 2: /* priviledged */
952 printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
953 need_endlabel = 1;
954 start_brace ();
955 break;
956 case 3: /* privileged if size == word */
957 if (curi->size == sz_byte)
958 break;
959 printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
960 need_endlabel = 1;
961 start_brace ();
962 break;
963 }
964
965 /* Build the opcodes: */
966 switch (curi->mnemo) {
967 case i_OR:
968 case i_AND:
969 case i_EOR:
970 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
971 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
972 printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^');
973 genflags (flag_logical, curi->size, "src", "", "");
974 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
975 if(curi->size==sz_long && curi->dmode==Dreg)
976 {
977 insn_n_cycles += 2;
978 if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi))
979 insn_n_cycles += 2;
980 }
981 break;
982 case i_ORSR:
983 case i_EORSR:
984 printf ("\tMakeSR();\n");
985 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
986 if (curi->size == sz_byte) {
987 printf ("\tsrc &= 0xFF;\n");
988 }
989 printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
990 printf ("\tMakeFromSR();\n");
991 insn_n_cycles = 20;
992 break;
993 case i_ANDSR:
994 printf ("\tMakeSR();\n");
995 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
996 if (curi->size == sz_byte) {
997 printf ("\tsrc |= 0xFF00;\n");
998 }
999 printf ("\tregs.sr &= src;\n");
1000 printf ("\tMakeFromSR();\n");
1001 insn_n_cycles = 20;
1002 break;
1003 case i_SUB:
1004 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1005 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1006 start_brace ();
1007 genflags (flag_sub, curi->size, "newv", "src", "dst");
1008 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1009 if(curi->size==sz_long && curi->dmode==Dreg)
1010 {
1011 insn_n_cycles += 2;
1012 if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi))
1013 insn_n_cycles += 2;
1014 }
1015 break;
1016 case i_SUBA:
1017 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1018 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1019 start_brace ();
1020 printf ("\tuint32_t newv = dst - src;\n");
1021 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1022 if(curi->size==sz_long && curi->smode!=Dreg && curi->smode!=Areg && !(curi->smode>=imm && curi->smode<=immi))
1023 insn_n_cycles += 2;
1024 else
1025 insn_n_cycles += 4;
1026 break;
1027 case i_SUBX:
1028 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1029 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1030 start_brace ();
1031 printf ("\tuint32_t newv = dst - src - (GET_XFLG ? 1 : 0);\n");
1032 genflags (flag_subx, curi->size, "newv", "src", "dst");
1033 genflags (flag_zn, curi->size, "newv", "", "");
1034 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1035 if(curi->smode==Dreg && curi->size==sz_long)
1036 insn_n_cycles=8;
1037 if(curi->smode==Apdi)
1038 {
1039 if(curi->size==sz_long)
1040 insn_n_cycles=30;
1041 else
1042 insn_n_cycles=18;
1043 }
1044 break;
1045 case i_SBCD:
1046 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1047 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1048 start_brace ();
1049 printf ("\tuint16_t newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG ? 1 : 0);\n");
1050 printf ("\tuint16_t newv_hi = (dst & 0xF0) - (src & 0xF0);\n");
1051 printf ("\tuint16_t newv, tmp_newv;\n");
1052 printf ("\tint bcd = 0;\n");
1053 printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n");
1054 printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n");
1055 printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n");
1056 printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG ? 1 : 0)) & 0x300) > 0xFF);\n");
1057 duplicate_carry ();
1058 genflags (flag_zn, curi->size, "newv", "", "");
1059 printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
1060 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1061 if(curi->smode==Dreg) insn_n_cycles=6;
1062 if(curi->smode==Apdi) insn_n_cycles=18;
1063 break;
1064 case i_ADD:
1065 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1066 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1067 start_brace ();
1068 printf("\trefill_prefetch (m68k_getpc(), 2);\n"); // FIXME [NP] For Transbeauce 2 demo, need better prefetch emulation
1069 genflags (flag_add, curi->size, "newv", "src", "dst");
1070 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1071 if(curi->size==sz_long && curi->dmode==Dreg)
1072 {
1073 insn_n_cycles += 2;
1074 if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi))
1075 insn_n_cycles += 2;
1076 }
1077 break;
1078 case i_ADDA:
1079 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1080 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1081 start_brace ();
1082 printf ("\tuint32_t newv = dst + src;\n");
1083 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1084 if(curi->size==sz_long && curi->smode!=Dreg && curi->smode!=Areg && !(curi->smode>=imm && curi->smode<=immi))
1085 insn_n_cycles += 2;
1086 else
1087 insn_n_cycles += 4;
1088 break;
1089 case i_ADDX:
1090 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1091 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1092 start_brace ();
1093 printf ("\tuint32_t newv = dst + src + (GET_XFLG ? 1 : 0);\n");
1094 genflags (flag_addx, curi->size, "newv", "src", "dst");
1095 genflags (flag_zn, curi->size, "newv", "", "");
1096 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1097 if(curi->smode==Dreg && curi->size==sz_long)
1098 insn_n_cycles=8;
1099 if(curi->smode==Apdi)
1100 {
1101 if(curi->size==sz_long)
1102 insn_n_cycles=30;
1103 else
1104 insn_n_cycles=18;
1105 }
1106 break;
1107 case i_ABCD:
1108 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1109 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1110 start_brace ();
1111 printf ("\tuint16_t newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG ? 1 : 0);\n");
1112 printf ("\tuint16_t newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
1113 printf ("\tuint16_t newv, tmp_newv;\n");
1114 printf ("\tint cflg;\n");
1115 printf ("\tnewv = tmp_newv = newv_hi + newv_lo;");
1116 printf ("\tif (newv_lo > 9) { newv += 6; }\n");
1117 printf ("\tcflg = (newv & 0x3F0) > 0x90;\n");
1118 printf ("\tif (cflg) newv += 0x60;\n");
1119 printf ("\tSET_CFLG (cflg);\n");
1120 duplicate_carry ();
1121 genflags (flag_zn, curi->size, "newv", "", "");
1122 printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
1123 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1124 if(curi->smode==Dreg) insn_n_cycles=6;
1125 if(curi->smode==Apdi) insn_n_cycles=18;
1126 break;
1127 case i_NEG:
1128 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1129 start_brace ();
1130 genflags (flag_sub, curi->size, "dst", "src", "0");
1131 genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1132 if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2;
1133 break;
1134 case i_NEGX:
1135 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1136 start_brace ();
1137 printf ("\tuint32_t newv = 0 - src - (GET_XFLG ? 1 : 0);\n");
1138 genflags (flag_subx, curi->size, "newv", "src", "0");
1139 genflags (flag_zn, curi->size, "newv", "", "");
1140 genastore ("newv", curi->smode, "srcreg", curi->size, "src");
1141 if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2;
1142 break;
1143 case i_NBCD:
1144 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1145 start_brace ();
1146 printf ("\tuint16_t newv_lo = - (src & 0xF) - (GET_XFLG ? 1 : 0);\n");
1147 printf ("\tuint16_t newv_hi = - (src & 0xF0);\n");
1148 printf ("\tuint16_t newv;\n");
1149 printf ("\tint cflg;\n");
1150 printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
1151 printf ("\tnewv = newv_hi + newv_lo;");
1152 printf ("\tcflg = (newv & 0x1F0) > 0x90;\n");
1153 printf ("\tif (cflg) newv -= 0x60;\n");
1154 printf ("\tSET_CFLG (cflg);\n");
1155 duplicate_carry();
1156 genflags (flag_zn, curi->size, "newv", "", "");
1157 genastore ("newv", curi->smode, "srcreg", curi->size, "src");
1158 if(curi->smode==Dreg) insn_n_cycles += 2;
1159 break;
1160 case i_CLR:
1161 genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1162
1163 /* [NP] CLR does a read before the write only on 68000 */
1164 /* but there's no cycle penalty for doing the read */
1165 if ( curi->smode != Dreg ) // only if destination is memory
1166 {
1167 if (curi->size==sz_byte)
1168 printf ("\tint8_t src = m68k_read_memory_8(srca);\n");
1169 else if (curi->size==sz_word)
1170 printf ("\tint16_t src = m68k_read_memory_16(srca);\n");
1171 else if (curi->size==sz_long)
1172 printf ("\tint32_t src = m68k_read_memory_32(srca);\n");
1173 }
1174
1175 genflags (flag_logical, curi->size, "0", "", "");
1176 genastore ("0", curi->smode, "srcreg", curi->size, "src");
1177 if(curi->size==sz_long)
1178 {
1179 if(curi->smode==Dreg)
1180 insn_n_cycles += 2;
1181 else
1182 insn_n_cycles += 4;
1183 }
1184 if(curi->smode!=Dreg)
1185 insn_n_cycles += 4;
1186 break;
1187 case i_NOT:
1188 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1189 start_brace ();
1190 printf ("\tuint32_t dst = ~src;\n");
1191 genflags (flag_logical, curi->size, "dst", "", "");
1192 genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1193 if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2;
1194 break;
1195 case i_TST:
1196 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1197 genflags (flag_logical, curi->size, "src", "", "");
1198 break;
1199 case i_BTST:
1200 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1201 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1202 if (curi->size == sz_byte)
1203 printf ("\tsrc &= 7;\n");
1204 else
1205 printf ("\tsrc &= 31;\n");
1206 printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1207 if(curi->dmode==Dreg) insn_n_cycles += 2;
1208 break;
1209 case i_BCHG:
1210 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1211 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1212 if (curi->size == sz_byte)
1213 printf ("\tsrc &= 7;\n");
1214 else
1215 printf ("\tsrc &= 31;\n");
1216 printf ("\tdst ^= (1 << src);\n");
1217 printf ("\tSET_ZFLG (((uint32_t)dst & (1 << src)) >> src);\n");
1218 genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1219 if(curi->dmode==Dreg) insn_n_cycles += 4;
1220 break;
1221 case i_BCLR:
1222 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1223 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1224 if (curi->size == sz_byte)
1225 printf ("\tsrc &= 7;\n");
1226 else
1227 printf ("\tsrc &= 31;\n");
1228 printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1229 printf ("\tdst &= ~(1 << src);\n");
1230 genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1231 if(curi->dmode==Dreg) insn_n_cycles += 6;
1232 /* [NP] BCLR #n,Dx takes 12 cycles instead of 14 if n<16 */
1233 if((curi->smode==imm1) && (curi->dmode==Dreg))
1234 printf ("\tif ( src < 16 ) { m68k_incpc(4); return 12; }\n");
1235 /* [NP] BCLR Dy,Dx takes 8 cycles instead of 10 if Dy<16 */
1236 if((curi->smode==Dreg) && (curi->dmode==Dreg))
1237 printf ("\tif ( src < 16 ) { m68k_incpc(2); return 8; }\n");
1238 break;
1239 case i_BSET:
1240 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1241 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1242 if (curi->size == sz_byte)
1243 printf ("\tsrc &= 7;\n");
1244 else
1245 printf ("\tsrc &= 31;\n");
1246 printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1247 printf ("\tdst |= (1 << src);\n");
1248 genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1249 if(curi->dmode==Dreg) insn_n_cycles += 4;
1250 break;
1251 case i_CMPM:
1252 case i_CMP:
1253 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1254 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1255 start_brace ();
1256 genflags (flag_cmp, curi->size, "newv", "src", "dst");
1257 if(curi->size==sz_long && curi->dmode==Dreg)
1258 insn_n_cycles += 2;
1259 break;
1260 case i_CMPA:
1261 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1262 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1263 start_brace ();
1264 genflags (flag_cmp, sz_long, "newv", "src", "dst");
1265 insn_n_cycles += 2;
1266 break;
1267 /* The next two are coded a little unconventional, but they are doing
1268 * weird things... */
1269 case i_MVPRM:
1270 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1271
1272 printf ("\tuint32_t memp = m68k_areg(regs, dstreg) + (int32_t)(int16_t)%s;\n", gen_nextiword ());
1273 if (curi->size == sz_word) {
1274 printf ("\tm68k_write_memory_8(memp, src >> 8); m68k_write_memory_8(memp + 2, src);\n");
1275 } else {
1276 printf ("\tm68k_write_memory_8(memp, src >> 24); m68k_write_memory_8(memp + 2, src >> 16);\n");
1277 printf ("\tm68k_write_memory_8(memp + 4, src >> 8); m68k_write_memory_8(memp + 6, src);\n");
1278 }
1279 if(curi->size==sz_long) insn_n_cycles=24; else insn_n_cycles=16;
1280 break;
1281 case i_MVPMR:
1282 printf ("\tuint32_t memp = m68k_areg(regs, srcreg) + (int32_t)(int16_t)%s;\n", gen_nextiword ());
1283 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1284 if (curi->size == sz_word) {
1285 printf ("\tuint16_t val = (m68k_read_memory_8(memp) << 8) + m68k_read_memory_8(memp + 2);\n");
1286 } else {
1287 printf ("\tuint32_t val = (m68k_read_memory_8(memp) << 24) + (m68k_read_memory_8(memp + 2) << 16)\n");
1288 printf (" + (m68k_read_memory_8(memp + 4) << 8) + m68k_read_memory_8(memp + 6);\n");
1289 }
1290 genastore ("val", curi->dmode, "dstreg", curi->size, "dst");
1291 if(curi->size==sz_long) insn_n_cycles=24; else insn_n_cycles=16;
1292 break;
1293 case i_MOVE:
1294 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1295 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1296
1297 /* [NP] genamode counts 2 cycles if dest is -(An), this is wrong. */
1298 /* For move dest (An), (An)+ and -(An) take the same time */
1299 /* (for other instr, dest -(An) really takes 2 cycles more) */
1300 if ( curi->dmode == Apdi )
1301 insn_n_cycles -= 2; /* correct the wrong cycle count for -(An) */
1302
1303 genflags (flag_logical, curi->size, "src", "", "");
1304 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1305 break;
1306 case i_MOVEA:
1307 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1308 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1309 if (curi->size == sz_word) {
1310 printf ("\tuint32_t val = (int32_t)(int16_t)src;\n");
1311 } else {
1312 printf ("\tuint32_t val = src;\n");
1313 }
1314 genastore ("val", curi->dmode, "dstreg", sz_long, "dst");
1315 break;
1316 case i_MVSR2: /* Move from SR */
1317 genamode (curi->smode, "srcreg", sz_word, "src", 2, 0);
1318 printf ("\tMakeSR();\n");
1319 if (curi->size == sz_byte)
1320 genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src");
1321 else
1322 genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src");
1323 if (curi->smode==Dreg) insn_n_cycles += 2; else insn_n_cycles += 4;
1324 break;
1325 case i_MV2SR: /* Move to SR */
1326 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1327 if (curi->size == sz_byte)
1328 printf ("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
1329 else {
1330 printf ("\tregs.sr = src;\n");
1331 }
1332 printf ("\tMakeFromSR();\n");
1333 insn_n_cycles += 8;
1334 break;
1335 case i_SWAP:
1336 genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1337 start_brace ();
1338 printf ("\tuint32_t dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
1339 genflags (flag_logical, sz_long, "dst", "", "");
1340 genastore ("dst", curi->smode, "srcreg", sz_long, "src");
1341 break;
1342 case i_EXG:
1343 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1344 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1345 genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1346 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1347 insn_n_cycles = 6;
1348 break;
1349 case i_EXT:
1350 genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1351 start_brace ();
1352 switch (curi->size) {
1353 case sz_byte: printf ("\tuint32_t dst = (int32_t)(int8_t)src;\n"); break;
1354 case sz_word: printf ("\tuint16_t dst = (int16_t)(int8_t)src;\n"); break;
1355 case sz_long: printf ("\tuint32_t dst = (int32_t)(int16_t)src;\n"); break;
1356 default: abort ();
1357 }
1358 genflags (flag_logical,
1359 curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
1360 genastore ("dst", curi->smode, "srcreg",
1361 curi->size == sz_word ? sz_word : sz_long, "src");
1362 break;
1363 case i_MVMEL:
1364 genmovemel (opcode);
1365 break;
1366 case i_MVMLE:
1367 genmovemle (opcode);
1368 break;
1369 case i_TRAP:
1370 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1371 sync_m68k_pc ();
1372 printf ("\tException(src+32,0,M68000_EXC_SRC_CPU);\n");
1373 m68k_pc_offset = 0;
1374 break;
1375 case i_MVR2USP:
1376 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1377 printf ("\tregs.usp = src;\n");
1378 break;
1379 case i_MVUSP2R:
1380 genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1381 genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src");
1382 break;
1383 case i_RESET:
1384 //JLH:Not needed printf ("\tcustomreset();\n");
1385 insn_n_cycles = 132; /* I am not so sure about this!? - Thothy */
1386 break;
1387 case i_NOP:
1388 break;
1389 case i_STOP:
1390 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1391 printf ("\tregs.sr = src;\n");
1392 printf ("\tMakeFromSR();\n");
1393 printf ("\tm68k_setstopped(1);\n");
1394 insn_n_cycles = 4;
1395 break;
1396 case i_RTE:
1397 if (cpu_level == 0) {
1398 genamode (Aipi, "7", sz_word, "sr", 1, 0);
1399 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1400 printf ("\tregs.sr = sr; m68k_setpc_rte(pc);\n");
1401 fill_prefetch_0 ();
1402 printf ("\tMakeFromSR();\n");
1403 } else {
1404 int old_brace_level = n_braces;
1405 if (next_cpu_level < 0)
1406 next_cpu_level = 0;
1407 printf ("\tuint16_t newsr; uint32_t newpc; for (;;) {\n");
1408 genamode (Aipi, "7", sz_word, "sr", 1, 0);
1409 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1410 genamode (Aipi, "7", sz_word, "format", 1, 0);
1411 printf ("\tnewsr = sr; newpc = pc;\n");
1412 printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n");
1413 printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n");
1414 printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }\n");
1415 printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }\n");
1416 printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }\n");
1417 printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }\n");
1418 printf ("\telse if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; }\n");
1419 printf ("\telse { Exception(14,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1420 printf ("\tregs.sr = newsr; MakeFromSR();\n}\n");
1421 pop_braces (old_brace_level);
1422 printf ("\tregs.sr = newsr; MakeFromSR();\n");
1423 printf ("\tm68k_setpc_rte(newpc);\n");
1424 fill_prefetch_0 ();
1425 need_endlabel = 1;
1426 }
1427 /* PC is set and prefetch filled. */
1428 m68k_pc_offset = 0;
1429 insn_n_cycles = 20;
1430 break;
1431 case i_RTD:
1432 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1433 genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0);
1434 printf ("\tm68k_areg(regs, 7) += offs;\n");
1435 printf ("\tm68k_setpc_rte(pc);\n");
1436 fill_prefetch_0 ();
1437 /* PC is set and prefetch filled. */
1438 m68k_pc_offset = 0;
1439 break;
1440 case i_LINK:
1441 genamode (Apdi, "7", sz_long, "old", 2, 0);
1442 genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1443 genastore ("src", Apdi, "7", sz_long, "old");
1444 genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src");
1445 genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1446 printf ("\tm68k_areg(regs, 7) += offs;\n");
1447 break;
1448 case i_UNLK:
1449 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1450 printf ("\tm68k_areg(regs, 7) = src;\n");
1451 genamode (Aipi, "7", sz_long, "old", 1, 0);
1452 genastore ("old", curi->smode, "srcreg", curi->size, "src");
1453 break;
1454 case i_RTS:
1455 printf ("\tm68k_do_rts();\n");
1456 fill_prefetch_0 ();
1457 m68k_pc_offset = 0;
1458 insn_n_cycles = 16;
1459 break;
1460 case i_TRAPV:
1461 sync_m68k_pc ();
1462 printf ("\tif (GET_VFLG) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1463 need_endlabel = 1;
1464 break;
1465 case i_RTR:
1466 printf ("\tMakeSR();\n");
1467 genamode (Aipi, "7", sz_word, "sr", 1, 0);
1468 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1469 printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
1470 printf ("\tregs.sr |= sr; m68k_setpc(pc);\n");
1471 fill_prefetch_0 ();
1472 printf ("\tMakeFromSR();\n");
1473 m68k_pc_offset = 0;
1474 insn_n_cycles = 20;
1475 break;
1476 case i_JSR:
1477 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1478 printf ("\tuint32_t oldpc = m68k_getpc () + %d;\n", m68k_pc_offset);
1479 if (using_exception_3) {
1480 printf ("\tif (srca & 1) {\n");
1481 printf ("\t\tlast_addr_for_exception_3 = oldpc;\n");
1482 printf ("\t\tlast_fault_for_exception_3 = srca;\n");
1483 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1484 printf ("\t}\n");
1485 need_endlabel = 1;
1486 }
1487 printf ("\tm68k_do_jsr(m68k_getpc() + %d, srca);\n", m68k_pc_offset);
1488 fill_prefetch_0 ();
1489 m68k_pc_offset = 0;
1490 switch(curi->smode)
1491 {
1492 case Aind: insn_n_cycles=16; break;
1493 case Ad16: insn_n_cycles=18; break;
1494 case Ad8r: insn_n_cycles=22; break;
1495 case absw: insn_n_cycles=18; break;
1496 case absl: insn_n_cycles=20; break;
1497 case PC16: insn_n_cycles=18; break;
1498 case PC8r: insn_n_cycles=22; break;
1499 }
1500 break;
1501 case i_JMP:
1502 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1503 if (using_exception_3) {
1504 printf ("\tif (srca & 1) {\n");
1505 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 6;\n");
1506 printf ("\t\tlast_fault_for_exception_3 = srca;\n");
1507 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1508 printf ("\t}\n");
1509 need_endlabel = 1;
1510 }
1511 printf ("\tm68k_setpc(srca);\n");
1512 fill_prefetch_0 ();
1513 m68k_pc_offset = 0;
1514 switch(curi->smode)
1515 {
1516 case Aind: insn_n_cycles=8; break;
1517 case Ad16: insn_n_cycles=10; break;
1518 case Ad8r: insn_n_cycles=14; break;
1519 case absw: insn_n_cycles=10; break;
1520 case absl: insn_n_cycles=12; break;
1521 case PC16: insn_n_cycles=10; break;
1522 case PC8r: insn_n_cycles=14; break;
1523 }
1524 break;
1525 case i_BSR:
1526 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1527 printf ("\tint32_t s = (int32_t)src + 2;\n");
1528 if (using_exception_3) {
1529 printf ("\tif (src & 1) {\n");
1530 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ?
1531 printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + s;\n");
1532 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1533 printf ("\t}\n");
1534 need_endlabel = 1;
1535 }
1536 printf ("\tm68k_do_bsr(m68k_getpc() + %d, s);\n", m68k_pc_offset);
1537 fill_prefetch_0 ();
1538 m68k_pc_offset = 0;
1539 insn_n_cycles = 18;
1540 break;
1541 case i_Bcc:
1542 if (curi->size == sz_long) {
1543 if (cpu_level < 2) {
1544 printf ("\tm68k_incpc(2);\n");
1545 printf ("\tif (!cctrue(%d)) goto %s;\n", curi->cc, endlabelstr);
1546 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n");
1547 printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 1;\n");
1548 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1549 need_endlabel = 1;
1550 } else {
1551 if (next_cpu_level < 1)
1552 next_cpu_level = 1;
1553 }
1554 }
1555 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1556 printf ("\tif (!cctrue(%d)) goto didnt_jump;\n", curi->cc);
1557 if (using_exception_3) {
1558 printf ("\tif (src & 1) {\n");
1559 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ?
1560 printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (int32_t)src;\n");
1561 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1562 printf ("\t}\n");
1563 need_endlabel = 1;
1564 }
1565 printf ("\tm68k_incpc ((int32_t)src + 2);\n");
1566 fill_prefetch_0 ();
1567 printf ("\treturn 10;\n");
1568 printf ("didnt_jump:;\n");
1569 need_endlabel = 1;
1570 insn_n_cycles = (curi->size == sz_byte) ? 8 : 12;
1571 break;
1572 case i_LEA:
1573 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1574 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1575 genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
1576 /* Set correct cycles: According to the M68K User Manual, LEA takes 12
1577 * cycles in Ad8r and PC8r mode, but it takes 14 (or 16) cycles on a real ST: */
1578 if (curi->smode == Ad8r || curi->smode == PC8r)
1579 insn_n_cycles = 14;
1580 break;
1581 case i_PEA:
1582 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1583 genamode (Apdi, "7", sz_long, "dst", 2, 0);
1584 genastore ("srca", Apdi, "7", sz_long, "dst");
1585 /* Set correct cycles: */
1586 switch(curi->smode)
1587 {
1588 case Aind: insn_n_cycles=12; break;
1589 case Ad16: insn_n_cycles=16; break;
1590 /* Note: according to the M68K User Manual, PEA takes 20 cycles for
1591 * the Ad8r mode, but on a real ST, it takes 22 (or 24) cycles! */
1592 case Ad8r: insn_n_cycles=22; break;
1593 case absw: insn_n_cycles=16; break;
1594 case absl: insn_n_cycles=20; break;
1595 case PC16: insn_n_cycles=16; break;
1596 /* Note: PEA with PC8r takes 20 cycles according to the User Manual,
1597 * but it takes 22 (or 24) cycles on a real ST: */
1598 case PC8r: insn_n_cycles=22; break;
1599 }
1600 break;
1601 case i_DBcc:
1602 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1603 genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1604
1605 printf ("\tif (!cctrue(%d)) {\n\t", curi->cc);
1606 genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src");
1607
1608 printf ("\t\tif (src) {\n");
1609 if (using_exception_3) {
1610 printf ("\t\t\tif (offs & 1) {\n");
1611 printf ("\t\t\tlast_addr_for_exception_3 = m68k_getpc() + 2 + 2;\n"); // [NP] last_addr is pc+4, not pc+2
1612 printf ("\t\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (int32_t)offs + 2;\n");
1613 printf ("\t\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1614 printf ("\t\t}\n");
1615 need_endlabel = 1;
1616 }
1617 printf ("\t\t\tm68k_incpc((int32_t)offs + 2);\n");
1618 fill_prefetch_0 ();
1619 printf ("\t\t\treturn 10;\n");
1620 printf ("\t\t} else {\n\t\t\t");
1621 {
1622 int tmp_offset = m68k_pc_offset;
1623 sync_m68k_pc(); /* not so nice to call it here... */
1624 m68k_pc_offset = tmp_offset;
1625 }
1626 printf ("\t\t\treturn 14;\n");
1627 printf ("\t\t}\n");
1628 printf ("\t}\n");
1629 insn_n_cycles = 12;
1630 need_endlabel = 1;
1631 break;
1632 case i_Scc:
1633 genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1634 start_brace ();
1635 printf ("\tint val = cctrue(%d) ? 0xff : 0;\n", curi->cc);
1636 genastore ("val", curi->smode, "srcreg", curi->size, "src");
1637 if (curi->smode!=Dreg) insn_n_cycles += 4;
1638 else
1639 { /* [NP] if result is TRUE, we return 6 instead of 4 */
1640 printf ("\tif (val) { m68k_incpc(2) ; return 4+2; }\n");
1641 }
1642 break;
1643 case i_DIVU:
1644 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1645 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1646 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1647 sync_m68k_pc ();
1648 /* Clear V flag when dividing by zero - Alcatraz Odyssey demo depends
1649 * on this (actually, it's doing a DIVS). */
1650 printf ("\tif (src == 0) { SET_VFLG (0); Exception (5, oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr);
1651 printf ("\tuint32_t newv = (uint32_t)dst / (uint32_t)(uint16_t)src;\n");
1652 printf ("\tuint32_t rem = (uint32_t)dst %% (uint32_t)(uint16_t)src;\n");
1653 /* The N flag appears to be set each time there is an overflow.
1654 * Weird. */
1655 printf ("\tif (newv > 0xffff) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n");
1656 genflags (flag_logical, sz_word, "newv", "", "");
1657 printf ("\tnewv = (newv & 0xffff) | ((uint32_t)rem << 16);\n");
1658 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1659 printf ("\t}\n");
1660 printf ("\t}\n");
1661 // insn_n_cycles += 136;
1662 printf ("\tretcycles = getDivu68kCycles((uint32_t)dst, (uint16_t)src);\n");
1663 sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles);
1664 need_endlabel = 1;
1665 break;
1666 case i_DIVS:
1667 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1668 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1669 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1670 sync_m68k_pc ();
1671 printf ("\tif (src == 0) { SET_VFLG (0); Exception(5,oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr);
1672 printf ("\tint32_t newv = (int32_t)dst / (int32_t)(int16_t)src;\n");
1673 printf ("\tuint16_t rem = (int32_t)dst %% (int32_t)(int16_t)src;\n");
1674 printf ("\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n");
1675 printf ("\tif (((int16_t)rem < 0) != ((int32_t)dst < 0)) rem = -rem;\n");
1676 genflags (flag_logical, sz_word, "newv", "", "");
1677 printf ("\tnewv = (newv & 0xffff) | ((uint32_t)rem << 16);\n");
1678 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1679 printf ("\t}\n");
1680 printf ("\t}\n");
1681 // insn_n_cycles += 154;
1682 printf ("\tretcycles = getDivs68kCycles((int32_t)dst, (int16_t)src);\n");
1683 sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles);
1684 need_endlabel = 1;
1685 break;
1686 case i_MULU:
1687 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1688 genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
1689 start_brace ();
1690 printf ("\tuint32_t newv = (uint32_t)(uint16_t)dst * (uint32_t)(uint16_t)src;\n");
1691 genflags (flag_logical, sz_long, "newv", "", "");
1692 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1693 /* [NP] number of cycles is 38 + 2n + ea time ; n is the number of 1 bits in src */
1694 insn_n_cycles += 38-4; /* insn_n_cycles is already initialized to 4 instead of 0 */
1695 printf ("\twhile (src) { if (src & 1) retcycles++; src = (uint16_t)src >> 1; }\n");
1696 sprintf(exactCpuCycles," return (%i+retcycles*2);", insn_n_cycles);
1697 break;
1698 case i_MULS:
1699 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1700 genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
1701 start_brace ();
1702 printf ("\tuint32_t newv = (int32_t)(int16_t)dst * (int32_t)(int16_t)src;\n");
1703 printf ("\tuint32_t src2;\n");
1704 genflags (flag_logical, sz_long, "newv", "", "");
1705 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1706 /* [NP] number of cycles is 38 + 2n + ea time ; n is the number of 01 or 10 patterns in src expanded to 17 bits */
1707 insn_n_cycles += 38-4; /* insn_n_cycles is already initialized to 4 instead of 0 */
1708 printf ("\tsrc2 = ((uint32_t)src) << 1;\n");
1709 printf ("\twhile (src2) { if ( ( (src2 & 3) == 1 ) || ( (src2 & 3) == 2 ) ) retcycles++; src2 >>= 1; }\n");
1710 sprintf(exactCpuCycles," return (%i+retcycles*2);", insn_n_cycles);
1711 break;
1712 case i_CHK:
1713 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1714 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1715 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1716 sync_m68k_pc ();
1717 printf ("\tif ((int32_t)dst < 0) { SET_NFLG (1); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1718 printf ("\telse if (dst > src) { SET_NFLG (0); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1719 need_endlabel = 1;
1720 insn_n_cycles += 6;
1721 break;
1722
1723 case i_CHK2:
1724 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1725 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
1726 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1727 printf ("\t{int32_t upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
1728 switch (curi->size) {
1729 case sz_byte:
1730 printf ("\tlower=(int32_t)(int8_t)m68k_read_memory_8(dsta); upper = (int32_t)(int8_t)m68k_read_memory_8(dsta+1);\n");
1731 printf ("\tif ((extra & 0x8000) == 0) reg = (int32_t)(int8_t)reg;\n");
1732 break;
1733 case sz_word:
1734 printf ("\tlower=(int32_t)(int16_t)m68k_read_memory_16(dsta); upper = (int32_t)(int16_t)m68k_read_memory_16(dsta+2);\n");
1735 printf ("\tif ((extra & 0x8000) == 0) reg = (int32_t)(int16_t)reg;\n");
1736 break;
1737 case sz_long:
1738 printf ("\tlower=m68k_read_memory_32(dsta); upper = m68k_read_memory_32(dsta+4);\n");
1739 break;
1740 default:
1741 abort ();
1742 }
1743 printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
1744 printf ("\tSET_CFLG (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
1745 sync_m68k_pc ();
1746 printf ("\tif ((extra & 0x800) && GET_CFLG) { Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n}\n", endlabelstr);
1747 need_endlabel = 1;
1748 break;
1749
1750 case i_ASR:
1751 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1752 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1753 start_brace ();
1754 switch (curi->size) {
1755 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1756 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1757 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1758 default: abort ();
1759 }
1760 printf ("\tuint32_t sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1);
1761 printf ("\tcnt &= 63;\n");
1762 printf ("\tretcycles = cnt;\n");
1763 printf ("\tCLEAR_CZNV;\n");
1764 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1765 printf ("\t\tval = %s & (uint32_t)-sign;\n", bit_mask (curi->size));
1766 printf ("\t\tSET_CFLG (sign);\n");
1767 duplicate_carry ();
1768 if (source_is_imm1_8 (curi))
1769 printf ("\t} else {\n");
1770 else
1771 printf ("\t} else if (cnt > 0) {\n");
1772 printf ("\t\tval >>= cnt - 1;\n");
1773 printf ("\t\tSET_CFLG (val & 1);\n");
1774 duplicate_carry ();
1775 printf ("\t\tval >>= 1;\n");
1776 printf ("\t\tval |= (%s << (%d - cnt)) & (uint32_t)-sign;\n",
1777 bit_mask (curi->size),
1778 bit_size (curi->size));
1779 printf ("\t\tval &= %s;\n", bit_mask (curi->size));
1780 printf ("\t}\n");
1781 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1782 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1783 if(curi->size==sz_long)
1784 strcpy(exactCpuCycles," return (8+retcycles*2);");
1785 else
1786 strcpy(exactCpuCycles," return (6+retcycles*2);");
1787 break;
1788 case i_ASL:
1789 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1790 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1791 start_brace ();
1792 switch (curi->size) {
1793 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1794 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1795 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1796 default: abort ();
1797 }
1798 printf ("\tcnt &= 63;\n");
1799 printf ("\tretcycles = cnt;\n");
1800 printf ("\tCLEAR_CZNV;\n");
1801 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1802 printf ("\t\tSET_VFLG (val != 0);\n");
1803 printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
1804 bit_size (curi->size));
1805 duplicate_carry ();
1806 printf ("\t\tval = 0;\n");
1807 if (source_is_imm1_8 (curi))
1808 printf ("\t} else {\n");
1809 else
1810 printf ("\t} else if (cnt > 0) {\n");
1811 printf ("\t\tuint32_t mask = (%s << (%d - cnt)) & %s;\n",
1812 bit_mask (curi->size),
1813 bit_size (curi->size) - 1,
1814 bit_mask (curi->size));
1815 printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n");
1816 printf ("\t\tval <<= cnt - 1;\n");
1817 printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1818 duplicate_carry ();
1819 printf ("\t\tval <<= 1;\n");
1820 printf ("\t\tval &= %s;\n", bit_mask (curi->size));
1821 printf ("\t}\n");
1822 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1823 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1824 if(curi->size==sz_long)
1825 strcpy(exactCpuCycles," return (8+retcycles*2);");
1826 else
1827 strcpy(exactCpuCycles," return (6+retcycles*2);");
1828 break;
1829 case i_LSR:
1830 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1831 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1832 start_brace ();
1833 switch (curi->size) {
1834 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1835 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1836 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1837 default: abort ();
1838 }
1839 printf ("\tcnt &= 63;\n");
1840 printf ("\tretcycles = cnt;\n");
1841 printf ("\tCLEAR_CZNV;\n");
1842 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1843 printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n",
1844 bit_size (curi->size), bit_size (curi->size) - 1);
1845 duplicate_carry ();
1846 printf ("\t\tval = 0;\n");
1847 if (source_is_imm1_8 (curi))
1848 printf ("\t} else {\n");
1849 else
1850 printf ("\t} else if (cnt > 0) {\n");
1851 printf ("\t\tval >>= cnt - 1;\n");
1852 printf ("\t\tSET_CFLG (val & 1);\n");
1853 duplicate_carry ();
1854 printf ("\t\tval >>= 1;\n");
1855 printf ("\t}\n");
1856 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1857 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1858 if(curi->size==sz_long)
1859 strcpy(exactCpuCycles," return (8+retcycles*2);");
1860 else
1861 strcpy(exactCpuCycles," return (6+retcycles*2);");
1862 break;
1863 case i_LSL:
1864 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1865 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1866 start_brace ();
1867 switch (curi->size) {
1868 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1869 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1870 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1871 default: abort ();
1872 }
1873 printf ("\tcnt &= 63;\n");
1874 printf ("\tretcycles = cnt;\n");
1875 printf ("\tCLEAR_CZNV;\n");
1876 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1877 printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
1878 bit_size (curi->size));
1879 duplicate_carry ();
1880 printf ("\t\tval = 0;\n");
1881 if (source_is_imm1_8 (curi))
1882 printf ("\t} else {\n");
1883 else
1884 printf ("\t} else if (cnt > 0) {\n");
1885 printf ("\t\tval <<= (cnt - 1);\n");
1886 printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1887 duplicate_carry ();
1888 printf ("\t\tval <<= 1;\n");
1889 printf ("\tval &= %s;\n", bit_mask (curi->size));
1890 printf ("\t}\n");
1891 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1892 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1893 if(curi->size==sz_long)
1894 strcpy(exactCpuCycles," return (8+retcycles*2);");
1895 else
1896 strcpy(exactCpuCycles," return (6+retcycles*2);");
1897 break;
1898 case i_ROL:
1899 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1900 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1901 start_brace ();
1902 switch (curi->size) {
1903 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1904 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1905 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1906 default: abort ();
1907 }
1908 printf ("\tcnt &= 63;\n");
1909 printf ("\tretcycles = cnt;\n");
1910 printf ("\tCLEAR_CZNV;\n");
1911 if (source_is_imm1_8 (curi))
1912 printf ("{");
1913 else
1914 printf ("\tif (cnt > 0) {\n");
1915 printf ("\tuint32_t loval;\n");
1916 printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
1917 printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size));
1918 printf ("\tval <<= cnt;\n");
1919 printf ("\tval |= loval;\n");
1920 printf ("\tval &= %s;\n", bit_mask (curi->size));
1921 printf ("\tSET_CFLG (val & 1);\n");
1922 printf ("}\n");
1923 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1924 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1925 if(curi->size==sz_long)
1926 strcpy(exactCpuCycles," return (8+retcycles*2);");
1927 else
1928 strcpy(exactCpuCycles," return (6+retcycles*2);");
1929 break;
1930 case i_ROR:
1931 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1932 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1933 start_brace ();
1934 switch (curi->size) {
1935 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1936 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1937 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1938 default: abort ();
1939 }
1940 printf ("\tcnt &= 63;\n");
1941 printf ("\tretcycles = cnt;\n");
1942 printf ("\tCLEAR_CZNV;\n");
1943 if (source_is_imm1_8 (curi))
1944 printf ("{");
1945 else
1946 printf ("\tif (cnt > 0) {");
1947 printf ("\tuint32_t hival;\n");
1948 printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
1949 printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size));
1950 printf ("\tval >>= cnt;\n");
1951 printf ("\tval |= hival;\n");
1952 printf ("\tval &= %s;\n", bit_mask (curi->size));
1953 printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1954 printf ("\t}\n");
1955 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1956 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1957 if(curi->size==sz_long)
1958 strcpy(exactCpuCycles," return (8+retcycles*2);");
1959 else
1960 strcpy(exactCpuCycles," return (6+retcycles*2);");
1961 break;
1962 case i_ROXL:
1963 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1964 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1965 start_brace ();
1966 switch (curi->size) {
1967 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1968 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1969 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1970 default: abort ();
1971 }
1972 printf ("\tcnt &= 63;\n");
1973 printf ("\tretcycles = cnt;\n");
1974 printf ("\tCLEAR_CZNV;\n");
1975 if (source_is_imm1_8 (curi))
1976 printf ("{");
1977 else {
1978 force_range_for_rox ("cnt", curi->size);
1979 printf ("\tif (cnt > 0) {\n");
1980 }
1981 printf ("\tcnt--;\n");
1982 printf ("\t{\n\tuint32_t carry;\n");
1983 printf ("\tuint32_t loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1);
1984 printf ("\tcarry = loval & 1;\n");
1985 printf ("\tval = (((val << 1) | GET_XFLG) << cnt) | (loval >> 1);\n");
1986 printf ("\tSET_XFLG (carry);\n");
1987 printf ("\tval &= %s;\n", bit_mask (curi->size));
1988 printf ("\t} }\n");
1989 printf ("\tSET_CFLG (GET_XFLG);\n");
1990 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1991 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1992 if(curi->size==sz_long)
1993 strcpy(exactCpuCycles," return (8+retcycles*2);");
1994 else
1995 strcpy(exactCpuCycles," return (6+retcycles*2);");
1996 break;
1997 case i_ROXR:
1998 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1999 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2000 start_brace ();
2001 switch (curi->size) {
2002 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2003 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2004 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2005 default: abort ();
2006 }
2007 printf ("\tcnt &= 63;\n");
2008 printf ("\tretcycles = cnt;\n");
2009 printf ("\tCLEAR_CZNV;\n");
2010 if (source_is_imm1_8 (curi))
2011 printf ("{");
2012 else {
2013 force_range_for_rox ("cnt", curi->size);
2014 printf ("\tif (cnt > 0) {\n");
2015 }
2016 printf ("\tcnt--;\n");
2017 printf ("\t{\n\tuint32_t carry;\n");
2018 printf ("\tuint32_t hival = (val << 1) | GET_XFLG;\n");
2019 printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1);
2020 printf ("\tval >>= cnt;\n");
2021 printf ("\tcarry = val & 1;\n");
2022 printf ("\tval >>= 1;\n");
2023 printf ("\tval |= hival;\n");
2024 printf ("\tSET_XFLG (carry);\n");
2025 printf ("\tval &= %s;\n", bit_mask (curi->size));
2026 printf ("\t} }\n");
2027 printf ("\tSET_CFLG (GET_XFLG);\n");
2028 genflags (flag_logical_noclobber, curi->size, "val", "", "");
2029 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2030 if(curi->size==sz_long)
2031 strcpy(exactCpuCycles," return (8+retcycles*2);");
2032 else
2033 strcpy(exactCpuCycles," return (6+retcycles*2);");
2034 break;
2035 case i_ASRW:
2036 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2037 start_brace ();
2038 switch (curi->size) {
2039 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2040 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2041 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2042 default: abort ();
2043 }
2044 printf ("\tuint32_t sign = %s & val;\n", cmask (curi->size));
2045 printf ("\tuint32_t cflg = val & 1;\n");
2046 printf ("\tval = (val >> 1) | sign;\n");
2047 genflags (flag_logical, curi->size, "val", "", "");
2048 printf ("\tSET_CFLG (cflg);\n");
2049 duplicate_carry ();
2050 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2051 break;
2052 case i_ASLW:
2053 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2054 start_brace ();
2055 switch (curi->size) {
2056 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2057 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2058 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2059 default: abort ();
2060 }
2061 printf ("\tuint32_t sign = %s & val;\n", cmask (curi->size));
2062 printf ("\tuint32_t sign2;\n");
2063 printf ("\tval <<= 1;\n");
2064 genflags (flag_logical, curi->size, "val", "", "");
2065 printf ("\tsign2 = %s & val;\n", cmask (curi->size));
2066 printf ("\tSET_CFLG (sign != 0);\n");
2067 duplicate_carry ();
2068
2069 printf ("\tSET_VFLG (GET_VFLG | (sign2 != sign));\n");
2070 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2071 break;
2072 case i_LSRW:
2073 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2074 start_brace ();
2075 switch (curi->size) {
2076 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2077 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2078 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2079 default: abort ();
2080 }
2081 printf ("\tuint32_t carry = val & 1;\n");
2082 printf ("\tval >>= 1;\n");
2083 genflags (flag_logical, curi->size, "val", "", "");
2084 printf ("SET_CFLG (carry);\n");
2085 duplicate_carry ();
2086 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2087 break;
2088 case i_LSLW:
2089 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2090 start_brace ();
2091 switch (curi->size) {
2092 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2093 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2094 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2095 default: abort ();
2096 }
2097 printf ("\tuint32_t carry = val & %s;\n", cmask (curi->size));
2098 printf ("\tval <<= 1;\n");
2099 genflags (flag_logical, curi->size, "val", "", "");
2100 printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2101 duplicate_carry ();
2102 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2103 break;
2104 case i_ROLW:
2105 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2106 start_brace ();
2107 switch (curi->size) {
2108 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2109 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2110 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2111 default: abort ();
2112 }
2113 printf ("\tuint32_t carry = val & %s;\n", cmask (curi->size));
2114 printf ("\tval <<= 1;\n");
2115 printf ("\tif (carry) val |= 1;\n");
2116 genflags (flag_logical, curi->size, "val", "", "");
2117 printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2118 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2119 break;
2120 case i_RORW:
2121 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2122 start_brace ();
2123 switch (curi->size) {
2124 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2125 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2126 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2127 default: abort ();
2128 }
2129 printf ("\tuint32_t carry = val & 1;\n");
2130 printf ("\tval >>= 1;\n");
2131 printf ("\tif (carry) val |= %s;\n", cmask (curi->size));
2132 genflags (flag_logical, curi->size, "val", "", "");
2133 printf ("SET_CFLG (carry);\n");
2134 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2135 break;
2136 case i_ROXLW:
2137 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2138 start_brace ();
2139 switch (curi->size) {
2140 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2141 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2142 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2143 default: abort ();
2144 }
2145 printf ("\tuint32_t carry = val & %s;\n", cmask (curi->size));
2146 printf ("\tval <<= 1;\n");
2147 printf ("\tif (GET_XFLG) val |= 1;\n");
2148 genflags (flag_logical, curi->size, "val", "", "");
2149 printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2150 duplicate_carry ();
2151 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2152 break;
2153 case i_ROXRW:
2154 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2155 start_brace ();
2156 switch (curi->size) {
2157 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2158 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2159 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2160 default: abort ();
2161 }
2162 printf ("\tuint32_t carry = val & 1;\n");
2163 printf ("\tval >>= 1;\n");
2164 printf ("\tif (GET_XFLG) val |= %s;\n", cmask (curi->size));
2165 genflags (flag_logical, curi->size, "val", "", "");
2166 printf ("SET_CFLG (carry);\n");
2167 duplicate_carry ();
2168 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2169 break;
2170 case i_MOVEC2:
2171 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2172 start_brace ();
2173 printf ("\tint regno = (src >> 12) & 15;\n");
2174 printf ("\tuint32_t *regp = regs.regs + regno;\n");
2175 printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
2176 break;
2177 case i_MOVE2C:
2178 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2179 start_brace ();
2180 printf ("\tint regno = (src >> 12) & 15;\n");
2181 printf ("\tuint32_t *regp = regs.regs + regno;\n");
2182 printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
2183 break;
2184 case i_CAS:
2185 {
2186 int old_brace_level;
2187 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2188 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2189 start_brace ();
2190 printf ("\tint ru = (src >> 6) & 7;\n");
2191 printf ("\tint rc = src & 7;\n");
2192 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc)", "dst");
2193 printf ("\tif (GET_ZFLG)");
2194 old_brace_level = n_braces;
2195 start_brace ();
2196 genastore ("(m68k_dreg(regs, ru))", curi->dmode, "dstreg", curi->size, "dst");
2197 pop_braces (old_brace_level);
2198 printf ("else");
2199 start_brace ();
2200 printf ("m68k_dreg(regs, rc) = dst;\n");
2201 pop_braces (old_brace_level);
2202 }
2203 break;
2204 case i_CAS2:
2205 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2206 printf ("\tuint32_t rn1 = regs.regs[(extra >> 28) & 15];\n");
2207 printf ("\tuint32_t rn2 = regs.regs[(extra >> 12) & 15];\n");
2208 if (curi->size == sz_word) {
2209 int old_brace_level = n_braces;
2210 printf ("\tuint16_t dst1 = m68k_read_memory_16(rn1), dst2 = m68k_read_memory_16(rn2);\n");
2211 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1");
2212 printf ("\tif (GET_ZFLG) {\n");
2213 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, extra & 7)", "dst2");
2214 printf ("\tif (GET_ZFLG) {\n");
2215 printf ("\tm68k_write_memory_16(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n");
2216 printf ("\tm68k_write_memory_16(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n");
2217 printf ("\t}}\n");
2218 pop_braces (old_brace_level);
2219 printf ("\tif (! GET_ZFLG) {\n");
2220 printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = (m68k_dreg(regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
2221 printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = (m68k_dreg(regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
2222 printf ("\t}\n");
2223 } else {
2224 int old_brace_level = n_braces;
2225 printf ("\tuint32_t dst1 = m68k_read_memory_32(rn1), dst2 = m68k_read_memory_32(rn2);\n");
2226 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1");
2227 printf ("\tif (GET_ZFLG) {\n");
2228 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, extra & 7)", "dst2");
2229 printf ("\tif (GET_ZFLG) {\n");
2230 printf ("\tm68k_write_memory_32(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n");
2231 printf ("\tm68k_write_memory_32(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n");
2232 printf ("\t}}\n");
2233 pop_braces (old_brace_level);
2234 printf ("\tif (! GET_ZFLG) {\n");
2235 printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = dst1;\n");
2236 printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = dst2;\n");
2237 printf ("\t}\n");
2238 }
2239 break;
2240 case i_MOVES: /* ignore DFC and SFC because we have no MMU */
2241 {
2242 int old_brace_level;
2243 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2244 printf ("\tif (extra & 0x800)\n");
2245 old_brace_level = n_braces;
2246 start_brace ();
2247 printf ("\tuint32_t src = regs.regs[(extra >> 12) & 15];\n");
2248 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
2249 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
2250 pop_braces (old_brace_level);
2251 printf ("else");
2252 start_brace ();
2253 genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0);
2254 printf ("\tif (extra & 0x8000) {\n");
2255 switch (curi->size) {
2256 case sz_byte: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (int32_t)(int8_t)src;\n"); break;
2257 case sz_word: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (int32_t)(int16_t)src;\n"); break;
2258 case sz_long: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = src;\n"); break;
2259 default: abort ();
2260 }
2261 printf ("\t} else {\n");
2262 genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, "");
2263 printf ("\t}\n");
2264 pop_braces (old_brace_level);
2265 }
2266 break;
2267 case i_BKPT: /* only needed for hardware emulators */
2268 sync_m68k_pc ();
2269 printf ("\top_illg(opcode);\n");
2270 break;
2271 case i_CALLM: /* not present in 68030 */
2272 sync_m68k_pc ();
2273 printf ("\top_illg(opcode);\n");
2274 break;
2275 case i_RTM: /* not present in 68030 */
2276 sync_m68k_pc ();
2277 printf ("\top_illg(opcode);\n");
2278 break;
2279 case i_TRAPcc:
2280 if (curi->smode != am_unknown && curi->smode != am_illg)
2281 genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0);
2282 printf ("\tif (cctrue(%d)) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", curi->cc, endlabelstr);
2283 need_endlabel = 1;
2284 break;
2285 case i_DIVL:
2286 sync_m68k_pc ();
2287 start_brace ();
2288 printf ("\tuint32_t oldpc = m68k_getpc();\n");
2289 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2290 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2291 sync_m68k_pc ();
2292 printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n");
2293 break;
2294 case i_MULL:
2295 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2296 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2297 sync_m68k_pc ();
2298 printf ("\tm68k_mull(opcode, dst, extra);\n");
2299 break;
2300 case i_BFTST:
2301 case i_BFEXTU:
2302 case i_BFCHG:
2303 case i_BFEXTS:
2304 case i_BFCLR:
2305 case i_BFFFO:
2306 case i_BFSET:
2307 case i_BFINS:
2308 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2309 genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0);
2310 start_brace ();
2311 printf ("\tint32_t offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n");
2312 printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n");
2313 if (curi->dmode == Dreg) {
2314 printf ("\tuint32_t tmp = m68k_dreg(regs, dstreg) << (offset & 0x1f);\n");
2315 } else {
2316 printf ("\tuint32_t tmp,bf0,bf1;\n");
2317 printf ("\tdsta += (offset >> 3) | (offset & 0x80000000 ? ~0x1fffffff : 0);\n");
2318 printf ("\tbf0 = m68k_read_memory_32(dsta);bf1 = m68k_read_memory_8(dsta+4) & 0xff;\n");
2319 printf ("\ttmp = (bf0 << (offset & 7)) | (bf1 >> (8 - (offset & 7)));\n");
2320 }
2321 printf ("\ttmp >>= (32 - width);\n");
2322 printf ("\tSET_NFLG (tmp & (1 << (width-1)) ? 1 : 0);\n");
2323 printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n");
2324 switch (curi->mnemo) {
2325 case i_BFTST:
2326 break;
2327 case i_BFEXTU:
2328 printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n");
2329 break;
2330 case i_BFCHG:
2331 printf ("\ttmp = ~tmp;\n");
2332 break;
2333 case i_BFEXTS:
2334 printf ("\tif (GET_NFLG) tmp |= width == 32 ? 0 : (-1 << width);\n");
2335 printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n");
2336 break;
2337 case i_BFCLR:
2338 printf ("\ttmp = 0;\n");
2339 break;
2340 case i_BFFFO:
2341 printf ("\t{ uint32_t mask = 1 << (width-1);\n");
2342 printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n");
2343 printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = offset;\n");
2344 break;
2345 case i_BFSET:
2346 printf ("\ttmp = 0xffffffff;\n");
2347 break;
2348 case i_BFINS:
2349 printf ("\ttmp = m68k_dreg(regs, (extra >> 12) & 7);\n");
2350 printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n");
2351 printf ("\tSET_ZFLG (tmp == 0);\n");
2352 break;
2353 default:
2354 break;
2355 }
2356 if (curi->mnemo == i_BFCHG
2357 || curi->mnemo == i_BFCLR
2358 || curi->mnemo == i_BFSET
2359 || curi->mnemo == i_BFINS)
2360 {
2361 printf ("\ttmp <<= (32 - width);\n");
2362 if (curi->dmode == Dreg) {
2363 printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & ((offset & 0x1f) == 0 ? 0 :\n");
2364 printf ("\t\t(0xffffffff << (32 - (offset & 0x1f))))) |\n");
2365 printf ("\t\t(tmp >> (offset & 0x1f)) |\n");
2366 printf ("\t\t(((offset & 0x1f) + width) >= 32 ? 0 :\n");
2367 printf (" (m68k_dreg(regs, dstreg) & ((uint32_t)0xffffffff >> ((offset & 0x1f) + width))));\n");
2368 } else {
2369 printf ("\tbf0 = (bf0 & (0xff000000 << (8 - (offset & 7)))) |\n");
2370 printf ("\t\t(tmp >> (offset & 7)) |\n");
2371 printf ("\t\t(((offset & 7) + width) >= 32 ? 0 :\n");
2372 printf ("\t\t (bf0 & ((uint32_t)0xffffffff >> ((offset & 7) + width))));\n");
2373 printf ("\tm68k_write_memory_32(dsta,bf0 );\n");
2374 printf ("\tif (((offset & 7) + width) > 32) {\n");
2375 printf ("\t\tbf1 = (bf1 & (0xff >> (width - 32 + (offset & 7)))) |\n");
2376 printf ("\t\t\t(tmp << (8 - (offset & 7)));\n");
2377 printf ("\t\tm68k_write_memory_8(dsta+4,bf1);\n");
2378 printf ("\t}\n");
2379 }
2380 }
2381 break;
2382 case i_PACK:
2383 if (curi->smode == Dreg) {
2384 printf ("\tuint16_t val = m68k_dreg(regs, srcreg) + %s;\n", gen_nextiword ());
2385 printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
2386 } else {
2387 printf ("\tuint16_t val;\n");
2388 printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
2389 printf ("\tval = (uint16_t)m68k_read_memory_8(m68k_areg(regs, srcreg));\n");
2390 printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
2391 printf ("\tval = (val | ((uint16_t)m68k_read_memory_8(m68k_areg(regs, srcreg)) << 8)) + %s;\n", gen_nextiword ());
2392 printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
2393 printf ("\tm68k_write_memory_8(m68k_areg(regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n");
2394 }
2395 break;
2396 case i_UNPK:
2397 if (curi->smode == Dreg) {
2398 printf ("\tuint16_t val = m68k_dreg(regs, srcreg);\n");
2399 printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ());
2400 printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffff0000) | (val & 0xffff);\n");
2401 } else {
2402 printf ("\tuint16_t val;\n");
2403 printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
2404 printf ("\tval = (uint16_t)m68k_read_memory_8(m68k_areg(regs, srcreg));\n");
2405 printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ());
2406 printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
2407 printf ("\tm68k_write_memory_8(m68k_areg(regs, dstreg),val);\n");
2408 printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
2409 printf ("\tm68k_write_memory_8(m68k_areg(regs, dstreg),val >> 8);\n");
2410 }
2411 break;
2412 case i_TAS:
2413 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2414 genflags (flag_logical, curi->size, "src", "", "");
2415 printf ("\tsrc |= 0x80;\n");
2416 genastore ("src", curi->smode, "srcreg", curi->size, "src");
2417 if( curi->smode!=Dreg ) insn_n_cycles += 2;
2418 break;
2419 case i_FPP:
2420 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2421 sync_m68k_pc ();
2422 printf ("\tfpp_opp(opcode,extra);\n");
2423 break;
2424 case i_FDBcc:
2425 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2426 sync_m68k_pc ();
2427 printf ("\tfdbcc_opp(opcode,extra);\n");
2428 break;
2429 case i_FScc:
2430 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2431 sync_m68k_pc ();
2432 printf ("\tfscc_opp(opcode,extra);\n");
2433 break;
2434 case i_FTRAPcc:
2435 sync_m68k_pc ();
2436 start_brace ();
2437 printf ("\tuint32_t oldpc = m68k_getpc();\n");
2438 if (curi->smode != am_unknown && curi->smode != am_illg)
2439 genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0);
2440 sync_m68k_pc ();
2441 printf ("\tftrapcc_opp(opcode,oldpc);\n");
2442 break;
2443 case i_FBcc:
2444 sync_m68k_pc ();
2445 start_brace ();
2446 printf ("\tuint32_t pc = m68k_getpc();\n");
2447 genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0);
2448 sync_m68k_pc ();
2449 printf ("\tfbcc_opp(opcode,pc,extra);\n");
2450 break;
2451 case i_FSAVE:
2452 sync_m68k_pc ();
2453 printf ("\tfsave_opp(opcode);\n");
2454 break;
2455 case i_FRESTORE:
2456 sync_m68k_pc ();
2457 printf ("\tfrestore_opp(opcode);\n");
2458 break;
2459
2460 case i_CINVL:
2461 case i_CINVP:
2462 case i_CINVA:
2463 case i_CPUSHL:
2464 case i_CPUSHP:
2465 case i_CPUSHA:
2466 break;
2467 case i_MOVE16:
2468 if ((opcode & 0xfff8) == 0xf620) {
2469 /* MOVE16 (Ax)+,(Ay)+ */
2470 printf ("\tuint32_t mems = m68k_areg(regs, srcreg) & ~15, memd;\n");
2471 printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword());
2472 printf ("\tmemd = m68k_areg(regs, dstreg) & ~15;\n");
2473 printf ("\tm68k_write_memory_32(memd, m68k_read_memory_32(mems));\n");
2474 printf ("\tm68k_write_memory_32(memd+4, m68k_read_memory_32(mems+4));\n");
2475 printf ("\tm68k_write_memory_32(memd+8, m68k_read_memory_32(mems+8));\n");
2476 printf ("\tm68k_write_memory_32(memd+12, m68k_read_memory_32(mems+12));\n");
2477 printf ("\tif (srcreg != dstreg)\n");
2478 printf ("\tm68k_areg(regs, srcreg) += 16;\n");
2479 printf ("\tm68k_areg(regs, dstreg) += 16;\n");
2480 } else {
2481 /* Other variants */
2482 genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2);
2483 genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2);
2484 printf ("\tmemsa &= ~15;\n");
2485 printf ("\tmemda &= ~15;\n");
2486 printf ("\tm68k_write_memory_32(memda, m68k_read_memory_32(memsa));\n");
2487 printf ("\tm68k_write_memory_32(memda+4, m68k_read_memory_32(memsa+4));\n");
2488 printf ("\tm68k_write_memory_32(memda+8, m68k_read_memory_32(memsa+8));\n");
2489 printf ("\tm68k_write_memory_32(memda+12, m68k_read_memory_32(memsa+12));\n");
2490 if ((opcode & 0xfff8) == 0xf600)
2491 printf ("\tm68k_areg(regs, srcreg) += 16;\n");
2492 else if ((opcode & 0xfff8) == 0xf608)
2493 printf ("\tm68k_areg(regs, dstreg) += 16;\n");
2494 }
2495 break;
2496
2497 case i_MMUOP:
2498 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2499 sync_m68k_pc ();
2500 printf ("\tmmu_op(opcode,extra);\n");
2501 break;
2502 default:
2503 abort ();
2504 break;
2505 }
2506 finish_braces ();
2507 sync_m68k_pc ();
2508 }
2509
generate_includes(FILE * f)2510 static void generate_includes(FILE * f)
2511 {
2512 //JLH:no fprintf(f, "#include \"sysdeps.h\"\n");
2513 //JLH:no fprintf(f, "#include \"hatari-glue.h\"\n");
2514 //JLH:no fprintf(f, "#include \"maccess.h\"\n");
2515 //JLH:no fprintf(f, "#include \"memory.h\"\n");
2516 //JLH:no fprintf(f, "#include \"newcpu.h\"\n");
2517 fprintf(f, "#include \"cpudefs.h\"\n");
2518 fprintf(f, "#include \"cpuextra.h\"\n");
2519 fprintf(f, "#include \"inlines.h\"\n");
2520 fprintf(f, "#include \"cputbl.h\"\n");
2521 fprintf(f, "#define CPUFUNC(x) x##_ff\n"
2522 "#ifdef NOFLAGS\n"
2523 "#include \"noflags.h\"\n"
2524 "#endif\n");
2525 }
2526
2527 // JLH: Since this is stuff that should be generated in a file that creates
2528 // constants, it's in here now. :-P
GenerateTables(FILE * f)2529 static void GenerateTables(FILE * f)
2530 {
2531 int i, j;
2532
2533 fprintf(f, "\nconst int areg_byteinc[] = { 1, 1, 1, 1, 1, 1, 1, 2 };\n");
2534 fprintf(f, "const int imm8_table[] = { 8, 1, 2, 3, 4, 5, 6, 7 };\n\n");
2535 fprintf(f, "const int movem_index1[256] = {\n");
2536
2537 for(i=0; i<256; i++)
2538 {
2539 for(j=0; j<8; j++)
2540 if (i & (1 << j))
2541 break;
2542
2543 fprintf(f, "0x%02X, ", j);
2544
2545 if ((i % 16) == 15)
2546 fprintf(f, "\n");
2547 }
2548
2549 fprintf(f, "};\n\n");
2550 fprintf(f, "const int movem_index2[256] = {\n");
2551
2552 for(i=0; i<256; i++)
2553 {
2554 for(j=0; j<8; j++)
2555 if (i & (1 << j))
2556 break;
2557
2558 fprintf(f, "0x%02X, ", 7 - j);
2559
2560 if ((i % 16) == 15)
2561 fprintf(f, "\n");
2562 }
2563
2564 fprintf(f, "};\n\n");
2565 fprintf(f, "const int movem_next[256] = {\n");
2566
2567 for(i=0; i<256; i++)
2568 {
2569 for(j=0; j<8; j++)
2570 if (i & (1 << j))
2571 break;
2572
2573 fprintf(f, "0x%02X, ", i & (~(1 << j)));
2574
2575 if ((i % 16) == 15)
2576 fprintf(f, "\n");
2577 }
2578
2579 fprintf(f, "};\n\n");
2580 }
2581
2582 static int postfix;
2583
generate_one_opcode(int rp)2584 static void generate_one_opcode (int rp)
2585 {
2586 int i;
2587 uint16_t smsk, dmsk;
2588 long int opcode = opcode_map[rp];
2589
2590 exactCpuCycles[0] = 0; /* Default: not used */
2591
2592 if (table68k[opcode].mnemo == i_ILLG
2593 || table68k[opcode].clev > cpu_level)
2594 return;
2595
2596 for (i = 0; lookuptab[i].name[0]; i++) {
2597 if (table68k[opcode].mnemo == lookuptab[i].mnemo)
2598 break;
2599 }
2600
2601 if (table68k[opcode].handler != -1)
2602 return;
2603
2604 if (opcode_next_clev[rp] != cpu_level) {
2605 fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp],
2606 opcode, lookuptab[i].name);
2607 return;
2608 }
2609 fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
2610 fprintf (headerfile, "extern cpuop_func op_%lx_%d_nf;\n", opcode, postfix);
2611 fprintf (headerfile, "extern cpuop_func op_%lx_%d_ff;\n", opcode, postfix);
2612 printf ("unsigned long CPUFUNC(op_%lx_%d)(uint32_t opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
2613
2614 switch (table68k[opcode].stype) {
2615 case 0: smsk = 7; break;
2616 case 1: smsk = 255; break;
2617 case 2: smsk = 15; break;
2618 case 3: smsk = 7; break;
2619 case 4: smsk = 7; break;
2620 case 5: smsk = 63; break;
2621 case 7: smsk = 3; break;
2622 default: abort ();
2623 }
2624 dmsk = 7;
2625
2626 next_cpu_level = -1;
2627 if (table68k[opcode].suse
2628 && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
2629 && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
2630 && table68k[opcode].smode != absw && table68k[opcode].smode != absl
2631 && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
2632 {
2633 if (table68k[opcode].spos == -1) {
2634 if (((int) table68k[opcode].sreg) >= 128)
2635 printf ("\tuint32_t srcreg = (int32_t)(int8_t)%d;\n", (int) table68k[opcode].sreg);
2636 else
2637 printf ("\tuint32_t srcreg = %d;\n", (int) table68k[opcode].sreg);
2638 } else {
2639 char source[100];
2640 int pos = table68k[opcode].spos;
2641
2642 if (pos)
2643 sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
2644 else
2645 sprintf (source, "(opcode & %d)", smsk);
2646
2647 if (table68k[opcode].stype == 3)
2648 printf ("\tuint32_t srcreg = imm8_table[%s];\n", source);
2649 else if (table68k[opcode].stype == 1)
2650 printf ("\tuint32_t srcreg = (int32_t)(int8_t)%s;\n", source);
2651 else
2652 printf ("\tuint32_t srcreg = %s;\n", source);
2653 }
2654 }
2655 if (table68k[opcode].duse
2656 /* Yes, the dmode can be imm, in case of LINK or DBcc */
2657 && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
2658 && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
2659 && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
2660 {
2661 if (table68k[opcode].dpos == -1) {
2662 if (((int) table68k[opcode].dreg) >= 128)
2663 printf ("\tuint32_t dstreg = (int32_t)(int8_t)%d;\n", (int) table68k[opcode].dreg);
2664 else
2665 printf ("\tuint32_t dstreg = %d;\n", (int) table68k[opcode].dreg);
2666 } else {
2667 int pos = table68k[opcode].dpos;
2668 if (pos)
2669 printf ("\tuint32_t dstreg = (opcode >> %d) & %d;\n",
2670 pos, dmsk);
2671 else
2672 printf ("\tuint32_t dstreg = opcode & %d;\n", dmsk);
2673 }
2674 }
2675 need_endlabel = 0;
2676 endlabelno++;
2677 sprintf (endlabelstr, "endlabel%d", endlabelno);
2678 if(table68k[opcode].mnemo==i_ASR || table68k[opcode].mnemo==i_ASL || table68k[opcode].mnemo==i_LSR || table68k[opcode].mnemo==i_LSL
2679 || table68k[opcode].mnemo==i_ROL || table68k[opcode].mnemo==i_ROR || table68k[opcode].mnemo==i_ROXL || table68k[opcode].mnemo==i_ROXR
2680 || table68k[opcode].mnemo==i_MVMEL || table68k[opcode].mnemo==i_MVMLE
2681 || table68k[opcode].mnemo==i_MULU || table68k[opcode].mnemo==i_MULS
2682 || table68k[opcode].mnemo==i_DIVU || table68k[opcode].mnemo==i_DIVS )
2683 printf("\tunsigned int retcycles = 0;\n");
2684 gen_opcode (opcode);
2685 if (need_endlabel)
2686 printf ("%s: ;\n", endlabelstr);
2687
2688 if (strlen(exactCpuCycles) > 0)
2689 printf("%s\n",exactCpuCycles);
2690 else
2691 printf ("return %d;\n", insn_n_cycles);
2692 /* Now patch in the instruction cycles at the beginning of the function: */
2693 fseek(stdout, nCurInstrCycPos, SEEK_SET);
2694 printf("%d;", insn_n_cycles);
2695 fseek(stdout, 0, SEEK_END);
2696
2697 printf ("}\n");
2698 opcode_next_clev[rp] = next_cpu_level;
2699 opcode_last_postfix[rp] = postfix;
2700 }
2701
generate_func(void)2702 static void generate_func(void)
2703 {
2704 int i, j, rp;
2705
2706 using_prefetch = 0;
2707 using_exception_3 = 0;
2708 //JLH:
2709 // for(i=0; i<6; i++)
2710 //For some reason, this doesn't work properly. Seems something is making a bad
2711 //assumption somewhere.
2712 //and it's probably in opcode_next_clev[rp]...
2713 for(i=4; i<6; i++)
2714 {
2715 cpu_level = 4 - i;
2716
2717 //JLH
2718 for(rp=0; rp<nr_cpuop_funcs; rp++)
2719 opcode_next_clev[rp] = 0;
2720
2721 if (i == 5)
2722 {
2723 cpu_level = 0;
2724 using_prefetch = 1;
2725 using_exception_3 = 1;
2726
2727 for(rp=0; rp<nr_cpuop_funcs; rp++)
2728 opcode_next_clev[rp] = 0;
2729 }
2730
2731 postfix = i;
2732 fprintf(stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix);
2733
2734 /* sam: this is for people with low memory (eg. me :)) */
2735 printf("\n"
2736 "#if !defined(PART_1) && !defined(PART_2) && "
2737 "!defined(PART_3) && !defined(PART_4) && "
2738 "!defined(PART_5) && !defined(PART_6) && "
2739 "!defined(PART_7) && !defined(PART_8)"
2740 "\n"
2741 "#define PART_1 1\n"
2742 "#define PART_2 1\n"
2743 "#define PART_3 1\n"
2744 "#define PART_4 1\n"
2745 "#define PART_5 1\n"
2746 "#define PART_6 1\n"
2747 "#define PART_7 1\n"
2748 "#define PART_8 1\n"
2749 "#endif\n\n");
2750
2751 rp = 0;
2752
2753 for(j=1; j<=8; ++j)
2754 {
2755 int k = (j * nr_cpuop_funcs) / 8;
2756 printf("#ifdef PART_%d\n", j);
2757
2758 for(; rp<k; rp++)
2759 generate_one_opcode(rp);
2760
2761 printf ("#endif\n\n");
2762 }
2763
2764 fprintf(stblfile, "{ 0, 0, 0 }};\n");
2765 }
2766 }
2767
main(int argc,char ** argv)2768 int main(int argc, char ** argv)
2769 {
2770 read_table68k();
2771 do_merges();
2772
2773 opcode_map = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
2774 opcode_last_postfix = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
2775 opcode_next_clev = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
2776 counts = (unsigned long *)malloc(65536 * sizeof(unsigned long));
2777 read_counts();
2778
2779 /* It would be a lot nicer to put all in one file (we'd also get rid of
2780 * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
2781 * I don't dare to touch the 68k version. */
2782
2783 headerfile = fopen("cputbl.h", "wb");
2784 stblfile = fopen("cpustbl.c", "wb");
2785
2786 if (freopen("cpuemu.c", "wb", stdout) == NULL)
2787 {
2788 perror("cpuemu.c");
2789 return -1;
2790 }
2791
2792 generate_includes(stdout);
2793 generate_includes(stblfile);
2794
2795 GenerateTables(stdout);
2796
2797 generate_func();
2798
2799 free(table68k);
2800 return 0;
2801 }
2802