Added detection for the unsigned/signed short type
[clinton/Virtual-Jaguar-Rx.git] / src / m68000 / gencpu.c
CommitLineData
cf76e892
JPM
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
80static FILE *headerfile;
81static FILE *stblfile;
82
83static int using_prefetch;
84static int using_exception_3;
85static int cpu_level;
86
87char exactCpuCycles[256]; /* Space to store return string for exact cpu cycles */
88
89long 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. */
94static int next_cpu_level;
95static int *opcode_map;
96static int *opcode_next_clev;
97static int *opcode_last_postfix;
98static unsigned long *counts;
99
100
101static 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
138static char endlabelstr[80];
139static int endlabelno = 0;
140static int need_endlabel;
141
142static int n_braces = 0;
143static int m68k_pc_offset = 0;
144static int insn_n_cycles;
145
146static void start_brace (void)
147{
148 n_braces++;
149 printf ("{");
150}
151
152static void close_brace (void)
153{
154 assert (n_braces > 0);
155 n_braces--;
156 printf ("}");
157}
158
159static void finish_braces (void)
160{
161 while (n_braces > 0)
162 close_brace ();
163}
164
165static void pop_braces (int to)
166{
167 while (n_braces > to)
168 close_brace ();
169}
170
171static 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
182static 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
193static 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
208static 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
223static 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
238static void fill_prefetch_0 (void)
239{
240 if (using_prefetch)
241 printf ("fill_prefetch_0 ();\n");
242}
243
244static void fill_prefetch_2 (void)
245{
246 if (using_prefetch)
247 printf ("fill_prefetch_2 ();\n");
248}
249
250static 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 */
276static 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
489static 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
566static 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
608static 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
660static void duplicate_carry (void)
661{
662 printf ("\tCOPY_CARRY;\n");
663}
664
665typedef 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}
670flagtypes;
671
672static 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
814static 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
892static 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
911static 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
921static int source_is_imm1_8 (struct instr *i)
922{
923 return i->stype == 3;
924}
925
926
927
928static void gen_opcode (unsigned long int opcode)
929{
930#if 0
931 char *amodenames[] = { "Dreg", "Areg", "Aind", "Aipi", "Apdi", "Ad16", "Ad8r",
932 "absw", "absl", "PC16", "PC8r", "imm", "imm0", "imm1", "imm2", "immi", "am_unknown", "am_illg"};
933#endif
934
935 struct instr *curi = table68k + opcode;
936 insn_n_cycles = 4;
937
938 /* Store the family of the instruction (used to check for pairing on ST)
939 * and leave some space for patching in the current cycles later */
940 printf ("\tOpcodeFamily = %d; CurrentInstrCycles = \n", curi->mnemo);
941 nCurInstrCycPos = ftell(stdout) - 5;
942
943 start_brace ();
944 m68k_pc_offset = 2;
945
946 switch (curi->plev) {
947 case 0: /* not privileged */
948 break;
949 case 1: /* unprivileged only on 68000 */
950 if (cpu_level == 0)
951 break;
952 if (next_cpu_level < 0)
953 next_cpu_level = 0;
954
955 /* fall through */
956 case 2: /* priviledged */
957 printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
958 need_endlabel = 1;
959 start_brace ();
960 break;
961 case 3: /* privileged if size == word */
962 if (curi->size == sz_byte)
963 break;
964 printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
965 need_endlabel = 1;
966 start_brace ();
967 break;
968 }
969
970 /* Build the opcodes: */
971 switch (curi->mnemo) {
972 case i_OR:
973 case i_AND:
974 case i_EOR:
975 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
976 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
977 printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^');
978 genflags (flag_logical, curi->size, "src", "", "");
979 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
980 if(curi->size==sz_long && curi->dmode==Dreg)
981 {
982 insn_n_cycles += 2;
983 if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi))
984 insn_n_cycles += 2;
985 }
986#if 0
987 /* Output the CPU cycles: */
988 fprintf(stderr,"MOVE, size %i: ",curi->size);
989 fprintf(stderr," %s ->",amodenames[curi->smode]);
990 fprintf(stderr," %s ",amodenames[curi->dmode]);
991 fprintf(stderr," Cycles: %i\n",insn_n_cycles);
992#endif
993 break;
994 case i_ORSR:
995 case i_EORSR:
996 printf ("\tMakeSR();\n");
997 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
998 if (curi->size == sz_byte) {
999 printf ("\tsrc &= 0xFF;\n");
1000 }
1001 printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
1002 printf ("\tMakeFromSR();\n");
1003 insn_n_cycles = 20;
1004 break;
1005 case i_ANDSR:
1006 printf ("\tMakeSR();\n");
1007 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1008 if (curi->size == sz_byte) {
1009 printf ("\tsrc |= 0xFF00;\n");
1010 }
1011 printf ("\tregs.sr &= src;\n");
1012 printf ("\tMakeFromSR();\n");
1013 insn_n_cycles = 20;
1014 break;
1015 case i_SUB:
1016 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1017 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1018 start_brace ();
1019 genflags (flag_sub, curi->size, "newv", "src", "dst");
1020 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1021 if(curi->size==sz_long && curi->dmode==Dreg)
1022 {
1023 insn_n_cycles += 2;
1024 if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi))
1025 insn_n_cycles += 2;
1026 }
1027 break;
1028 case i_SUBA:
1029 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1030 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1031 start_brace ();
1032 printf ("\tuint32_t newv = dst - src;\n");
1033 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1034 if(curi->size==sz_long && curi->smode!=Dreg && curi->smode!=Areg && !(curi->smode>=imm && curi->smode<=immi))
1035 insn_n_cycles += 2;
1036 else
1037 insn_n_cycles += 4;
1038 break;
1039 case i_SUBX:
1040 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1041 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1042 start_brace ();
1043 printf ("\tuint32_t newv = dst - src - (GET_XFLG ? 1 : 0);\n");
1044 genflags (flag_subx, curi->size, "newv", "src", "dst");
1045 genflags (flag_zn, curi->size, "newv", "", "");
1046 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1047 if(curi->smode==Dreg && curi->size==sz_long)
1048 insn_n_cycles=8;
1049 if(curi->smode==Apdi)
1050 {
1051 if(curi->size==sz_long)
1052 insn_n_cycles=30;
1053 else
1054 insn_n_cycles=18;
1055 }
1056 break;
1057 case i_SBCD:
1058 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1059 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1060 start_brace ();
1061 printf ("\tuint16_t newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG ? 1 : 0);\n");
1062 printf ("\tuint16_t newv_hi = (dst & 0xF0) - (src & 0xF0);\n");
1063 printf ("\tuint16_t newv, tmp_newv;\n");
1064 printf ("\tint bcd = 0;\n");
1065 printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n");
1066 printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n");
1067 printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n");
1068 printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG ? 1 : 0)) & 0x300) > 0xFF);\n");
1069 duplicate_carry ();
1070 genflags (flag_zn, curi->size, "newv", "", "");
1071 printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
1072 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1073 if(curi->smode==Dreg) insn_n_cycles=6;
1074 if(curi->smode==Apdi) insn_n_cycles=18;
1075 break;
1076 case i_ADD:
1077 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1078 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1079 start_brace ();
1080 printf("\trefill_prefetch (m68k_getpc(), 2);\n"); // FIXME [NP] For Transbeauce 2 demo, need better prefetch emulation
1081 genflags (flag_add, curi->size, "newv", "src", "dst");
1082 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1083 if(curi->size==sz_long && curi->dmode==Dreg)
1084 {
1085 insn_n_cycles += 2;
1086 if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi))
1087 insn_n_cycles += 2;
1088 }
1089 break;
1090 case i_ADDA:
1091 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1092 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1093 start_brace ();
1094 printf ("\tuint32_t newv = dst + src;\n");
1095 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1096 if(curi->size==sz_long && curi->smode!=Dreg && curi->smode!=Areg && !(curi->smode>=imm && curi->smode<=immi))
1097 insn_n_cycles += 2;
1098 else
1099 insn_n_cycles += 4;
1100 break;
1101 case i_ADDX:
1102 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1103 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1104 start_brace ();
1105 printf ("\tuint32_t newv = dst + src + (GET_XFLG ? 1 : 0);\n");
1106 genflags (flag_addx, curi->size, "newv", "src", "dst");
1107 genflags (flag_zn, curi->size, "newv", "", "");
1108 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1109 if(curi->smode==Dreg && curi->size==sz_long)
1110 insn_n_cycles=8;
1111 if(curi->smode==Apdi)
1112 {
1113 if(curi->size==sz_long)
1114 insn_n_cycles=30;
1115 else
1116 insn_n_cycles=18;
1117 }
1118 break;
1119 case i_ABCD:
1120 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1121 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1122 start_brace ();
1123 printf ("\tuint16_t newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG ? 1 : 0);\n");
1124 printf ("\tuint16_t newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
1125 printf ("\tuint16_t newv, tmp_newv;\n");
1126 printf ("\tint cflg;\n");
1127 printf ("\tnewv = tmp_newv = newv_hi + newv_lo;");
1128 printf ("\tif (newv_lo > 9) { newv += 6; }\n");
1129 printf ("\tcflg = (newv & 0x3F0) > 0x90;\n");
1130 printf ("\tif (cflg) newv += 0x60;\n");
1131 printf ("\tSET_CFLG (cflg);\n");
1132 duplicate_carry ();
1133 genflags (flag_zn, curi->size, "newv", "", "");
1134 printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
1135 genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1136 if(curi->smode==Dreg) insn_n_cycles=6;
1137 if(curi->smode==Apdi) insn_n_cycles=18;
1138 break;
1139 case i_NEG:
1140 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1141 start_brace ();
1142 genflags (flag_sub, curi->size, "dst", "src", "0");
1143 genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1144 if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2;
1145 break;
1146 case i_NEGX:
1147 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1148 start_brace ();
1149 printf ("\tuint32_t newv = 0 - src - (GET_XFLG ? 1 : 0);\n");
1150 genflags (flag_subx, curi->size, "newv", "src", "0");
1151 genflags (flag_zn, curi->size, "newv", "", "");
1152 genastore ("newv", curi->smode, "srcreg", curi->size, "src");
1153 if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2;
1154 break;
1155 case i_NBCD:
1156 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1157 start_brace ();
1158 printf ("\tuint16_t newv_lo = - (src & 0xF) - (GET_XFLG ? 1 : 0);\n");
1159 printf ("\tuint16_t newv_hi = - (src & 0xF0);\n");
1160 printf ("\tuint16_t newv;\n");
1161 printf ("\tint cflg;\n");
1162 printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
1163 printf ("\tnewv = newv_hi + newv_lo;");
1164 printf ("\tcflg = (newv & 0x1F0) > 0x90;\n");
1165 printf ("\tif (cflg) newv -= 0x60;\n");
1166 printf ("\tSET_CFLG (cflg);\n");
1167 duplicate_carry();
1168 genflags (flag_zn, curi->size, "newv", "", "");
1169 genastore ("newv", curi->smode, "srcreg", curi->size, "src");
1170 if(curi->smode==Dreg) insn_n_cycles += 2;
1171 break;
1172 case i_CLR:
1173 genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1174
1175 /* [NP] CLR does a read before the write only on 68000 */
1176 /* but there's no cycle penalty for doing the read */
1177 if ( curi->smode != Dreg ) // only if destination is memory
1178 {
1179 if (curi->size==sz_byte)
1180 printf ("\tint8_t src = m68k_read_memory_8(srca);\n");
1181 else if (curi->size==sz_word)
1182 printf ("\tint16_t src = m68k_read_memory_16(srca);\n");
1183 else if (curi->size==sz_long)
1184 printf ("\tint32_t src = m68k_read_memory_32(srca);\n");
1185 }
1186
1187 genflags (flag_logical, curi->size, "0", "", "");
1188 genastore ("0", curi->smode, "srcreg", curi->size, "src");
1189 if(curi->size==sz_long)
1190 {
1191 if(curi->smode==Dreg)
1192 insn_n_cycles += 2;
1193 else
1194 insn_n_cycles += 4;
1195 }
1196 if(curi->smode!=Dreg)
1197 insn_n_cycles += 4;
1198 break;
1199 case i_NOT:
1200 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1201 start_brace ();
1202 printf ("\tuint32_t dst = ~src;\n");
1203 genflags (flag_logical, curi->size, "dst", "", "");
1204 genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1205 if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2;
1206 break;
1207 case i_TST:
1208 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1209 genflags (flag_logical, curi->size, "src", "", "");
1210 break;
1211 case i_BTST:
1212 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1213 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1214 if (curi->size == sz_byte)
1215 printf ("\tsrc &= 7;\n");
1216 else
1217 printf ("\tsrc &= 31;\n");
1218 printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1219 if(curi->dmode==Dreg) insn_n_cycles += 2;
1220 break;
1221 case i_BCHG:
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 ("\tdst ^= (1 << src);\n");
1229 printf ("\tSET_ZFLG (((uint32_t)dst & (1 << src)) >> src);\n");
1230 genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1231 if(curi->dmode==Dreg) insn_n_cycles += 4;
1232 break;
1233 case i_BCLR:
1234 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1235 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1236 if (curi->size == sz_byte)
1237 printf ("\tsrc &= 7;\n");
1238 else
1239 printf ("\tsrc &= 31;\n");
1240 printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1241 printf ("\tdst &= ~(1 << src);\n");
1242 genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1243 if(curi->dmode==Dreg) insn_n_cycles += 6;
1244 /* [NP] BCLR #n,Dx takes 12 cycles instead of 14 if n<16 */
1245 if((curi->smode==imm1) && (curi->dmode==Dreg))
1246 printf ("\tif ( src < 16 ) { m68k_incpc(4); return 12; }\n");
1247 /* [NP] BCLR Dy,Dx takes 8 cycles instead of 10 if Dy<16 */
1248 if((curi->smode==Dreg) && (curi->dmode==Dreg))
1249 printf ("\tif ( src < 16 ) { m68k_incpc(2); return 8; }\n");
1250 break;
1251 case i_BSET:
1252 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1253 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1254 if (curi->size == sz_byte)
1255 printf ("\tsrc &= 7;\n");
1256 else
1257 printf ("\tsrc &= 31;\n");
1258 printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1259 printf ("\tdst |= (1 << src);\n");
1260 genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1261 if(curi->dmode==Dreg) insn_n_cycles += 4;
1262 break;
1263 case i_CMPM:
1264 case i_CMP:
1265 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1266 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1267 start_brace ();
1268 genflags (flag_cmp, curi->size, "newv", "src", "dst");
1269 if(curi->size==sz_long && curi->dmode==Dreg)
1270 insn_n_cycles += 2;
1271 break;
1272 case i_CMPA:
1273 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1274 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1275 start_brace ();
1276 genflags (flag_cmp, sz_long, "newv", "src", "dst");
1277 insn_n_cycles += 2;
1278 break;
1279 /* The next two are coded a little unconventional, but they are doing
1280 * weird things... */
1281 case i_MVPRM:
1282 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1283
1284 printf ("\tuint32_t memp = m68k_areg(regs, dstreg) + (int32_t)(int16_t)%s;\n", gen_nextiword ());
1285 if (curi->size == sz_word) {
1286 printf ("\tm68k_write_memory_8(memp, src >> 8); m68k_write_memory_8(memp + 2, src);\n");
1287 } else {
1288 printf ("\tm68k_write_memory_8(memp, src >> 24); m68k_write_memory_8(memp + 2, src >> 16);\n");
1289 printf ("\tm68k_write_memory_8(memp + 4, src >> 8); m68k_write_memory_8(memp + 6, src);\n");
1290 }
1291 if(curi->size==sz_long) insn_n_cycles=24; else insn_n_cycles=16;
1292 break;
1293 case i_MVPMR:
1294 printf ("\tuint32_t memp = m68k_areg(regs, srcreg) + (int32_t)(int16_t)%s;\n", gen_nextiword ());
1295 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1296 if (curi->size == sz_word) {
1297 printf ("\tuint16_t val = (m68k_read_memory_8(memp) << 8) + m68k_read_memory_8(memp + 2);\n");
1298 } else {
1299 printf ("\tuint32_t val = (m68k_read_memory_8(memp) << 24) + (m68k_read_memory_8(memp + 2) << 16)\n");
1300 printf (" + (m68k_read_memory_8(memp + 4) << 8) + m68k_read_memory_8(memp + 6);\n");
1301 }
1302 genastore ("val", curi->dmode, "dstreg", curi->size, "dst");
1303 if(curi->size==sz_long) insn_n_cycles=24; else insn_n_cycles=16;
1304 break;
1305 case i_MOVE:
1306 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1307 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1308
1309 /* [NP] genamode counts 2 cycles if dest is -(An), this is wrong. */
1310 /* For move dest (An), (An)+ and -(An) take the same time */
1311 /* (for other instr, dest -(An) really takes 2 cycles more) */
1312 if ( curi->dmode == Apdi )
1313 insn_n_cycles -= 2; /* correct the wrong cycle count for -(An) */
1314
1315 genflags (flag_logical, curi->size, "src", "", "");
1316 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1317 break;
1318 case i_MOVEA:
1319 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1320 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1321 if (curi->size == sz_word) {
1322 printf ("\tuint32_t val = (int32_t)(int16_t)src;\n");
1323 } else {
1324 printf ("\tuint32_t val = src;\n");
1325 }
1326 genastore ("val", curi->dmode, "dstreg", sz_long, "dst");
1327 break;
1328 case i_MVSR2: /* Move from SR */
1329 genamode (curi->smode, "srcreg", sz_word, "src", 2, 0);
1330 printf ("\tMakeSR();\n");
1331 if (curi->size == sz_byte)
1332 genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src");
1333 else
1334 genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src");
1335 if (curi->smode==Dreg) insn_n_cycles += 2; else insn_n_cycles += 4;
1336 break;
1337 case i_MV2SR: /* Move to SR */
1338 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1339 if (curi->size == sz_byte)
1340 printf ("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
1341 else {
1342 printf ("\tregs.sr = src;\n");
1343 }
1344 printf ("\tMakeFromSR();\n");
1345 insn_n_cycles += 8;
1346 break;
1347 case i_SWAP:
1348 genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1349 start_brace ();
1350 printf ("\tuint32_t dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
1351 genflags (flag_logical, sz_long, "dst", "", "");
1352 genastore ("dst", curi->smode, "srcreg", sz_long, "src");
1353 break;
1354 case i_EXG:
1355 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1356 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1357 genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1358 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1359 insn_n_cycles = 6;
1360 break;
1361 case i_EXT:
1362 genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1363 start_brace ();
1364 switch (curi->size) {
1365 case sz_byte: printf ("\tuint32_t dst = (int32_t)(int8_t)src;\n"); break;
1366 case sz_word: printf ("\tuint16_t dst = (int16_t)(int8_t)src;\n"); break;
1367 case sz_long: printf ("\tuint32_t dst = (int32_t)(int16_t)src;\n"); break;
1368 default: abort ();
1369 }
1370 genflags (flag_logical,
1371 curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
1372 genastore ("dst", curi->smode, "srcreg",
1373 curi->size == sz_word ? sz_word : sz_long, "src");
1374 break;
1375 case i_MVMEL:
1376 genmovemel (opcode);
1377 break;
1378 case i_MVMLE:
1379 genmovemle (opcode);
1380 break;
1381 case i_TRAP:
1382 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1383 sync_m68k_pc ();
1384 printf ("\tException(src+32,0,M68000_EXC_SRC_CPU);\n");
1385 m68k_pc_offset = 0;
1386 break;
1387 case i_MVR2USP:
1388 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1389 printf ("\tregs.usp = src;\n");
1390 break;
1391 case i_MVUSP2R:
1392 genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1393 genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src");
1394 break;
1395 case i_RESET:
1396//JLH:Not needed printf ("\tcustomreset();\n");
1397 insn_n_cycles = 132; /* I am not so sure about this!? - Thothy */
1398 break;
1399 case i_NOP:
1400 break;
1401 case i_STOP:
1402 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1403 printf ("\tregs.sr = src;\n");
1404 printf ("\tMakeFromSR();\n");
1405 printf ("\tm68k_setstopped(1);\n");
1406 insn_n_cycles = 4;
1407 break;
1408 case i_RTE:
1409 if (cpu_level == 0) {
1410 genamode (Aipi, "7", sz_word, "sr", 1, 0);
1411 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1412 printf ("\tregs.sr = sr; m68k_setpc_rte(pc);\n");
1413 fill_prefetch_0 ();
1414 printf ("\tMakeFromSR();\n");
1415 } else {
1416 int old_brace_level = n_braces;
1417 if (next_cpu_level < 0)
1418 next_cpu_level = 0;
1419 printf ("\tuint16_t newsr; uint32_t newpc; for (;;) {\n");
1420 genamode (Aipi, "7", sz_word, "sr", 1, 0);
1421 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1422 genamode (Aipi, "7", sz_word, "format", 1, 0);
1423 printf ("\tnewsr = sr; newpc = pc;\n");
1424 printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n");
1425 printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n");
1426 printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }\n");
1427 printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }\n");
1428 printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }\n");
1429 printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }\n");
1430 printf ("\telse if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; }\n");
1431 printf ("\telse { Exception(14,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1432 printf ("\tregs.sr = newsr; MakeFromSR();\n}\n");
1433 pop_braces (old_brace_level);
1434 printf ("\tregs.sr = newsr; MakeFromSR();\n");
1435 printf ("\tm68k_setpc_rte(newpc);\n");
1436 fill_prefetch_0 ();
1437 need_endlabel = 1;
1438 }
1439 /* PC is set and prefetch filled. */
1440 m68k_pc_offset = 0;
1441 insn_n_cycles = 20;
1442 break;
1443 case i_RTD:
1444 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1445 genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0);
1446 printf ("\tm68k_areg(regs, 7) += offs;\n");
1447 printf ("\tm68k_setpc_rte(pc);\n");
1448 fill_prefetch_0 ();
1449 /* PC is set and prefetch filled. */
1450 m68k_pc_offset = 0;
1451 break;
1452 case i_LINK:
1453 genamode (Apdi, "7", sz_long, "old", 2, 0);
1454 genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1455 genastore ("src", Apdi, "7", sz_long, "old");
1456 genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src");
1457 genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1458 printf ("\tm68k_areg(regs, 7) += offs;\n");
1459 break;
1460 case i_UNLK:
1461 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1462 printf ("\tm68k_areg(regs, 7) = src;\n");
1463 genamode (Aipi, "7", sz_long, "old", 1, 0);
1464 genastore ("old", curi->smode, "srcreg", curi->size, "src");
1465 break;
1466 case i_RTS:
1467 printf ("\tm68k_do_rts();\n");
1468 fill_prefetch_0 ();
1469 m68k_pc_offset = 0;
1470 insn_n_cycles = 16;
1471 break;
1472 case i_TRAPV:
1473 sync_m68k_pc ();
1474 printf ("\tif (GET_VFLG) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1475 need_endlabel = 1;
1476 break;
1477 case i_RTR:
1478 printf ("\tMakeSR();\n");
1479 genamode (Aipi, "7", sz_word, "sr", 1, 0);
1480 genamode (Aipi, "7", sz_long, "pc", 1, 0);
1481 printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
1482 printf ("\tregs.sr |= sr; m68k_setpc(pc);\n");
1483 fill_prefetch_0 ();
1484 printf ("\tMakeFromSR();\n");
1485 m68k_pc_offset = 0;
1486 insn_n_cycles = 20;
1487 break;
1488 case i_JSR:
1489 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1490 printf ("\tuint32_t oldpc = m68k_getpc () + %d;\n", m68k_pc_offset);
1491 if (using_exception_3) {
1492 printf ("\tif (srca & 1) {\n");
1493 printf ("\t\tlast_addr_for_exception_3 = oldpc;\n");
1494 printf ("\t\tlast_fault_for_exception_3 = srca;\n");
1495 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1496 printf ("\t}\n");
1497 need_endlabel = 1;
1498 }
1499 printf ("\tm68k_do_jsr(m68k_getpc() + %d, srca);\n", m68k_pc_offset);
1500 fill_prefetch_0 ();
1501 m68k_pc_offset = 0;
1502 switch(curi->smode)
1503 {
1504 case Aind: insn_n_cycles=16; break;
1505 case Ad16: insn_n_cycles=18; break;
1506 case Ad8r: insn_n_cycles=22; break;
1507 case absw: insn_n_cycles=18; break;
1508 case absl: insn_n_cycles=20; break;
1509 case PC16: insn_n_cycles=18; break;
1510 case PC8r: insn_n_cycles=22; break;
1511 }
1512 break;
1513 case i_JMP:
1514 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1515 if (using_exception_3) {
1516 printf ("\tif (srca & 1) {\n");
1517 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 6;\n");
1518 printf ("\t\tlast_fault_for_exception_3 = srca;\n");
1519 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1520 printf ("\t}\n");
1521 need_endlabel = 1;
1522 }
1523 printf ("\tm68k_setpc(srca);\n");
1524 fill_prefetch_0 ();
1525 m68k_pc_offset = 0;
1526 switch(curi->smode)
1527 {
1528 case Aind: insn_n_cycles=8; break;
1529 case Ad16: insn_n_cycles=10; break;
1530 case Ad8r: insn_n_cycles=14; break;
1531 case absw: insn_n_cycles=10; break;
1532 case absl: insn_n_cycles=12; break;
1533 case PC16: insn_n_cycles=10; break;
1534 case PC8r: insn_n_cycles=14; break;
1535 }
1536 break;
1537 case i_BSR:
1538 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1539 printf ("\tint32_t s = (int32_t)src + 2;\n");
1540 if (using_exception_3) {
1541 printf ("\tif (src & 1) {\n");
1542 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ?
1543 printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + s;\n");
1544 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1545 printf ("\t}\n");
1546 need_endlabel = 1;
1547 }
1548 printf ("\tm68k_do_bsr(m68k_getpc() + %d, s);\n", m68k_pc_offset);
1549 fill_prefetch_0 ();
1550 m68k_pc_offset = 0;
1551 insn_n_cycles = 18;
1552 break;
1553 case i_Bcc:
1554 if (curi->size == sz_long) {
1555 if (cpu_level < 2) {
1556 printf ("\tm68k_incpc(2);\n");
1557 printf ("\tif (!cctrue(%d)) goto %s;\n", curi->cc, endlabelstr);
1558 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n");
1559 printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 1;\n");
1560 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1561 need_endlabel = 1;
1562 } else {
1563 if (next_cpu_level < 1)
1564 next_cpu_level = 1;
1565 }
1566 }
1567 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1568 printf ("\tif (!cctrue(%d)) goto didnt_jump;\n", curi->cc);
1569 if (using_exception_3) {
1570 printf ("\tif (src & 1) {\n");
1571 printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ?
1572 printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (int32_t)src;\n");
1573 printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1574 printf ("\t}\n");
1575 need_endlabel = 1;
1576 }
1577 printf ("\tm68k_incpc ((int32_t)src + 2);\n");
1578 fill_prefetch_0 ();
1579 printf ("\treturn 10;\n");
1580 printf ("didnt_jump:;\n");
1581 need_endlabel = 1;
1582 insn_n_cycles = (curi->size == sz_byte) ? 8 : 12;
1583 break;
1584 case i_LEA:
1585 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1586 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1587 genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
1588 /* Set correct cycles: According to the M68K User Manual, LEA takes 12
1589 * cycles in Ad8r and PC8r mode, but it takes 14 (or 16) cycles on a real ST: */
1590 if (curi->smode == Ad8r || curi->smode == PC8r)
1591 insn_n_cycles = 14;
1592 break;
1593 case i_PEA:
1594 genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1595 genamode (Apdi, "7", sz_long, "dst", 2, 0);
1596 genastore ("srca", Apdi, "7", sz_long, "dst");
1597 /* Set correct cycles: */
1598 switch(curi->smode)
1599 {
1600 case Aind: insn_n_cycles=12; break;
1601 case Ad16: insn_n_cycles=16; break;
1602 /* Note: according to the M68K User Manual, PEA takes 20 cycles for
1603 * the Ad8r mode, but on a real ST, it takes 22 (or 24) cycles! */
1604 case Ad8r: insn_n_cycles=22; break;
1605 case absw: insn_n_cycles=16; break;
1606 case absl: insn_n_cycles=20; break;
1607 case PC16: insn_n_cycles=16; break;
1608 /* Note: PEA with PC8r takes 20 cycles according to the User Manual,
1609 * but it takes 22 (or 24) cycles on a real ST: */
1610 case PC8r: insn_n_cycles=22; break;
1611 }
1612 break;
1613 case i_DBcc:
1614 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1615 genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1616
1617 printf ("\tif (!cctrue(%d)) {\n\t", curi->cc);
1618 genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src");
1619
1620 printf ("\t\tif (src) {\n");
1621 if (using_exception_3) {
1622 printf ("\t\t\tif (offs & 1) {\n");
1623 printf ("\t\t\tlast_addr_for_exception_3 = m68k_getpc() + 2 + 2;\n"); // [NP] last_addr is pc+4, not pc+2
1624 printf ("\t\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (int32_t)offs + 2;\n");
1625 printf ("\t\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr);
1626 printf ("\t\t}\n");
1627 need_endlabel = 1;
1628 }
1629 printf ("\t\t\tm68k_incpc((int32_t)offs + 2);\n");
1630 fill_prefetch_0 ();
1631 printf ("\t\t\treturn 10;\n");
1632 printf ("\t\t} else {\n\t\t\t");
1633 {
1634 int tmp_offset = m68k_pc_offset;
1635 sync_m68k_pc(); /* not so nice to call it here... */
1636 m68k_pc_offset = tmp_offset;
1637 }
1638 printf ("\t\t\treturn 14;\n");
1639 printf ("\t\t}\n");
1640 printf ("\t}\n");
1641 insn_n_cycles = 12;
1642 need_endlabel = 1;
1643 break;
1644 case i_Scc:
1645 genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1646 start_brace ();
1647 printf ("\tint val = cctrue(%d) ? 0xff : 0;\n", curi->cc);
1648 genastore ("val", curi->smode, "srcreg", curi->size, "src");
1649 if (curi->smode!=Dreg) insn_n_cycles += 4;
1650 else
1651 { /* [NP] if result is TRUE, we return 6 instead of 4 */
1652 printf ("\tif (val) { m68k_incpc(2) ; return 4+2; }\n");
1653 }
1654 break;
1655 case i_DIVU:
1656 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1657 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1658 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1659 sync_m68k_pc ();
1660 /* Clear V flag when dividing by zero - Alcatraz Odyssey demo depends
1661 * on this (actually, it's doing a DIVS). */
1662 printf ("\tif (src == 0) { SET_VFLG (0); Exception (5, oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr);
1663 printf ("\tuint32_t newv = (uint32_t)dst / (uint32_t)(uint16_t)src;\n");
1664 printf ("\tuint32_t rem = (uint32_t)dst %% (uint32_t)(uint16_t)src;\n");
1665 /* The N flag appears to be set each time there is an overflow.
1666 * Weird. */
1667 printf ("\tif (newv > 0xffff) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n");
1668 genflags (flag_logical, sz_word, "newv", "", "");
1669 printf ("\tnewv = (newv & 0xffff) | ((uint32_t)rem << 16);\n");
1670 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1671 printf ("\t}\n");
1672 printf ("\t}\n");
1673// insn_n_cycles += 136;
1674 printf ("\tretcycles = getDivu68kCycles((uint32_t)dst, (uint16_t)src);\n");
1675 sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles);
1676 need_endlabel = 1;
1677 break;
1678 case i_DIVS:
1679 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1680 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1681 genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1682 sync_m68k_pc ();
1683 printf ("\tif (src == 0) { SET_VFLG (0); Exception(5,oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr);
1684 printf ("\tint32_t newv = (int32_t)dst / (int32_t)(int16_t)src;\n");
1685 printf ("\tuint16_t rem = (int32_t)dst %% (int32_t)(int16_t)src;\n");
1686 printf ("\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n");
1687 printf ("\tif (((int16_t)rem < 0) != ((int32_t)dst < 0)) rem = -rem;\n");
1688 genflags (flag_logical, sz_word, "newv", "", "");
1689 printf ("\tnewv = (newv & 0xffff) | ((uint32_t)rem << 16);\n");
1690 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1691 printf ("\t}\n");
1692 printf ("\t}\n");
1693// insn_n_cycles += 154;
1694 printf ("\tretcycles = getDivs68kCycles((int32_t)dst, (int16_t)src);\n");
1695 sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles);
1696 need_endlabel = 1;
1697 break;
1698 case i_MULU:
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 = (uint32_t)(uint16_t)dst * (uint32_t)(uint16_t)src;\n");
1703 genflags (flag_logical, sz_long, "newv", "", "");
1704 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1705 /* [NP] number of cycles is 38 + 2n + ea time ; n is the number of 1 bits in src */
1706 insn_n_cycles += 38-4; /* insn_n_cycles is already initialized to 4 instead of 0 */
1707 printf ("\twhile (src) { if (src & 1) retcycles++; src = (uint16_t)src >> 1; }\n");
1708 sprintf(exactCpuCycles," return (%i+retcycles*2);", insn_n_cycles);
1709 break;
1710 case i_MULS:
1711 genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1712 genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
1713 start_brace ();
1714 printf ("\tuint32_t newv = (int32_t)(int16_t)dst * (int32_t)(int16_t)src;\n");
1715 printf ("\tuint32_t src2;\n");
1716 genflags (flag_logical, sz_long, "newv", "", "");
1717 genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1718 /* [NP] number of cycles is 38 + 2n + ea time ; n is the number of 01 or 10 patterns in src expanded to 17 bits */
1719 insn_n_cycles += 38-4; /* insn_n_cycles is already initialized to 4 instead of 0 */
1720 printf ("\tsrc2 = ((uint32_t)src) << 1;\n");
1721 printf ("\twhile (src2) { if ( ( (src2 & 3) == 1 ) || ( (src2 & 3) == 2 ) ) retcycles++; src2 >>= 1; }\n");
1722 sprintf(exactCpuCycles," return (%i+retcycles*2);", insn_n_cycles);
1723 break;
1724 case i_CHK:
1725 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1726 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1727 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1728 sync_m68k_pc ();
1729 printf ("\tif ((int32_t)dst < 0) { SET_NFLG (1); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1730 printf ("\telse if (dst > src) { SET_NFLG (0); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr);
1731 need_endlabel = 1;
1732 insn_n_cycles += 6;
1733 break;
1734
1735 case i_CHK2:
1736 printf ("\tuint32_t oldpc = m68k_getpc();\n");
1737 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
1738 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1739 printf ("\t{int32_t upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
1740 switch (curi->size) {
1741 case sz_byte:
1742 printf ("\tlower=(int32_t)(int8_t)m68k_read_memory_8(dsta); upper = (int32_t)(int8_t)m68k_read_memory_8(dsta+1);\n");
1743 printf ("\tif ((extra & 0x8000) == 0) reg = (int32_t)(int8_t)reg;\n");
1744 break;
1745 case sz_word:
1746 printf ("\tlower=(int32_t)(int16_t)m68k_read_memory_16(dsta); upper = (int32_t)(int16_t)m68k_read_memory_16(dsta+2);\n");
1747 printf ("\tif ((extra & 0x8000) == 0) reg = (int32_t)(int16_t)reg;\n");
1748 break;
1749 case sz_long:
1750 printf ("\tlower=m68k_read_memory_32(dsta); upper = m68k_read_memory_32(dsta+4);\n");
1751 break;
1752 default:
1753 abort ();
1754 }
1755 printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
1756 printf ("\tSET_CFLG (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
1757 sync_m68k_pc ();
1758 printf ("\tif ((extra & 0x800) && GET_CFLG) { Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n}\n", endlabelstr);
1759 need_endlabel = 1;
1760 break;
1761
1762 case i_ASR:
1763 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1764 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1765 start_brace ();
1766 switch (curi->size) {
1767 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1768 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1769 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1770 default: abort ();
1771 }
1772 printf ("\tuint32_t sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1);
1773 printf ("\tcnt &= 63;\n");
1774 printf ("\tretcycles = cnt;\n");
1775 printf ("\tCLEAR_CZNV;\n");
1776 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1777 printf ("\t\tval = %s & (uint32_t)-sign;\n", bit_mask (curi->size));
1778 printf ("\t\tSET_CFLG (sign);\n");
1779 duplicate_carry ();
1780 if (source_is_imm1_8 (curi))
1781 printf ("\t} else {\n");
1782 else
1783 printf ("\t} else if (cnt > 0) {\n");
1784 printf ("\t\tval >>= cnt - 1;\n");
1785 printf ("\t\tSET_CFLG (val & 1);\n");
1786 duplicate_carry ();
1787 printf ("\t\tval >>= 1;\n");
1788 printf ("\t\tval |= (%s << (%d - cnt)) & (uint32_t)-sign;\n",
1789 bit_mask (curi->size),
1790 bit_size (curi->size));
1791 printf ("\t\tval &= %s;\n", bit_mask (curi->size));
1792 printf ("\t}\n");
1793 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1794 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1795 if(curi->size==sz_long)
1796 strcpy(exactCpuCycles," return (8+retcycles*2);");
1797 else
1798 strcpy(exactCpuCycles," return (6+retcycles*2);");
1799 break;
1800 case i_ASL:
1801 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1802 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1803 start_brace ();
1804 switch (curi->size) {
1805 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1806 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1807 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1808 default: abort ();
1809 }
1810 printf ("\tcnt &= 63;\n");
1811 printf ("\tretcycles = cnt;\n");
1812 printf ("\tCLEAR_CZNV;\n");
1813 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1814 printf ("\t\tSET_VFLG (val != 0);\n");
1815 printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
1816 bit_size (curi->size));
1817 duplicate_carry ();
1818 printf ("\t\tval = 0;\n");
1819 if (source_is_imm1_8 (curi))
1820 printf ("\t} else {\n");
1821 else
1822 printf ("\t} else if (cnt > 0) {\n");
1823 printf ("\t\tuint32_t mask = (%s << (%d - cnt)) & %s;\n",
1824 bit_mask (curi->size),
1825 bit_size (curi->size) - 1,
1826 bit_mask (curi->size));
1827 printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n");
1828 printf ("\t\tval <<= cnt - 1;\n");
1829 printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1830 duplicate_carry ();
1831 printf ("\t\tval <<= 1;\n");
1832 printf ("\t\tval &= %s;\n", bit_mask (curi->size));
1833 printf ("\t}\n");
1834 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1835 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1836 if(curi->size==sz_long)
1837 strcpy(exactCpuCycles," return (8+retcycles*2);");
1838 else
1839 strcpy(exactCpuCycles," return (6+retcycles*2);");
1840 break;
1841 case i_LSR:
1842 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1843 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1844 start_brace ();
1845 switch (curi->size) {
1846 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1847 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1848 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1849 default: abort ();
1850 }
1851 printf ("\tcnt &= 63;\n");
1852 printf ("\tretcycles = cnt;\n");
1853 printf ("\tCLEAR_CZNV;\n");
1854 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1855 printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n",
1856 bit_size (curi->size), bit_size (curi->size) - 1);
1857 duplicate_carry ();
1858 printf ("\t\tval = 0;\n");
1859 if (source_is_imm1_8 (curi))
1860 printf ("\t} else {\n");
1861 else
1862 printf ("\t} else if (cnt > 0) {\n");
1863 printf ("\t\tval >>= cnt - 1;\n");
1864 printf ("\t\tSET_CFLG (val & 1);\n");
1865 duplicate_carry ();
1866 printf ("\t\tval >>= 1;\n");
1867 printf ("\t}\n");
1868 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1869 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1870 if(curi->size==sz_long)
1871 strcpy(exactCpuCycles," return (8+retcycles*2);");
1872 else
1873 strcpy(exactCpuCycles," return (6+retcycles*2);");
1874 break;
1875 case i_LSL:
1876 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1877 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1878 start_brace ();
1879 switch (curi->size) {
1880 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1881 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1882 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1883 default: abort ();
1884 }
1885 printf ("\tcnt &= 63;\n");
1886 printf ("\tretcycles = cnt;\n");
1887 printf ("\tCLEAR_CZNV;\n");
1888 printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1889 printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
1890 bit_size (curi->size));
1891 duplicate_carry ();
1892 printf ("\t\tval = 0;\n");
1893 if (source_is_imm1_8 (curi))
1894 printf ("\t} else {\n");
1895 else
1896 printf ("\t} else if (cnt > 0) {\n");
1897 printf ("\t\tval <<= (cnt - 1);\n");
1898 printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1899 duplicate_carry ();
1900 printf ("\t\tval <<= 1;\n");
1901 printf ("\tval &= %s;\n", bit_mask (curi->size));
1902 printf ("\t}\n");
1903 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1904 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1905 if(curi->size==sz_long)
1906 strcpy(exactCpuCycles," return (8+retcycles*2);");
1907 else
1908 strcpy(exactCpuCycles," return (6+retcycles*2);");
1909 break;
1910 case i_ROL:
1911 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1912 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1913 start_brace ();
1914 switch (curi->size) {
1915 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1916 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1917 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1918 default: abort ();
1919 }
1920 printf ("\tcnt &= 63;\n");
1921 printf ("\tretcycles = cnt;\n");
1922 printf ("\tCLEAR_CZNV;\n");
1923 if (source_is_imm1_8 (curi))
1924 printf ("{");
1925 else
1926 printf ("\tif (cnt > 0) {\n");
1927 printf ("\tuint32_t loval;\n");
1928 printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
1929 printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size));
1930 printf ("\tval <<= cnt;\n");
1931 printf ("\tval |= loval;\n");
1932 printf ("\tval &= %s;\n", bit_mask (curi->size));
1933 printf ("\tSET_CFLG (val & 1);\n");
1934 printf ("}\n");
1935 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1936 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1937 if(curi->size==sz_long)
1938 strcpy(exactCpuCycles," return (8+retcycles*2);");
1939 else
1940 strcpy(exactCpuCycles," return (6+retcycles*2);");
1941 break;
1942 case i_ROR:
1943 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1944 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1945 start_brace ();
1946 switch (curi->size) {
1947 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1948 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1949 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1950 default: abort ();
1951 }
1952 printf ("\tcnt &= 63;\n");
1953 printf ("\tretcycles = cnt;\n");
1954 printf ("\tCLEAR_CZNV;\n");
1955 if (source_is_imm1_8 (curi))
1956 printf ("{");
1957 else
1958 printf ("\tif (cnt > 0) {");
1959 printf ("\tuint32_t hival;\n");
1960 printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
1961 printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size));
1962 printf ("\tval >>= cnt;\n");
1963 printf ("\tval |= hival;\n");
1964 printf ("\tval &= %s;\n", bit_mask (curi->size));
1965 printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1966 printf ("\t}\n");
1967 genflags (flag_logical_noclobber, curi->size, "val", "", "");
1968 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1969 if(curi->size==sz_long)
1970 strcpy(exactCpuCycles," return (8+retcycles*2);");
1971 else
1972 strcpy(exactCpuCycles," return (6+retcycles*2);");
1973 break;
1974 case i_ROXL:
1975 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1976 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1977 start_brace ();
1978 switch (curi->size) {
1979 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
1980 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
1981 case sz_long: printf ("\tuint32_t val = data;\n"); break;
1982 default: abort ();
1983 }
1984 printf ("\tcnt &= 63;\n");
1985 printf ("\tretcycles = cnt;\n");
1986 printf ("\tCLEAR_CZNV;\n");
1987 if (source_is_imm1_8 (curi))
1988 printf ("{");
1989 else {
1990 force_range_for_rox ("cnt", curi->size);
1991 printf ("\tif (cnt > 0) {\n");
1992 }
1993 printf ("\tcnt--;\n");
1994 printf ("\t{\n\tuint32_t carry;\n");
1995 printf ("\tuint32_t loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1);
1996 printf ("\tcarry = loval & 1;\n");
1997 printf ("\tval = (((val << 1) | GET_XFLG) << cnt) | (loval >> 1);\n");
1998 printf ("\tSET_XFLG (carry);\n");
1999 printf ("\tval &= %s;\n", bit_mask (curi->size));
2000 printf ("\t} }\n");
2001 printf ("\tSET_CFLG (GET_XFLG);\n");
2002 genflags (flag_logical_noclobber, curi->size, "val", "", "");
2003 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2004 if(curi->size==sz_long)
2005 strcpy(exactCpuCycles," return (8+retcycles*2);");
2006 else
2007 strcpy(exactCpuCycles," return (6+retcycles*2);");
2008 break;
2009 case i_ROXR:
2010 genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2011 genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2012 start_brace ();
2013 switch (curi->size) {
2014 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2015 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2016 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2017 default: abort ();
2018 }
2019 printf ("\tcnt &= 63;\n");
2020 printf ("\tretcycles = cnt;\n");
2021 printf ("\tCLEAR_CZNV;\n");
2022 if (source_is_imm1_8 (curi))
2023 printf ("{");
2024 else {
2025 force_range_for_rox ("cnt", curi->size);
2026 printf ("\tif (cnt > 0) {\n");
2027 }
2028 printf ("\tcnt--;\n");
2029 printf ("\t{\n\tuint32_t carry;\n");
2030 printf ("\tuint32_t hival = (val << 1) | GET_XFLG;\n");
2031 printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1);
2032 printf ("\tval >>= cnt;\n");
2033 printf ("\tcarry = val & 1;\n");
2034 printf ("\tval >>= 1;\n");
2035 printf ("\tval |= hival;\n");
2036 printf ("\tSET_XFLG (carry);\n");
2037 printf ("\tval &= %s;\n", bit_mask (curi->size));
2038 printf ("\t} }\n");
2039 printf ("\tSET_CFLG (GET_XFLG);\n");
2040 genflags (flag_logical_noclobber, curi->size, "val", "", "");
2041 genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2042 if(curi->size==sz_long)
2043 strcpy(exactCpuCycles," return (8+retcycles*2);");
2044 else
2045 strcpy(exactCpuCycles," return (6+retcycles*2);");
2046 break;
2047 case i_ASRW:
2048 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2049 start_brace ();
2050 switch (curi->size) {
2051 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2052 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2053 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2054 default: abort ();
2055 }
2056 printf ("\tuint32_t sign = %s & val;\n", cmask (curi->size));
2057 printf ("\tuint32_t cflg = val & 1;\n");
2058 printf ("\tval = (val >> 1) | sign;\n");
2059 genflags (flag_logical, curi->size, "val", "", "");
2060 printf ("\tSET_CFLG (cflg);\n");
2061 duplicate_carry ();
2062 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2063 break;
2064 case i_ASLW:
2065 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2066 start_brace ();
2067 switch (curi->size) {
2068 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2069 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2070 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2071 default: abort ();
2072 }
2073 printf ("\tuint32_t sign = %s & val;\n", cmask (curi->size));
2074 printf ("\tuint32_t sign2;\n");
2075 printf ("\tval <<= 1;\n");
2076 genflags (flag_logical, curi->size, "val", "", "");
2077 printf ("\tsign2 = %s & val;\n", cmask (curi->size));
2078 printf ("\tSET_CFLG (sign != 0);\n");
2079 duplicate_carry ();
2080
2081 printf ("\tSET_VFLG (GET_VFLG | (sign2 != sign));\n");
2082 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2083 break;
2084 case i_LSRW:
2085 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2086 start_brace ();
2087 switch (curi->size) {
2088 case sz_byte: printf ("\tuint32_t val = (uint8_t)data;\n"); break;
2089 case sz_word: printf ("\tuint32_t val = (uint16_t)data;\n"); break;
2090 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2091 default: abort ();
2092 }
2093 printf ("\tuint32_t carry = val & 1;\n");
2094 printf ("\tval >>= 1;\n");
2095 genflags (flag_logical, curi->size, "val", "", "");
2096 printf ("SET_CFLG (carry);\n");
2097 duplicate_carry ();
2098 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2099 break;
2100 case i_LSLW:
2101 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2102 start_brace ();
2103 switch (curi->size) {
2104 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2105 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2106 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2107 default: abort ();
2108 }
2109 printf ("\tuint32_t carry = val & %s;\n", cmask (curi->size));
2110 printf ("\tval <<= 1;\n");
2111 genflags (flag_logical, curi->size, "val", "", "");
2112 printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2113 duplicate_carry ();
2114 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2115 break;
2116 case i_ROLW:
2117 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2118 start_brace ();
2119 switch (curi->size) {
2120 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2121 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2122 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2123 default: abort ();
2124 }
2125 printf ("\tuint32_t carry = val & %s;\n", cmask (curi->size));
2126 printf ("\tval <<= 1;\n");
2127 printf ("\tif (carry) val |= 1;\n");
2128 genflags (flag_logical, curi->size, "val", "", "");
2129 printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2130 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2131 break;
2132 case i_RORW:
2133 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2134 start_brace ();
2135 switch (curi->size) {
2136 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2137 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2138 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2139 default: abort ();
2140 }
2141 printf ("\tuint32_t carry = val & 1;\n");
2142 printf ("\tval >>= 1;\n");
2143 printf ("\tif (carry) val |= %s;\n", cmask (curi->size));
2144 genflags (flag_logical, curi->size, "val", "", "");
2145 printf ("SET_CFLG (carry);\n");
2146 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2147 break;
2148 case i_ROXLW:
2149 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2150 start_brace ();
2151 switch (curi->size) {
2152 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2153 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2154 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2155 default: abort ();
2156 }
2157 printf ("\tuint32_t carry = val & %s;\n", cmask (curi->size));
2158 printf ("\tval <<= 1;\n");
2159 printf ("\tif (GET_XFLG) val |= 1;\n");
2160 genflags (flag_logical, curi->size, "val", "", "");
2161 printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2162 duplicate_carry ();
2163 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2164 break;
2165 case i_ROXRW:
2166 genamode (curi->smode, "srcreg", curi->size, "data", 1, 0);
2167 start_brace ();
2168 switch (curi->size) {
2169 case sz_byte: printf ("\tuint8_t val = data;\n"); break;
2170 case sz_word: printf ("\tuint16_t val = data;\n"); break;
2171 case sz_long: printf ("\tuint32_t val = data;\n"); break;
2172 default: abort ();
2173 }
2174 printf ("\tuint32_t carry = val & 1;\n");
2175 printf ("\tval >>= 1;\n");
2176 printf ("\tif (GET_XFLG) val |= %s;\n", cmask (curi->size));
2177 genflags (flag_logical, curi->size, "val", "", "");
2178 printf ("SET_CFLG (carry);\n");
2179 duplicate_carry ();
2180 genastore ("val", curi->smode, "srcreg", curi->size, "data");
2181 break;
2182 case i_MOVEC2:
2183 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2184 start_brace ();
2185 printf ("\tint regno = (src >> 12) & 15;\n");
2186 printf ("\tuint32_t *regp = regs.regs + regno;\n");
2187 printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
2188 break;
2189 case i_MOVE2C:
2190 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2191 start_brace ();
2192 printf ("\tint regno = (src >> 12) & 15;\n");
2193 printf ("\tuint32_t *regp = regs.regs + regno;\n");
2194 printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
2195 break;
2196 case i_CAS:
2197 {
2198 int old_brace_level;
2199 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2200 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2201 start_brace ();
2202 printf ("\tint ru = (src >> 6) & 7;\n");
2203 printf ("\tint rc = src & 7;\n");
2204 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc)", "dst");
2205 printf ("\tif (GET_ZFLG)");
2206 old_brace_level = n_braces;
2207 start_brace ();
2208 genastore ("(m68k_dreg(regs, ru))", curi->dmode, "dstreg", curi->size, "dst");
2209 pop_braces (old_brace_level);
2210 printf ("else");
2211 start_brace ();
2212 printf ("m68k_dreg(regs, rc) = dst;\n");
2213 pop_braces (old_brace_level);
2214 }
2215 break;
2216 case i_CAS2:
2217 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2218 printf ("\tuint32_t rn1 = regs.regs[(extra >> 28) & 15];\n");
2219 printf ("\tuint32_t rn2 = regs.regs[(extra >> 12) & 15];\n");
2220 if (curi->size == sz_word) {
2221 int old_brace_level = n_braces;
2222 printf ("\tuint16_t dst1 = m68k_read_memory_16(rn1), dst2 = m68k_read_memory_16(rn2);\n");
2223 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1");
2224 printf ("\tif (GET_ZFLG) {\n");
2225 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, extra & 7)", "dst2");
2226 printf ("\tif (GET_ZFLG) {\n");
2227 printf ("\tm68k_write_memory_16(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n");
2228 printf ("\tm68k_write_memory_16(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n");
2229 printf ("\t}}\n");
2230 pop_braces (old_brace_level);
2231 printf ("\tif (! GET_ZFLG) {\n");
2232 printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = (m68k_dreg(regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
2233 printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = (m68k_dreg(regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
2234 printf ("\t}\n");
2235 } else {
2236 int old_brace_level = n_braces;
2237 printf ("\tuint32_t dst1 = m68k_read_memory_32(rn1), dst2 = m68k_read_memory_32(rn2);\n");
2238 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1");
2239 printf ("\tif (GET_ZFLG) {\n");
2240 genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, extra & 7)", "dst2");
2241 printf ("\tif (GET_ZFLG) {\n");
2242 printf ("\tm68k_write_memory_32(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n");
2243 printf ("\tm68k_write_memory_32(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n");
2244 printf ("\t}}\n");
2245 pop_braces (old_brace_level);
2246 printf ("\tif (! GET_ZFLG) {\n");
2247 printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = dst1;\n");
2248 printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = dst2;\n");
2249 printf ("\t}\n");
2250 }
2251 break;
2252 case i_MOVES: /* ignore DFC and SFC because we have no MMU */
2253 {
2254 int old_brace_level;
2255 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2256 printf ("\tif (extra & 0x800)\n");
2257 old_brace_level = n_braces;
2258 start_brace ();
2259 printf ("\tuint32_t src = regs.regs[(extra >> 12) & 15];\n");
2260 genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
2261 genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
2262 pop_braces (old_brace_level);
2263 printf ("else");
2264 start_brace ();
2265 genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0);
2266 printf ("\tif (extra & 0x8000) {\n");
2267 switch (curi->size) {
2268 case sz_byte: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (int32_t)(int8_t)src;\n"); break;
2269 case sz_word: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (int32_t)(int16_t)src;\n"); break;
2270 case sz_long: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = src;\n"); break;
2271 default: abort ();
2272 }
2273 printf ("\t} else {\n");
2274 genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, "");
2275 printf ("\t}\n");
2276 pop_braces (old_brace_level);
2277 }
2278 break;
2279 case i_BKPT: /* only needed for hardware emulators */
2280 sync_m68k_pc ();
2281 printf ("\top_illg(opcode);\n");
2282 break;
2283 case i_CALLM: /* not present in 68030 */
2284 sync_m68k_pc ();
2285 printf ("\top_illg(opcode);\n");
2286 break;
2287 case i_RTM: /* not present in 68030 */
2288 sync_m68k_pc ();
2289 printf ("\top_illg(opcode);\n");
2290 break;
2291 case i_TRAPcc:
2292 if (curi->smode != am_unknown && curi->smode != am_illg)
2293 genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0);
2294 printf ("\tif (cctrue(%d)) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", curi->cc, endlabelstr);
2295 need_endlabel = 1;
2296 break;
2297 case i_DIVL:
2298 sync_m68k_pc ();
2299 start_brace ();
2300 printf ("\tuint32_t oldpc = m68k_getpc();\n");
2301 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2302 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2303 sync_m68k_pc ();
2304 printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n");
2305 break;
2306 case i_MULL:
2307 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2308 genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2309 sync_m68k_pc ();
2310 printf ("\tm68k_mull(opcode, dst, extra);\n");
2311 break;
2312 case i_BFTST:
2313 case i_BFEXTU:
2314 case i_BFCHG:
2315 case i_BFEXTS:
2316 case i_BFCLR:
2317 case i_BFFFO:
2318 case i_BFSET:
2319 case i_BFINS:
2320 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2321 genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0);
2322 start_brace ();
2323 printf ("\tint32_t offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n");
2324 printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n");
2325 if (curi->dmode == Dreg) {
2326 printf ("\tuint32_t tmp = m68k_dreg(regs, dstreg) << (offset & 0x1f);\n");
2327 } else {
2328 printf ("\tuint32_t tmp,bf0,bf1;\n");
2329 printf ("\tdsta += (offset >> 3) | (offset & 0x80000000 ? ~0x1fffffff : 0);\n");
2330 printf ("\tbf0 = m68k_read_memory_32(dsta);bf1 = m68k_read_memory_8(dsta+4) & 0xff;\n");
2331 printf ("\ttmp = (bf0 << (offset & 7)) | (bf1 >> (8 - (offset & 7)));\n");
2332 }
2333 printf ("\ttmp >>= (32 - width);\n");
2334 printf ("\tSET_NFLG (tmp & (1 << (width-1)) ? 1 : 0);\n");
2335 printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n");
2336 switch (curi->mnemo) {
2337 case i_BFTST:
2338 break;
2339 case i_BFEXTU:
2340 printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n");
2341 break;
2342 case i_BFCHG:
2343 printf ("\ttmp = ~tmp;\n");
2344 break;
2345 case i_BFEXTS:
2346 printf ("\tif (GET_NFLG) tmp |= width == 32 ? 0 : (-1 << width);\n");
2347 printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n");
2348 break;
2349 case i_BFCLR:
2350 printf ("\ttmp = 0;\n");
2351 break;
2352 case i_BFFFO:
2353 printf ("\t{ uint32_t mask = 1 << (width-1);\n");
2354 printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n");
2355 printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = offset;\n");
2356 break;
2357 case i_BFSET:
2358 printf ("\ttmp = 0xffffffff;\n");
2359 break;
2360 case i_BFINS:
2361 printf ("\ttmp = m68k_dreg(regs, (extra >> 12) & 7);\n");
2362 printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n");
2363 printf ("\tSET_ZFLG (tmp == 0);\n");
2364 break;
2365 default:
2366 break;
2367 }
2368 if (curi->mnemo == i_BFCHG
2369 || curi->mnemo == i_BFCLR
2370 || curi->mnemo == i_BFSET
2371 || curi->mnemo == i_BFINS)
2372 {
2373 printf ("\ttmp <<= (32 - width);\n");
2374 if (curi->dmode == Dreg) {
2375 printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & ((offset & 0x1f) == 0 ? 0 :\n");
2376 printf ("\t\t(0xffffffff << (32 - (offset & 0x1f))))) |\n");
2377 printf ("\t\t(tmp >> (offset & 0x1f)) |\n");
2378 printf ("\t\t(((offset & 0x1f) + width) >= 32 ? 0 :\n");
2379 printf (" (m68k_dreg(regs, dstreg) & ((uint32_t)0xffffffff >> ((offset & 0x1f) + width))));\n");
2380 } else {
2381 printf ("\tbf0 = (bf0 & (0xff000000 << (8 - (offset & 7)))) |\n");
2382 printf ("\t\t(tmp >> (offset & 7)) |\n");
2383 printf ("\t\t(((offset & 7) + width) >= 32 ? 0 :\n");
2384 printf ("\t\t (bf0 & ((uint32_t)0xffffffff >> ((offset & 7) + width))));\n");
2385 printf ("\tm68k_write_memory_32(dsta,bf0 );\n");
2386 printf ("\tif (((offset & 7) + width) > 32) {\n");
2387 printf ("\t\tbf1 = (bf1 & (0xff >> (width - 32 + (offset & 7)))) |\n");
2388 printf ("\t\t\t(tmp << (8 - (offset & 7)));\n");
2389 printf ("\t\tm68k_write_memory_8(dsta+4,bf1);\n");
2390 printf ("\t}\n");
2391 }
2392 }
2393 break;
2394 case i_PACK:
2395 if (curi->smode == Dreg) {
2396 printf ("\tuint16_t val = m68k_dreg(regs, srcreg) + %s;\n", gen_nextiword ());
2397 printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
2398 } else {
2399 printf ("\tuint16_t val;\n");
2400 printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
2401 printf ("\tval = (uint16_t)m68k_read_memory_8(m68k_areg(regs, srcreg));\n");
2402 printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
2403 printf ("\tval = (val | ((uint16_t)m68k_read_memory_8(m68k_areg(regs, srcreg)) << 8)) + %s;\n", gen_nextiword ());
2404 printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
2405 printf ("\tm68k_write_memory_8(m68k_areg(regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n");
2406 }
2407 break;
2408 case i_UNPK:
2409 if (curi->smode == Dreg) {
2410 printf ("\tuint16_t val = m68k_dreg(regs, srcreg);\n");
2411 printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ());
2412 printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffff0000) | (val & 0xffff);\n");
2413 } else {
2414 printf ("\tuint16_t val;\n");
2415 printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
2416 printf ("\tval = (uint16_t)m68k_read_memory_8(m68k_areg(regs, srcreg));\n");
2417 printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ());
2418 printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
2419 printf ("\tm68k_write_memory_8(m68k_areg(regs, dstreg),val);\n");
2420 printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
2421 printf ("\tm68k_write_memory_8(m68k_areg(regs, dstreg),val >> 8);\n");
2422 }
2423 break;
2424 case i_TAS:
2425 genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
2426 genflags (flag_logical, curi->size, "src", "", "");
2427 printf ("\tsrc |= 0x80;\n");
2428 genastore ("src", curi->smode, "srcreg", curi->size, "src");
2429 if( curi->smode!=Dreg ) insn_n_cycles += 2;
2430 break;
2431 case i_FPP:
2432 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2433 sync_m68k_pc ();
2434 printf ("\tfpp_opp(opcode,extra);\n");
2435 break;
2436 case i_FDBcc:
2437 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2438 sync_m68k_pc ();
2439 printf ("\tfdbcc_opp(opcode,extra);\n");
2440 break;
2441 case i_FScc:
2442 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2443 sync_m68k_pc ();
2444 printf ("\tfscc_opp(opcode,extra);\n");
2445 break;
2446 case i_FTRAPcc:
2447 sync_m68k_pc ();
2448 start_brace ();
2449 printf ("\tuint32_t oldpc = m68k_getpc();\n");
2450 if (curi->smode != am_unknown && curi->smode != am_illg)
2451 genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0);
2452 sync_m68k_pc ();
2453 printf ("\tftrapcc_opp(opcode,oldpc);\n");
2454 break;
2455 case i_FBcc:
2456 sync_m68k_pc ();
2457 start_brace ();
2458 printf ("\tuint32_t pc = m68k_getpc();\n");
2459 genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0);
2460 sync_m68k_pc ();
2461 printf ("\tfbcc_opp(opcode,pc,extra);\n");
2462 break;
2463 case i_FSAVE:
2464 sync_m68k_pc ();
2465 printf ("\tfsave_opp(opcode);\n");
2466 break;
2467 case i_FRESTORE:
2468 sync_m68k_pc ();
2469 printf ("\tfrestore_opp(opcode);\n");
2470 break;
2471
2472 case i_CINVL:
2473 case i_CINVP:
2474 case i_CINVA:
2475 case i_CPUSHL:
2476 case i_CPUSHP:
2477 case i_CPUSHA:
2478 break;
2479 case i_MOVE16:
2480 if ((opcode & 0xfff8) == 0xf620) {
2481 /* MOVE16 (Ax)+,(Ay)+ */
2482 printf ("\tuint32_t mems = m68k_areg(regs, srcreg) & ~15, memd;\n");
2483 printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword());
2484 printf ("\tmemd = m68k_areg(regs, dstreg) & ~15;\n");
2485 printf ("\tm68k_write_memory_32(memd, m68k_read_memory_32(mems));\n");
2486 printf ("\tm68k_write_memory_32(memd+4, m68k_read_memory_32(mems+4));\n");
2487 printf ("\tm68k_write_memory_32(memd+8, m68k_read_memory_32(mems+8));\n");
2488 printf ("\tm68k_write_memory_32(memd+12, m68k_read_memory_32(mems+12));\n");
2489 printf ("\tif (srcreg != dstreg)\n");
2490 printf ("\tm68k_areg(regs, srcreg) += 16;\n");
2491 printf ("\tm68k_areg(regs, dstreg) += 16;\n");
2492 } else {
2493 /* Other variants */
2494 genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2);
2495 genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2);
2496 printf ("\tmemsa &= ~15;\n");
2497 printf ("\tmemda &= ~15;\n");
2498 printf ("\tm68k_write_memory_32(memda, m68k_read_memory_32(memsa));\n");
2499 printf ("\tm68k_write_memory_32(memda+4, m68k_read_memory_32(memsa+4));\n");
2500 printf ("\tm68k_write_memory_32(memda+8, m68k_read_memory_32(memsa+8));\n");
2501 printf ("\tm68k_write_memory_32(memda+12, m68k_read_memory_32(memsa+12));\n");
2502 if ((opcode & 0xfff8) == 0xf600)
2503 printf ("\tm68k_areg(regs, srcreg) += 16;\n");
2504 else if ((opcode & 0xfff8) == 0xf608)
2505 printf ("\tm68k_areg(regs, dstreg) += 16;\n");
2506 }
2507 break;
2508
2509 case i_MMUOP:
2510 genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
2511 sync_m68k_pc ();
2512 printf ("\tmmu_op(opcode,extra);\n");
2513 break;
2514 default:
2515 abort ();
2516 break;
2517 }
2518 finish_braces ();
2519 sync_m68k_pc ();
2520}
2521
2522static void generate_includes(FILE * f)
2523{
2524//JLH:no fprintf(f, "#include \"sysdeps.h\"\n");
2525//JLH:no fprintf(f, "#include \"hatari-glue.h\"\n");
2526//JLH:no fprintf(f, "#include \"maccess.h\"\n");
2527//JLH:no fprintf(f, "#include \"memory.h\"\n");
2528//JLH:no fprintf(f, "#include \"newcpu.h\"\n");
2529 fprintf(f, "#include \"cpudefs.h\"\n");
2530 fprintf(f, "#include \"cpuextra.h\"\n");
2531 fprintf(f, "#include \"inlines.h\"\n");
2532 fprintf(f, "#include \"cputbl.h\"\n");
2533 fprintf(f, "#define CPUFUNC(x) x##_ff\n"
2534 "#ifdef NOFLAGS\n"
2535 "#include \"noflags.h\"\n"
2536 "#endif\n");
2537}
2538
2539// JLH: Since this is stuff that should be generated in a file that creates
2540// constants, it's in here now. :-P
2541static void GenerateTables(FILE * f)
2542{
2543 int i, j;
2544
2545 fprintf(f, "\nconst int areg_byteinc[] = { 1, 1, 1, 1, 1, 1, 1, 2 };\n");
2546 fprintf(f, "const int imm8_table[] = { 8, 1, 2, 3, 4, 5, 6, 7 };\n\n");
2547 fprintf(f, "const int movem_index1[256] = {\n");
2548
2549 for(i=0; i<256; i++)
2550 {
2551 for(j=0; j<8; j++)
2552 if (i & (1 << j))
2553 break;
2554
2555 fprintf(f, "0x%02X, ", j);
2556
2557 if ((i % 16) == 15)
2558 fprintf(f, "\n");
2559 }
2560
2561 fprintf(f, "};\n\n");
2562 fprintf(f, "const int movem_index2[256] = {\n");
2563
2564 for(i=0; i<256; i++)
2565 {
2566 for(j=0; j<8; j++)
2567 if (i & (1 << j))
2568 break;
2569
2570 fprintf(f, "0x%02X, ", 7 - j);
2571
2572 if ((i % 16) == 15)
2573 fprintf(f, "\n");
2574 }
2575
2576 fprintf(f, "};\n\n");
2577 fprintf(f, "const int movem_next[256] = {\n");
2578
2579 for(i=0; i<256; i++)
2580 {
2581 for(j=0; j<8; j++)
2582 if (i & (1 << j))
2583 break;
2584
2585 fprintf(f, "0x%02X, ", i & (~(1 << j)));
2586
2587 if ((i % 16) == 15)
2588 fprintf(f, "\n");
2589 }
2590
2591 fprintf(f, "};\n\n");
2592}
2593
2594static int postfix;
2595
2596static void generate_one_opcode (int rp)
2597{
2598 int i;
2599 uint16_t smsk, dmsk;
2600 long int opcode = opcode_map[rp];
2601
2602 exactCpuCycles[0] = 0; /* Default: not used */
2603
2604 if (table68k[opcode].mnemo == i_ILLG
2605 || table68k[opcode].clev > cpu_level)
2606 return;
2607
2608 for (i = 0; lookuptab[i].name[0]; i++) {
2609 if (table68k[opcode].mnemo == lookuptab[i].mnemo)
2610 break;
2611 }
2612
2613 if (table68k[opcode].handler != -1)
2614 return;
2615
2616 if (opcode_next_clev[rp] != cpu_level) {
2617 fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp],
2618 opcode, lookuptab[i].name);
2619 return;
2620 }
2621 fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
2622 fprintf (headerfile, "extern cpuop_func op_%lx_%d_nf;\n", opcode, postfix);
2623 fprintf (headerfile, "extern cpuop_func op_%lx_%d_ff;\n", opcode, postfix);
2624 printf ("unsigned long CPUFUNC(op_%lx_%d)(uint32_t opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
2625
2626 switch (table68k[opcode].stype) {
2627 case 0: smsk = 7; break;
2628 case 1: smsk = 255; break;
2629 case 2: smsk = 15; break;
2630 case 3: smsk = 7; break;
2631 case 4: smsk = 7; break;
2632 case 5: smsk = 63; break;
2633 case 7: smsk = 3; break;
2634 default: abort ();
2635 }
2636 dmsk = 7;
2637
2638 next_cpu_level = -1;
2639 if (table68k[opcode].suse
2640 && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
2641 && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
2642 && table68k[opcode].smode != absw && table68k[opcode].smode != absl
2643 && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
2644 {
2645 if (table68k[opcode].spos == -1) {
2646 if (((int) table68k[opcode].sreg) >= 128)
2647 printf ("\tuint32_t srcreg = (int32_t)(int8_t)%d;\n", (int) table68k[opcode].sreg);
2648 else
2649 printf ("\tuint32_t srcreg = %d;\n", (int) table68k[opcode].sreg);
2650 } else {
2651 char source[100];
2652 int pos = table68k[opcode].spos;
2653
2654 if (pos)
2655 sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
2656 else
2657 sprintf (source, "(opcode & %d)", smsk);
2658
2659 if (table68k[opcode].stype == 3)
2660 printf ("\tuint32_t srcreg = imm8_table[%s];\n", source);
2661 else if (table68k[opcode].stype == 1)
2662 printf ("\tuint32_t srcreg = (int32_t)(int8_t)%s;\n", source);
2663 else
2664 printf ("\tuint32_t srcreg = %s;\n", source);
2665 }
2666 }
2667 if (table68k[opcode].duse
2668 /* Yes, the dmode can be imm, in case of LINK or DBcc */
2669 && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
2670 && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
2671 && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
2672 {
2673 if (table68k[opcode].dpos == -1) {
2674 if (((int) table68k[opcode].dreg) >= 128)
2675 printf ("\tuint32_t dstreg = (int32_t)(int8_t)%d;\n", (int) table68k[opcode].dreg);
2676 else
2677 printf ("\tuint32_t dstreg = %d;\n", (int) table68k[opcode].dreg);
2678 } else {
2679 int pos = table68k[opcode].dpos;
2680#if 0
2681 /* Check that we can do the little endian optimization safely. */
2682 if (pos < 8 && (dmsk >> (8 - pos)) != 0)
2683 abort ();
2684#endif
2685 if (pos)
2686 printf ("\tuint32_t dstreg = (opcode >> %d) & %d;\n",
2687 pos, dmsk);
2688 else
2689 printf ("\tuint32_t dstreg = opcode & %d;\n", dmsk);
2690 }
2691 }
2692 need_endlabel = 0;
2693 endlabelno++;
2694 sprintf (endlabelstr, "endlabel%d", endlabelno);
2695 if(table68k[opcode].mnemo==i_ASR || table68k[opcode].mnemo==i_ASL || table68k[opcode].mnemo==i_LSR || table68k[opcode].mnemo==i_LSL
2696 || table68k[opcode].mnemo==i_ROL || table68k[opcode].mnemo==i_ROR || table68k[opcode].mnemo==i_ROXL || table68k[opcode].mnemo==i_ROXR
2697 || table68k[opcode].mnemo==i_MVMEL || table68k[opcode].mnemo==i_MVMLE
2698 || table68k[opcode].mnemo==i_MULU || table68k[opcode].mnemo==i_MULS
2699 || table68k[opcode].mnemo==i_DIVU || table68k[opcode].mnemo==i_DIVS )
2700 printf("\tunsigned int retcycles = 0;\n");
2701 gen_opcode (opcode);
2702 if (need_endlabel)
2703 printf ("%s: ;\n", endlabelstr);
2704
2705 if (strlen(exactCpuCycles) > 0)
2706 printf("%s\n",exactCpuCycles);
2707 else
2708 printf ("return %d;\n", insn_n_cycles);
2709 /* Now patch in the instruction cycles at the beginning of the function: */
2710 fseek(stdout, nCurInstrCycPos, SEEK_SET);
2711 printf("%d;", insn_n_cycles);
2712 fseek(stdout, 0, SEEK_END);
2713
2714 printf ("}\n");
2715 opcode_next_clev[rp] = next_cpu_level;
2716 opcode_last_postfix[rp] = postfix;
2717}
2718
2719static void generate_func(void)
2720{
2721 int i, j, rp;
2722
2723 using_prefetch = 0;
2724 using_exception_3 = 0;
2725//JLH:
2726// for(i=0; i<6; i++)
2727//For some reason, this doesn't work properly. Seems something is making a bad
2728//assumption somewhere.
2729//and it's probably in opcode_next_clev[rp]...
2730 for(i=4; i<6; i++)
2731 {
2732 cpu_level = 4 - i;
2733
2734 //JLH
2735 for(rp=0; rp<nr_cpuop_funcs; rp++)
2736 opcode_next_clev[rp] = 0;
2737
2738 if (i == 5)
2739 {
2740 cpu_level = 0;
2741 using_prefetch = 1;
2742 using_exception_3 = 1;
2743
2744 for(rp=0; rp<nr_cpuop_funcs; rp++)
2745 opcode_next_clev[rp] = 0;
2746 }
2747
2748 postfix = i;
2749 fprintf(stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix);
2750
2751 /* sam: this is for people with low memory (eg. me :)) */
2752 printf("\n"
2753 "#if !defined(PART_1) && !defined(PART_2) && "
2754 "!defined(PART_3) && !defined(PART_4) && "
2755 "!defined(PART_5) && !defined(PART_6) && "
2756 "!defined(PART_7) && !defined(PART_8)"
2757 "\n"
2758 "#define PART_1 1\n"
2759 "#define PART_2 1\n"
2760 "#define PART_3 1\n"
2761 "#define PART_4 1\n"
2762 "#define PART_5 1\n"
2763 "#define PART_6 1\n"
2764 "#define PART_7 1\n"
2765 "#define PART_8 1\n"
2766 "#endif\n\n");
2767
2768 rp = 0;
2769
2770 for(j=1; j<=8; ++j)
2771 {
2772 int k = (j * nr_cpuop_funcs) / 8;
2773 printf("#ifdef PART_%d\n", j);
2774
2775 for(; rp<k; rp++)
2776 generate_one_opcode(rp);
2777
2778 printf ("#endif\n\n");
2779 }
2780
2781 fprintf(stblfile, "{ 0, 0, 0 }};\n");
2782 }
2783}
2784
2785int main(int argc, char ** argv)
2786{
2787 read_table68k();
2788 do_merges();
2789
2790 opcode_map = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
2791 opcode_last_postfix = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
2792 opcode_next_clev = (int *)malloc(sizeof(int) * nr_cpuop_funcs);
2793 counts = (unsigned long *)malloc(65536 * sizeof(unsigned long));
2794 read_counts();
2795
2796 /* It would be a lot nicer to put all in one file (we'd also get rid of
2797 * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
2798 * I don't dare to touch the 68k version. */
2799
2800 headerfile = fopen("cputbl.h", "wb");
2801 stblfile = fopen("cpustbl.c", "wb");
2802
2803 if (freopen("cpuemu.c", "wb", stdout) == NULL)
2804 {
2805 perror("cpuemu.c");
2806 return -1;
2807 }
2808
2809 generate_includes(stdout);
2810 generate_includes(stblfile);
2811
2812 GenerateTables(stdout);
2813
2814 generate_func();
2815
2816 free(table68k);
2817 return 0;
2818}