1 /*
2  *  compiler/gencomp.c - MC680x0 compilation generator
3  *
4  *  Based on work Copyright 1995, 1996 Bernd Schmidt
5  *  Changes for UAE-JIT Copyright 2000 Bernd Meyer
6  *
7  *  Adaptation for ARAnyM/ARM, copyright 2001-2014
8  *    Milan Jurik, Jens Heitmann
9  *
10  *  Adaptation for Basilisk II and improvements, copyright 2000-2005
11  *    Gwenole Beauchesne
12  *
13  *  Basilisk II (C) 1997-2005 Christian Bauer
14  *
15  *  This program is free software; you can redistribute it and/or modify
16  *  it under the terms of the GNU General Public License as published by
17  *  the Free Software Foundation; either version 2 of the License, or
18  *  (at your option) any later version.
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, write to the Free Software
27  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29 
30 #define CC_FOR_BUILD 1
31 #include "sysconfig.h"
32 
33 #include "sysdeps.h"
34 #include "readcpu.h"
35 
36 #undef NDEBUG
37 #include <assert.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <stdarg.h>
41 #include <string.h>
42 #include <ctype.h>
43 #undef abort
44 
45 #ifdef UAE
46 /*
47 #define DISABLE_I_OR_AND_EOR
48 #define DISABLE_I_SUB
49 #define DISABLE_I_SUBA
50 #define DISABLE_I_SUBX
51 #define DISABLE_I_ADD
52 #define DISABLE_I_ADDA
53 #define DISABLE_I_ADDX
54 #define DISABLE_I_NEG
55 #define DISABLE_I_NEGX
56 #define DISABLE_I_CLR
57 #define DISABLE_I_NOT
58 #define DISABLE_I_TST
59 #define DISABLE_I_BCHG_BCLR_BSET_BTST
60 #define DISABLE_I_CMPM_CMP
61 #define DISABLE_I_CMPA
62 #define DISABLE_I_MOVE
63 #define DISABLE_I_MOVEA
64 #define DISABLE_I_SWAP
65 #define DISABLE_I_EXG
66 #define DISABLE_I_EXT
67 #define DISABLE_I_MVEL
68 #define DISABLE_I_MVMLE
69 #define DISABLE_I_RTD
70 #define DISABLE_I_LINK
71 #define DISABLE_I_UNLK
72 #define DISABLE_I_RTS
73 #define DISABLE_I_JSR
74 #define DISABLE_I_JMP
75 #define DISABLE_I_BSR
76 #define DISABLE_I_BCC
77 #define DISABLE_I_LEA
78 #define DISABLE_I_PEA
79 #define DISABLE_I_DBCC
80 #define DISABLE_I_SCC
81 #define DISABLE_I_MULU
82 #define DISABLE_I_MULS
83 #define DISABLE_I_ASR
84 #define DISABLE_I_ASL
85 #define DISABLE_I_LSR
86 #define DISABLE_I_LSL
87 #define DISABLE_I_ROL
88 #define DISABLE_I_ROR
89 #define DISABLE_I_MULL
90 #define DISABLE_I_FPP
91 #define DISABLE_I_FBCC
92 #define DISABLE_I_FSCC
93 #define DISABLE_I_MOVE16
94 */
95 
96 #endif /* UAE */
97 
98 #ifdef UAE
99 #define JIT_PATH "jit/"
100 #ifdef FSUAE
101 #define GEN_PATH "gen/"
102 #else
103 #define GEN_PATH "jit/"
104 #endif
105 #define RETURN "return 0;"
106 #define RETTYPE "uae_u32"
107 #define NEXT_CPU_LEVEL 5
108 #else
109 #define JIT_PATH "compiler/"
110 #define GEN_PATH ""
111 #define RETURN "return;"
112 #define RETTYPE "void"
113 #define NEXT_CPU_LEVEL 4
114 #endif
115 
116 #define BOOL_TYPE		"int"
117 #define failure			global_failure=1
118 #define FAILURE			global_failure=1
119 #define isjump			global_isjump=1
120 #define is_const_jump	global_iscjump=1
121 #define isaddx			global_isaddx=1
122 #define uses_cmov		global_cmov=1
123 #define mayfail			global_mayfail=1
124 #define uses_fpu		global_fpu=1
125 
126 int hack_opcode;
127 
128 static int global_failure;
129 static int global_isjump;
130 static int global_iscjump;
131 static int global_isaddx;
132 static int global_cmov;
133 static int long_opcode;
134 static int global_mayfail;
135 static int global_fpu;
136 
137 static char endstr[1000];
138 static char lines[100000];
139 static int comp_index=0;
140 
141 #include "flags_x86.h"
142 
143 #ifndef __attribute__
144 #  ifndef __GNUC__
145 #    define __attribute__(x)
146 #  endif
147 #endif
148 
149 
150 static int cond_codes[]={-1,-1,
151 		NATIVE_CC_HI,NATIVE_CC_LS,
152 		NATIVE_CC_CC,NATIVE_CC_CS,
153 		NATIVE_CC_NE,NATIVE_CC_EQ,
154 		-1,-1,
155 		NATIVE_CC_PL,NATIVE_CC_MI,
156 		NATIVE_CC_GE,NATIVE_CC_LT,
157 		NATIVE_CC_GT,NATIVE_CC_LE
158 		};
159 
160 __attribute__((format(printf, 1, 2)))
comprintf(const char * format,...)161 static void comprintf(const char *format, ...)
162 {
163 	va_list args;
164 
165 	va_start(args, format);
166 	comp_index += vsprintf(lines + comp_index, format, args);
167 	va_end(args);
168 }
169 
com_discard(void)170 static void com_discard(void)
171 {
172 	comp_index = 0;
173 }
174 
com_flush(void)175 static void com_flush(void)
176 {
177 	int i;
178 	for (i = 0; i < comp_index; i++)
179 		putchar(lines[i]);
180 	com_discard();
181 }
182 
183 
184 static FILE *headerfile;
185 static FILE *stblfile;
186 
187 static int using_prefetch;
188 static int using_exception_3;
189 static int cpu_level;
190 static int noflags;
191 
192 /* For the current opcode, the next lower level that will have different code.
193  * Initialized to -1 for each opcode. If it remains unchanged, indicates we
194  * are done with that opcode.  */
195 static int next_cpu_level;
196 
197 static int *opcode_map;
198 static int *opcode_next_clev;
199 static int *opcode_last_postfix;
200 static unsigned long *counts;
201 
read_counts(void)202 static void read_counts(void)
203 {
204     FILE *file;
205     unsigned long opcode, count, total;
206     char name[20];
207     int nr = 0;
208     memset (counts, 0, 65536 * sizeof *counts);
209 
210     file = fopen ("frequent.68k", "r");
211     if (file)
212     {
213 	if (fscanf (file, "Total: %lu\n", &total) != 1) {
214 		assert(0);
215 	}
216 	while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3)
217 	{
218 	    opcode_next_clev[nr] = NEXT_CPU_LEVEL;
219 	    opcode_last_postfix[nr] = -1;
220 	    opcode_map[nr++] = opcode;
221 	    counts[opcode] = count;
222 	}
223 	fclose (file);
224     }
225     if (nr == nr_cpuop_funcs)
226 	return;
227     for (opcode = 0; opcode < 0x10000; opcode++)
228     {
229 	if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
230 	    && counts[opcode] == 0)
231 	{
232 	    opcode_next_clev[nr] = NEXT_CPU_LEVEL;
233 	    opcode_last_postfix[nr] = -1;
234 	    opcode_map[nr++] = opcode;
235 	    counts[opcode] = count;
236 	}
237     }
238     assert (nr == nr_cpuop_funcs);
239 }
240 
241 static int n_braces = 0;
242 static int insn_n_cycles;
243 
244 static void
start_brace(void)245 start_brace (void)
246 {
247     n_braces++;
248     comprintf ("{");
249 }
250 
251 static void
close_brace(void)252 close_brace (void)
253 {
254     assert (n_braces > 0);
255     n_braces--;
256     comprintf ("}");
257 }
258 
259 static void
finish_braces(void)260 finish_braces (void)
261 {
262     while (n_braces > 0)
263 	close_brace ();
264 }
265 
gen_update_next_handler(void)266 static inline void gen_update_next_handler(void)
267 {
268     return; /* Can anything clever be done here? */
269 }
270 
gen_writebyte(const char * address,const char * source)271 static void gen_writebyte(const char *address, const char *source)
272 {
273 	comprintf("\twritebyte(%s, %s, scratchie);\n", address, source);
274 }
275 
gen_writeword(const char * address,const char * source)276 static void gen_writeword(const char *address, const char *source)
277 {
278 	comprintf("\twriteword(%s, %s, scratchie);\n", address, source);
279 }
280 
gen_writelong(const char * address,const char * source)281 static void gen_writelong(const char *address, const char *source)
282 {
283 	comprintf("\twritelong(%s, %s, scratchie);\n", address, source);
284 }
285 
gen_readbyte(const char * address,const char * dest)286 static void gen_readbyte(const char *address, const char* dest)
287 {
288 	comprintf("\treadbyte(%s, %s, scratchie);\n", address, dest);
289 }
290 
gen_readword(const char * address,const char * dest)291 static void gen_readword(const char *address, const char *dest)
292 {
293 	comprintf("\treadword(%s,%s,scratchie);\n", address, dest);
294 }
295 
gen_readlong(const char * address,const char * dest)296 static void gen_readlong(const char *address, const char *dest)
297 {
298 	comprintf("\treadlong(%s, %s, scratchie);\n", address, dest);
299 }
300 
301 
302 
303 static const char *
gen_nextilong(void)304 gen_nextilong (void)
305 {
306     static char buffer[80];
307 
308     sprintf (buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)");
309     insn_n_cycles += 4;
310 
311     long_opcode=1;
312     return buffer;
313 }
314 
315 static const char *
gen_nextiword(void)316 gen_nextiword (void)
317 {
318     static char buffer[80];
319 
320     sprintf (buffer, "comp_get_iword((m68k_pc_offset+=2)-2)");
321     insn_n_cycles+=2;
322 
323     long_opcode=1;
324     return buffer;
325 }
326 
327 static const char *
gen_nextibyte(void)328 gen_nextibyte (void)
329 {
330     static char buffer[80];
331 
332     sprintf (buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)");
333     insn_n_cycles += 2;
334 
335     long_opcode=1;
336     return buffer;
337 }
338 
339 
340 static void
swap_opcode(void)341 swap_opcode (void)
342 {
343 #ifdef UAE
344 	/* no-op */
345 #else
346 	comprintf("#ifdef USE_JIT_FPU\n");
347 	comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n");
348 	comprintf("\topcode = do_byteswap_16(opcode);\n");
349 	comprintf("#endif\n");
350 	comprintf("#endif\n");
351 #endif
352 }
353 
354 static void
sync_m68k_pc(void)355 sync_m68k_pc (void)
356 {
357 	comprintf("\t if (m68k_pc_offset > SYNC_PC_OFFSET) sync_m68k_pc();\n");
358 }
359 
360 
361 /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
362  * the calling routine handles Apdi and Aipi modes.
363  * gb-- movem == 2 means the same thing but for a MOVE16 instruction */
genamode(amodes mode,const char * reg,wordsizes size,const char * name,int getv,int movem)364 static void genamode(amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem)
365 {
366 	start_brace();
367 	switch (mode)
368 	{
369 	case Dreg: /* Do we need to check dodgy here? */
370 		assert (!movem);
371 		if (getv == 1 || getv == 2)
372 		{
373 			/* We generate the variable even for getv==2, so we can use
374 			 it as a destination for MOVE */
375 			comprintf("\tint %s = %s;\n", name, reg);
376 		}
377 		return;
378 
379 	case Areg:
380 		assert (!movem);
381 		if (getv == 1 || getv == 2)
382 		{
383 			/* see above */
384 			comprintf("\tint %s = dodgy ? scratchie++ : %s + 8;\n", name, reg);
385 			if (getv == 1)
386 			{
387 				comprintf("\tif (dodgy) \n");
388 				comprintf("\t\tmov_l_rr(%s, %s + 8);\n", name, reg);
389 			}
390 		}
391 		return;
392 
393 	case Aind:
394 		comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
395 		comprintf("\tif (dodgy)\n");
396 		comprintf("\t\tmov_l_rr(%sa, %s + 8);\n", name, reg);
397 		break;
398 	case Aipi:
399 		comprintf("\tint %sa = scratchie++;\n", name);
400 		comprintf("\tmov_l_rr(%sa, %s + 8);\n", name, reg);
401 		break;
402 	case Apdi:
403 		switch (size)
404 		{
405 		case sz_byte:
406 			if (movem)
407 			{
408 				comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
409 				comprintf("\tif (dodgy)\n");
410 				comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
411 			} else
412 			{
413 				start_brace();
414 				comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
415 				comprintf("\tlea_l_brr(%s + 8, %s + 8, (uae_s32)-areg_byteinc[%s]);\n", reg, reg, reg);
416 				comprintf("\tif (dodgy)\n");
417 				comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
418 			}
419 			break;
420 		case sz_word:
421 			if (movem)
422 			{
423 				comprintf("\tint %sa=dodgy?scratchie++:%s+8;\n", name, reg);
424 				comprintf("\tif (dodgy) \n");
425 				comprintf("\tmov_l_rr(%sa,8+%s);\n", name, reg);
426 			} else
427 			{
428 				start_brace();
429 				comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
430 				comprintf("\tlea_l_brr(%s + 8, %s + 8, -2);\n", reg, reg);
431 				comprintf("\tif (dodgy)\n");
432 				comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
433 			}
434 			break;
435 		case sz_long:
436 			if (movem)
437 			{
438 				comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
439 				comprintf("\tif (dodgy)\n");
440 				comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
441 			} else
442 			{
443 				start_brace();
444 				comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg);
445 				comprintf("\tlea_l_brr(%s + 8, %s + 8, -4);\n", reg, reg);
446 				comprintf("\tif (dodgy)\n");
447 				comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
448 			}
449 			break;
450 		default:
451 			assert(0);
452 			break;
453 		}
454 		break;
455 	case Ad16:
456 		comprintf("\tint %sa = scratchie++;\n", name);
457 		comprintf("\tmov_l_rr(%sa, 8 + %s);\n", name, reg);
458 		comprintf("\tlea_l_brr(%sa, %sa, (uae_s32)(uae_s16)%s);\n", name, name, gen_nextiword());
459 		break;
460 	case Ad8r:
461 		comprintf("\tint %sa = scratchie++;\n", name);
462 		comprintf("\tcalc_disp_ea_020(%s + 8, %s, %sa, scratchie);\n", reg, gen_nextiword(), name);
463 		break;
464 
465 	case PC16:
466 		comprintf("\tint %sa = scratchie++;\n", name);
467 		comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n");
468 		comprintf("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword());
469 		comprintf("\tmov_l_ri(%sa, address + PC16off);\n", name);
470 		break;
471 
472 	case PC8r:
473 		comprintf("\tint pctmp = scratchie++;\n");
474 		comprintf("\tint %sa = scratchie++;\n", name);
475 		comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n");
476 		start_brace();
477 		comprintf("\tmov_l_ri(pctmp,address);\n");
478 
479 		comprintf("\tcalc_disp_ea_020(pctmp, %s, %sa, scratchie);\n", gen_nextiword(), name);
480 		break;
481 	case absw:
482 		comprintf("\tint %sa = scratchie++;\n", name);
483 		comprintf("\tmov_l_ri(%sa, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword());
484 		break;
485 	case absl:
486 		comprintf("\tint %sa = scratchie++;\n", name);
487 		comprintf("\tmov_l_ri(%sa, %s); /* absl */\n", name, gen_nextilong());
488 		break;
489 	case imm:
490 		assert (getv == 1);
491 		switch (size)
492 		{
493 		case sz_byte:
494 			comprintf("\tint %s = scratchie++;\n", name);
495 			comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte());
496 			break;
497 		case sz_word:
498 			comprintf("\tint %s = scratchie++;\n", name);
499 			comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword());
500 			break;
501 		case sz_long:
502 			comprintf("\tint %s = scratchie++;\n", name);
503 			comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong());
504 			break;
505 		default:
506 			assert(0);
507 			break;
508 		}
509 		return;
510 	case imm0:
511 		assert (getv == 1);
512 		comprintf("\tint %s = scratchie++;\n", name);
513 		comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte());
514 		return;
515 	case imm1:
516 		assert (getv == 1);
517 		comprintf("\tint %s = scratchie++;\n", name);
518 		comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword());
519 		return;
520 	case imm2:
521 		assert (getv == 1);
522 		comprintf("\tint %s = scratchie++;\n", name);
523 		comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong());
524 		return;
525 	case immi:
526 		assert (getv == 1);
527 		comprintf("\tint %s = scratchie++;\n", name);
528 		comprintf("\tmov_l_ri(%s, %s);\n", name, reg);
529 		return;
530 	default:
531 		assert(0);
532 		break;
533 	}
534 
535 	/* We get here for all non-reg non-immediate addressing modes to
536 	 * actually fetch the value. */
537 	if (getv == 1)
538 	{
539 		char astring[80];
540 		sprintf(astring, "%sa", name);
541 		switch (size)
542 		{
543 		case sz_byte:
544 			insn_n_cycles += 2;
545 			break;
546 		case sz_word:
547 			insn_n_cycles += 2;
548 			break;
549 		case sz_long:
550 			insn_n_cycles += 4;
551 			break;
552 		default:
553 			assert(0);
554 			break;
555 		}
556 		start_brace();
557 		comprintf("\tint %s = scratchie++;\n", name);
558 		switch (size)
559 		{
560 		case sz_byte:
561 			gen_readbyte(astring, name);
562 			break;
563 		case sz_word:
564 			gen_readword(astring, name);
565 			break;
566 		case sz_long:
567 			gen_readlong(astring, name);
568 			break;
569 		default:
570 			assert(0);
571 			break;
572 		}
573 	}
574 
575 	/* We now might have to fix up the register for pre-dec or post-inc
576 	 * addressing modes. */
577 	if (!movem)
578 	{
579 		switch (mode)
580 		{
581 		case Aipi:
582 			switch (size)
583 			{
584 			case sz_byte:
585 				comprintf("\tlea_l_brr(%s + 8,%s + 8, areg_byteinc[%s]);\n", reg, reg, reg);
586 				break;
587 			case sz_word:
588 				comprintf("\tlea_l_brr(%s + 8, %s + 8, 2);\n", reg, reg);
589 				break;
590 			case sz_long:
591 				comprintf("\tlea_l_brr(%s + 8, %s + 8, 4);\n", reg, reg);
592 				break;
593 			default:
594 				assert(0);
595 				break;
596 			}
597 			break;
598 		case Apdi:
599 			break;
600 		default:
601 			break;
602 		}
603 	}
604 }
605 
genastore(const char * from,amodes mode,const char * reg,wordsizes size,const char * to)606 static void genastore(const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
607 {
608 	switch (mode)
609 	{
610 	case Dreg:
611 		switch (size)
612 		{
613 		case sz_byte:
614 			comprintf("\tif(%s != %s)\n", reg, from);
615 			comprintf("\t\tmov_b_rr(%s, %s);\n", reg, from);
616 			break;
617 		case sz_word:
618 			comprintf("\tif(%s != %s)\n", reg, from);
619 			comprintf("\t\tmov_w_rr(%s, %s);\n", reg, from);
620 			break;
621 		case sz_long:
622 			comprintf("\tif(%s != %s)\n", reg, from);
623 			comprintf("\t\tmov_l_rr(%s, %s);\n", reg, from);
624 			break;
625 		default:
626 			assert(0);
627 			break;
628 		}
629 		break;
630 	case Areg:
631 		switch (size)
632 		{
633 		case sz_word:
634 			comprintf("\tif(%s + 8 != %s)\n", reg, from);
635 			comprintf("\t\tmov_w_rr(%s + 8, %s);\n", reg, from);
636 			break;
637 		case sz_long:
638 			comprintf("\tif(%s + 8 != %s)\n", reg, from);
639 			comprintf("\t\tmov_l_rr(%s + 8, %s);\n", reg, from);
640 			break;
641 		default:
642 			assert(0);
643 			break;
644 		}
645 		break;
646 
647 	case Apdi:
648 	case absw:
649 	case PC16:
650 	case PC8r:
651 	case Ad16:
652 	case Ad8r:
653 	case Aipi:
654 	case Aind:
655 	case absl:
656 	{
657 		char astring[80];
658 		sprintf(astring, "%sa", to);
659 
660 		switch (size)
661 		{
662 		case sz_byte:
663 			insn_n_cycles += 2;
664 			gen_writebyte(astring, from);
665 			break;
666 		case sz_word:
667 			insn_n_cycles += 2;
668 			gen_writeword(astring, from);
669 			break;
670 		case sz_long:
671 			insn_n_cycles += 4;
672 			gen_writelong(astring, from);
673 			break;
674 		default:
675 			assert(0);
676 			break;
677 		}
678 	}
679 		break;
680 	case imm:
681 	case imm0:
682 	case imm1:
683 	case imm2:
684 	case immi:
685 		assert(0);
686 		break;
687 	default:
688 		assert(0);
689 		break;
690 	}
691 }
692 
genmov16(uae_u32 opcode,struct instr * curi)693 static void genmov16(uae_u32 opcode, struct instr *curi)
694 {
695 	comprintf("\tint src=scratchie++;\n");
696 	comprintf("\tint dst=scratchie++;\n");
697 
698 	if ((opcode & 0xfff8) == 0xf620) {
699 		/* MOVE16 (Ax)+,(Ay)+ */
700 		comprintf("\tuae_u16 dstreg=((%s)>>12)&0x07;\n", gen_nextiword());
701 		comprintf("\tmov_l_rr(src,8+srcreg);\n");
702 		comprintf("\tmov_l_rr(dst,8+dstreg);\n");
703 	}
704 	else {
705 		/* Other variants */
706 		genamode (curi->smode, "srcreg", curi->size, "src", 0, 2);
707 		genamode (curi->dmode, "dstreg", curi->size, "dst", 0, 2);
708 		comprintf("\tmov_l_rr(src,srca);\n");
709 		comprintf("\tmov_l_rr(dst,dsta);\n");
710 	}
711 
712 	/* Align on 16-byte boundaries */
713 	comprintf("\tand_l_ri(src,~15);\n");
714 	comprintf("\tand_l_ri(dst,~15);\n");
715 
716 	if ((opcode & 0xfff8) == 0xf620) {
717 		comprintf("\tif (srcreg != dstreg)\n");
718 		comprintf("\tadd_l_ri(srcreg+8,16);\n");
719 		comprintf("\tadd_l_ri(dstreg+8,16);\n");
720 	}
721 	else if ((opcode & 0xfff8) == 0xf600)
722 		comprintf("\tadd_l_ri(srcreg+8,16);\n");
723 	else if ((opcode & 0xfff8) == 0xf608)
724 		comprintf("\tadd_l_ri(dstreg+8,16);\n");
725 
726 #ifdef UAE
727 	comprintf("\tif (special_mem) {\n");
728 	comprintf("\t\tint tmp=scratchie;\n");
729 	comprintf("\tscratchie+=4;\n"
730 		  "\treadlong(src,tmp,scratchie);\n"
731 		  "\twritelong_clobber(dst,tmp,scratchie);\n"
732 		  "\tadd_l_ri(src,4);\n"
733 		  "\tadd_l_ri(dst,4);\n"
734 		  "\treadlong(src,tmp,scratchie);\n"
735 		  "\twritelong_clobber(dst,tmp,scratchie);\n"
736 		  "\tadd_l_ri(src,4);\n"
737 		  "\tadd_l_ri(dst,4);\n"
738 		  "\treadlong(src,tmp,scratchie);\n"
739 		  "\twritelong_clobber(dst,tmp,scratchie);\n"
740 		  "\tadd_l_ri(src,4);\n"
741 		  "\tadd_l_ri(dst,4);\n"
742 		  "\treadlong(src,tmp,scratchie);\n"
743 		  "\twritelong_clobber(dst,tmp,scratchie);\n");
744 	comprintf("\t} else\n");
745 #endif
746 	start_brace();
747 	comprintf("\tint tmp=scratchie;\n");
748 	comprintf("\tscratchie+=4;\n"
749 		"\tget_n_addr(src,src,scratchie);\n"
750 		"\tget_n_addr(dst,dst,scratchie);\n"
751 		"\tmov_l_rR(tmp+0,src,0);\n"
752 		"\tmov_l_rR(tmp+1,src,4);\n"
753 		"\tmov_l_rR(tmp+2,src,8);\n"
754 		"\tmov_l_rR(tmp+3,src,12);\n"
755 		"\tmov_l_Rr(dst,tmp+0,0);\n"
756 		"\tforget_about(tmp+0);\n"
757 		"\tmov_l_Rr(dst,tmp+1,4);\n"
758 		"\tforget_about(tmp+1);\n"
759 		"\tmov_l_Rr(dst,tmp+2,8);\n"
760 		"\tforget_about(tmp+2);\n"
761 		"\tmov_l_Rr(dst,tmp+3,12);\n");
762 	close_brace();
763 }
764 
765 static void
genmovemel(uae_u16 opcode)766 genmovemel (uae_u16 opcode)
767 {
768     comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ());
769     comprintf ("\tint native=scratchie++;\n");
770     comprintf ("\tint i;\n");
771     comprintf ("\tsigned char offset=0;\n");
772     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
773 #ifdef UAE
774 	if (table68k[opcode].size == sz_long)
775 	    comprintf("\tif (1 && !special_mem) {\n");
776 	else
777 	    comprintf("\tif (1 && !special_mem) {\n");
778 #endif
779 
780     /* Fast but unsafe...  */
781     comprintf("\tget_n_addr(srca,native,scratchie);\n");
782 
783     comprintf("\tfor (i=0;i<16;i++) {\n"
784 	      "\t\tif ((mask>>i)&1) {\n");
785     switch(table68k[opcode].size) {
786      case sz_long:
787 	comprintf("\t\t\tmov_l_rR(i,native,offset);\n"
788 		  "\t\t\tmid_bswap_32(i);\n"
789 		  "\t\t\toffset+=4;\n");
790 	break;
791      case sz_word:
792 	comprintf("\t\t\tmov_w_rR(i,native,offset);\n"
793 		  "\t\t\tmid_bswap_16(i);\n"
794 		  "\t\t\tsign_extend_16_rr(i,i);\n"
795 		  "\t\t\toffset+=2;\n");
796 	break;
797      default: assert(0);
798     }
799     comprintf("\t\t}\n"
800 	      "\t}");
801     if (table68k[opcode].dmode == Aipi) {
802 	comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n");
803     }
804     /* End fast but unsafe.   */
805 
806 #ifdef UAE
807     comprintf("\t} else {\n");
808 
809     comprintf ("\t\tint tmp=scratchie++;\n");
810 
811     comprintf("\t\tmov_l_rr(tmp,srca);\n");
812     comprintf("\t\tfor (i=0;i<16;i++) {\n"
813 	      "\t\t\tif ((mask>>i)&1) {\n");
814     switch(table68k[opcode].size) {
815     case sz_long:
816 	comprintf("\t\t\t\treadlong(tmp,i,scratchie);\n"
817 		  "\t\t\t\tadd_l_ri(tmp,4);\n");
818 	break;
819     case sz_word:
820 	comprintf("\t\t\t\treadword(tmp,i,scratchie);\n"
821 		  "\t\t\t\tadd_l_ri(tmp,2);\n");
822 	break;
823     default: assert(0);
824     }
825 
826     comprintf("\t\t\t}\n"
827 	      "\t\t}\n");
828     if (table68k[opcode].dmode == Aipi) {
829 	comprintf("\t\tmov_l_rr(8+dstreg,tmp);\n");
830     }
831     comprintf("\t}\n");
832 #endif
833 
834 }
835 
836 
837 static void
genmovemle(uae_u16 opcode)838 genmovemle (uae_u16 opcode)
839 {
840     comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ());
841     comprintf ("\tint native=scratchie++;\n");
842     comprintf ("\tint i;\n");
843     comprintf ("\tint tmp=scratchie++;\n");
844     comprintf ("\tsigned char offset=0;\n");
845     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
846 
847 #ifdef UAE
848     /* *Sigh* Some clever geek realized that the fastest way to copy a
849        buffer from main memory to the gfx card is by using movmle. Good
850        on her, but unfortunately, gfx mem isn't "real" mem, and thus that
851        act of cleverness means that movmle must pay attention to special_mem,
852        or Genetic Species is a rather boring-looking game ;-) */
853 	if (table68k[opcode].size == sz_long)
854 	    comprintf("\tif (1 && !special_mem) {\n");
855 	else
856 	    comprintf("\tif (1 && !special_mem) {\n");
857 #endif
858     comprintf("\tget_n_addr(srca,native,scratchie);\n");
859 
860     if (table68k[opcode].dmode!=Apdi) {
861 	comprintf("\tfor (i=0;i<16;i++) {\n"
862 		  "\t\tif ((mask>>i)&1) {\n");
863 	switch(table68k[opcode].size) {
864 	 case sz_long:
865 	    comprintf("\t\t\tmov_l_rr(tmp,i);\n"
866 		      "\t\t\tmid_bswap_32(tmp);\n"
867 		      "\t\t\tmov_l_Rr(native,tmp,offset);\n"
868 		      "\t\t\toffset+=4;\n");
869 	    break;
870 	 case sz_word:
871 	    comprintf("\t\t\tmov_l_rr(tmp,i);\n"
872 		      "\t\t\tmid_bswap_16(tmp);\n"
873 		      "\t\t\tmov_w_Rr(native,tmp,offset);\n"
874 		      "\t\t\toffset+=2;\n");
875 	    break;
876 	 default: assert(0);
877 	}
878     }
879     else {  /* Pre-decrement */
880 	comprintf("\tfor (i=0;i<16;i++) {\n"
881 		  "\t\tif ((mask>>i)&1) {\n");
882 	switch(table68k[opcode].size) {
883 	 case sz_long:
884 	    comprintf("\t\t\toffset-=4;\n"
885 		      "\t\t\tmov_l_rr(tmp,15-i);\n"
886 		      "\t\t\tmid_bswap_32(tmp);\n"
887 		      "\t\t\tmov_l_Rr(native,tmp,offset);\n"
888 		      );
889 	    break;
890 	 case sz_word:
891 	    comprintf("\t\t\toffset-=2;\n"
892 		      "\t\t\tmov_l_rr(tmp,15-i);\n"
893 		      "\t\t\tmid_bswap_16(tmp);\n"
894 		      "\t\t\tmov_w_Rr(native,tmp,offset);\n"
895 		      );
896 	    break;
897 	 default: assert(0);
898 	}
899     }
900 
901 
902     comprintf("\t\t}\n"
903 	      "\t}");
904     if (table68k[opcode].dmode == Apdi) {
905 	comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n");
906     }
907 #ifdef UAE
908     comprintf("\t} else {\n");
909 
910     if (table68k[opcode].dmode!=Apdi) {
911 	comprintf("\tmov_l_rr(tmp,srca);\n");
912 	comprintf("\tfor (i=0;i<16;i++) {\n"
913 		  "\t\tif ((mask>>i)&1) {\n");
914 	switch(table68k[opcode].size) {
915 	 case sz_long:
916 	    comprintf("\t\t\twritelong(tmp,i,scratchie);\n"
917 		      "\t\t\tadd_l_ri(tmp,4);\n");
918 	    break;
919 	 case sz_word:
920 	    comprintf("\t\t\twriteword(tmp,i,scratchie);\n"
921 		      "\t\t\tadd_l_ri(tmp,2);\n");
922 	    break;
923 	 default: assert(0);
924 	}
925     }
926     else {  /* Pre-decrement */
927 	comprintf("\tfor (i=0;i<16;i++) {\n"
928 		  "\t\tif ((mask>>i)&1) {\n");
929 	switch(table68k[opcode].size) {
930 	 case sz_long:
931 	    comprintf("\t\t\tsub_l_ri(srca,4);\n"
932 		      "\t\t\twritelong(srca,15-i,scratchie);\n");
933 	    break;
934 	 case sz_word:
935 	    comprintf("\t\t\tsub_l_ri(srca,2);\n"
936 		      "\t\t\twriteword(srca,15-i,scratchie);\n");
937 	    break;
938 	 default: assert(0);
939 	}
940     }
941 
942 
943     comprintf("\t\t}\n"
944 	      "\t}");
945     if (table68k[opcode].dmode == Apdi) {
946 	comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n");
947     }
948     comprintf("\t}\n");
949 #endif
950 }
951 
952 
953 static void
duplicate_carry(void)954 duplicate_carry (void)
955 {
956     comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n");
957 }
958 
959 typedef enum
960 {
961     flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp,
962     flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or,
963     flag_eor, flag_mov
964 }
965 flagtypes;
966 
967 
968 static void
genflags(flagtypes type,wordsizes size,const char * value,const char * src,const char * dst)969 genflags (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
970 {
971     if (noflags) {
972 	switch(type) {
973 	 case flag_cmp:
974 	    comprintf("\tdont_care_flags();\n");
975 	    comprintf("/* Weird --- CMP with noflags ;-) */\n");
976 	    return;
977 	 case flag_add:
978 	 case flag_sub:
979 	    comprintf("\tdont_care_flags();\n");
980 	    {
981 		const char* op;
982 		switch(type) {
983 		 case flag_add: op="add"; break;
984 		 case flag_sub: op="sub"; break;
985 		 default: assert(0);
986 		}
987 		switch (size)
988 		{
989 		 case sz_byte:
990 		    comprintf("\t%s_b(%s,%s);\n",op,dst,src);
991 		    break;
992 		 case sz_word:
993 		    comprintf("\t%s_w(%s,%s);\n",op,dst,src);
994 		    break;
995 		 case sz_long:
996 		    comprintf("\t%s_l(%s,%s);\n",op,dst,src);
997 		    break;
998 		}
999 		return;
1000 	    }
1001 	    break;
1002 
1003 	 case flag_and:
1004 	    comprintf("\tdont_care_flags();\n");
1005 	    switch (size)
1006 	    {
1007 	     case sz_byte:
1008 		comprintf("if (kill_rodent(dst)) {\n");
1009 		comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
1010 		comprintf("\tor_l_ri(scratchie,0xffffff00);\n");
1011 		comprintf("\tand_l(%s,scratchie);\n",dst);
1012 		comprintf("\tforget_about(scratchie);\n");
1013 		comprintf("\t} else \n"
1014 			  "\tand_b(%s,%s);\n",dst,src);
1015 		break;
1016 	     case sz_word:
1017 		comprintf("if (kill_rodent(dst)) {\n");
1018 		comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
1019 		comprintf("\tor_l_ri(scratchie,0xffff0000);\n");
1020 		comprintf("\tand_l(%s,scratchie);\n",dst);
1021 		comprintf("\tforget_about(scratchie);\n");
1022 		comprintf("\t} else \n"
1023 			  "\tand_w(%s,%s);\n",dst,src);
1024 		break;
1025 	     case sz_long:
1026 		comprintf("\tand_l(%s,%s);\n",dst,src);
1027 		break;
1028 	    }
1029 	    return;
1030 
1031 	 case flag_mov:
1032 	    comprintf("\tdont_care_flags();\n");
1033 	    switch (size)
1034 	    {
1035 	     case sz_byte:
1036 		comprintf("if (kill_rodent(dst)) {\n");
1037 		comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
1038 		comprintf("\tand_l_ri(%s,0xffffff00);\n",dst);
1039 		comprintf("\tor_l(%s,scratchie);\n",dst);
1040 		comprintf("\tforget_about(scratchie);\n");
1041 		comprintf("\t} else \n"
1042 			  "\tmov_b_rr(%s,%s);\n",dst,src);
1043 		break;
1044 	     case sz_word:
1045 		comprintf("if (kill_rodent(dst)) {\n");
1046 		comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
1047 		comprintf("\tand_l_ri(%s,0xffff0000);\n",dst);
1048 		comprintf("\tor_l(%s,scratchie);\n",dst);
1049 		comprintf("\tforget_about(scratchie);\n");
1050 		comprintf("\t} else \n"
1051 			  "\tmov_w_rr(%s,%s);\n",dst,src);
1052 		break;
1053 	     case sz_long:
1054 		comprintf("\tmov_l_rr(%s,%s);\n",dst,src);
1055 		break;
1056 	    }
1057 	    return;
1058 
1059 	 case flag_or:
1060 	 case flag_eor:
1061 	    comprintf("\tdont_care_flags();\n");
1062 	    start_brace();
1063 	    {
1064 		const char* op;
1065 		switch(type) {
1066 		 case flag_or:  op="or"; break;
1067 		 case flag_eor: op="xor"; break;
1068 		 default: assert(0);
1069 		}
1070 		switch (size)
1071 		{
1072 		 case sz_byte:
1073 		    comprintf("if (kill_rodent(dst)) {\n");
1074 		    comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
1075 		    comprintf("\t%s_l(%s,scratchie);\n",op,dst);
1076 		    comprintf("\tforget_about(scratchie);\n");
1077 		    comprintf("\t} else \n"
1078 			      "\t%s_b(%s,%s);\n",op,dst,src);
1079 		    break;
1080 		 case sz_word:
1081 		    comprintf("if (kill_rodent(dst)) {\n");
1082 		    comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
1083 		    comprintf("\t%s_l(%s,scratchie);\n",op,dst);
1084 		    comprintf("\tforget_about(scratchie);\n");
1085 		    comprintf("\t} else \n"
1086 			      "\t%s_w(%s,%s);\n",op,dst,src);
1087 		    break;
1088 		 case sz_long:
1089 		    comprintf("\t%s_l(%s,%s);\n",op,dst,src);
1090 		    break;
1091 		}
1092 		close_brace();
1093 		return;
1094 	    }
1095 
1096 
1097 	 case flag_addx:
1098 	 case flag_subx:
1099 	    comprintf("\tdont_care_flags();\n");
1100 	    {
1101 		const char* op;
1102 		switch(type) {
1103 		 case flag_addx: op="adc"; break;
1104 		 case flag_subx: op="sbb"; break;
1105 		 default: assert(0);
1106 		}
1107 		comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
1108 		switch (size)
1109 		{
1110 		 case sz_byte:
1111 		    comprintf("\t%s_b(%s,%s);\n",op,dst,src);
1112 		    break;
1113 		 case sz_word:
1114 		    comprintf("\t%s_w(%s,%s);\n",op,dst,src);
1115 		    break;
1116 		 case sz_long:
1117 		    comprintf("\t%s_l(%s,%s);\n",op,dst,src);
1118 		    break;
1119 		}
1120 		return;
1121 	    }
1122 	    break;
1123 	 default: return;
1124 	}
1125     }
1126 
1127     /* Need the flags, but possibly not all of them */
1128     switch (type)
1129     {
1130      case flag_logical_noclobber:
1131 	failure;
1132 	/* fall through */
1133 
1134      case flag_and:
1135      case flag_or:
1136      case flag_eor:
1137 	comprintf("\tdont_care_flags();\n");
1138 	start_brace();
1139 	{
1140 	    const char* op;
1141 	    switch(type) {
1142 	     case flag_and: op="and"; break;
1143 	     case flag_or:  op="or"; break;
1144 	     case flag_eor: op="xor"; break;
1145 	     default: assert(0);
1146 	    }
1147 	    switch (size)
1148 	    {
1149 	     case sz_byte:
1150 		comprintf("\tstart_needflags();\n"
1151 			  "\t%s_b(%s,%s);\n",op,dst,src);
1152 		break;
1153 	     case sz_word:
1154 		comprintf("\tstart_needflags();\n"
1155 			  "\t%s_w(%s,%s);\n",op,dst,src);
1156 		break;
1157 	     case sz_long:
1158 		comprintf("\tstart_needflags();\n"
1159 			  "\t%s_l(%s,%s);\n",op,dst,src);
1160 		break;
1161 	    }
1162 	    comprintf("\tlive_flags();\n");
1163 	    comprintf("\tend_needflags();\n");
1164 	    close_brace();
1165 	    return;
1166 	}
1167 
1168      case flag_mov:
1169 	comprintf("\tdont_care_flags();\n");
1170 	start_brace();
1171 	{
1172 	    switch (size)
1173 	    {
1174 	     case sz_byte:
1175 		comprintf("\tif (%s!=%s) {\n",src,dst);
1176 		comprintf("\tmov_b_ri(%s,0);\n"
1177 			  "\tstart_needflags();\n",dst);
1178 		comprintf("\tor_b(%s,%s);\n",dst,src);
1179 		comprintf("\t} else {\n");
1180 		comprintf("\tmov_b_rr(%s,%s);\n",dst,src);
1181 		comprintf("\ttest_b_rr(%s,%s);\n",dst,dst);
1182 		comprintf("\t}\n");
1183 		break;
1184 	     case sz_word:
1185 		comprintf("\tif (%s!=%s) {\n",src,dst);
1186 		comprintf("\tmov_w_ri(%s,0);\n"
1187 			  "\tstart_needflags();\n",dst);
1188 		comprintf("\tor_w(%s,%s);\n",dst,src);
1189 		comprintf("\t} else {\n");
1190 		comprintf("\tmov_w_rr(%s,%s);\n",dst,src);
1191 		comprintf("\ttest_w_rr(%s,%s);\n",dst,dst);
1192 		comprintf("\t}\n");
1193 		break;
1194 	     case sz_long:
1195 		comprintf("\tif (%s!=%s) {\n",src,dst);
1196 		comprintf("\tmov_l_ri(%s,0);\n"
1197 			  "\tstart_needflags();\n",dst);
1198 		comprintf("\tor_l(%s,%s);\n",dst,src);
1199 		comprintf("\t} else {\n");
1200 		comprintf("\tmov_l_rr(%s,%s);\n",dst,src);
1201 		comprintf("\ttest_l_rr(%s,%s);\n",dst,dst);
1202 		comprintf("\t}\n");
1203 		break;
1204 	    }
1205 	    comprintf("\tlive_flags();\n");
1206 	    comprintf("\tend_needflags();\n");
1207 	    close_brace();
1208 	    return;
1209 	}
1210 
1211      case flag_logical:
1212 	comprintf("\tdont_care_flags();\n");
1213 	start_brace();
1214 	switch (size)
1215 	{
1216 	 case sz_byte:
1217 	    comprintf("\tstart_needflags();\n"
1218 		      "\ttest_b_rr(%s,%s);\n",value,value);
1219 	    break;
1220 	 case sz_word:
1221 	    comprintf("\tstart_needflags();\n"
1222 		      "\ttest_w_rr(%s,%s);\n",value,value);
1223 	    break;
1224 	 case sz_long:
1225 	    comprintf("\tstart_needflags();\n"
1226 		      "\ttest_l_rr(%s,%s);\n",value,value);
1227 	    break;
1228 	}
1229 	comprintf("\tlive_flags();\n");
1230 	comprintf("\tend_needflags();\n");
1231 	close_brace();
1232 	return;
1233 
1234 
1235      case flag_add:
1236      case flag_sub:
1237      case flag_cmp:
1238 	comprintf("\tdont_care_flags();\n");
1239 	{
1240 	    const char* op;
1241 	    switch(type) {
1242 	     case flag_add: op="add"; break;
1243 	     case flag_sub: op="sub"; break;
1244 	     case flag_cmp: op="cmp"; break;
1245 	     default: assert(0);
1246 	    }
1247 	    switch (size)
1248 	    {
1249 	     case sz_byte:
1250 		comprintf("\tstart_needflags();\n"
1251 			  "\t%s_b(%s,%s);\n",op,dst,src);
1252 		break;
1253 	     case sz_word:
1254 		comprintf("\tstart_needflags();\n"
1255 			  "\t%s_w(%s,%s);\n",op,dst,src);
1256 		break;
1257 	     case sz_long:
1258 		comprintf("\tstart_needflags();\n"
1259 			  "\t%s_l(%s,%s);\n",op,dst,src);
1260 		break;
1261 	    }
1262 	    comprintf("\tlive_flags();\n");
1263 	    comprintf("\tend_needflags();\n");
1264 	    if (type!=flag_cmp) {
1265 		duplicate_carry();
1266 	    }
1267 	    comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
1268 
1269 	    return;
1270 	}
1271 
1272      case flag_addx:
1273      case flag_subx:
1274 		 uses_cmov;
1275 	comprintf("\tdont_care_flags();\n");
1276 	{
1277 	    const char* op;
1278 	    switch(type) {
1279 	     case flag_addx: op="adc"; break;
1280 	     case flag_subx: op="sbb"; break;
1281 	     default: assert(0);
1282 	    }
1283 	    start_brace();
1284 	    comprintf("\tint zero=scratchie++;\n"
1285 		      "\tint one=scratchie++;\n"
1286 		      "\tif (needed_flags&FLAG_Z) {\n"
1287 		      "\tmov_l_ri(zero,0);\n"
1288 		      "\tmov_l_ri(one,-1);\n"
1289 		      "\tmake_flags_live();\n"
1290 		      "\tcmov_l_rr(zero,one,%d);\n"
1291 		      "\t}\n",NATIVE_CC_NE);
1292 	    comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
1293 	    switch (size)
1294 	    {
1295 	     case sz_byte:
1296 		comprintf("\tstart_needflags();\n"
1297 			  "\t%s_b(%s,%s);\n",op,dst,src);
1298 		break;
1299 	     case sz_word:
1300 		comprintf("\tstart_needflags();\n"
1301 			  "\t%s_w(%s,%s);\n",op,dst,src);
1302 		break;
1303 	     case sz_long:
1304 		comprintf("\tstart_needflags();\n"
1305 			  "\t%s_l(%s,%s);\n",op,dst,src);
1306 		break;
1307 	    }
1308 	    comprintf("\tlive_flags();\n");
1309 	    comprintf("\tif (needed_flags&FLAG_Z) {\n");
1310 	    comprintf("\tcmov_l_rr(zero,one,%d);\n", NATIVE_CC_NE);
1311 	    comprintf("\tset_zero(zero, one);\n"); /* No longer need one */
1312 	    comprintf("\tlive_flags();\n");
1313 	    comprintf("\t}\n");
1314 	    comprintf("\tend_needflags();\n");
1315 	    duplicate_carry();
1316 	    comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
1317 	    return;
1318 	}
1319      default:
1320 	failure;
1321 	break;
1322     }
1323 }
1324 
1325 static int  /* returns zero for success, non-zero for failure */
gen_opcode(unsigned int opcode)1326 gen_opcode (unsigned int opcode)
1327 {
1328     struct instr *curi = table68k + opcode;
1329     const char* ssize=NULL;
1330 
1331     insn_n_cycles = 2;
1332     global_failure=0;
1333     long_opcode=0;
1334     global_isjump=0;
1335     global_iscjump=0;
1336     global_isaddx=0;
1337     global_cmov=0;
1338 	global_fpu=0;
1339     global_mayfail=0;
1340     hack_opcode=opcode;
1341     endstr[0]=0;
1342 
1343     start_brace ();
1344     comprintf("\tuae_u8 scratchie=S1;\n");
1345     switch (curi->plev)
1346     {
1347      case 0:			/* not privileged */
1348 	break;
1349      case 1:			/* unprivileged only on 68000 */
1350 	if (cpu_level == 0)
1351 	    break;
1352 	if (next_cpu_level < 0)
1353 	    next_cpu_level = 0;
1354 
1355 	/* fall through */
1356      case 2:			/* priviledged */
1357 	failure;   /* Easy ones first */
1358 	break;
1359      case 3:			/* privileged if size == word */
1360 	if (curi->size == sz_byte)
1361 	    break;
1362 	failure;
1363 	break;
1364     }
1365     switch (curi->size) {
1366      case sz_byte: ssize="b"; break;
1367      case sz_word: ssize="w"; break;
1368      case sz_long: ssize="l"; break;
1369      default: assert(0);
1370     }
1371     (void)ssize;
1372 
1373     switch (curi->mnemo)
1374     {
1375      case i_OR:
1376      case i_AND:
1377      case i_EOR:
1378 #ifdef DISABLE_I_OR_AND_EOR
1379     failure;
1380 #endif
1381 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1382 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1383 	switch(curi->mnemo) {
1384 	 case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break;
1385 	 case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break;
1386 	 case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break;
1387 	}
1388 	genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1389 	break;
1390 
1391      case i_ORSR:
1392      case i_EORSR:
1393 	failure;
1394 	isjump;
1395 	break;
1396 
1397      case i_ANDSR:
1398 	failure;
1399 	isjump;
1400 	break;
1401 
1402      case i_SUB:
1403 #ifdef DISABLE_I_SUB
1404     failure;
1405 #endif
1406 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1407 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1408 	genflags (flag_sub, curi->size, "", "src", "dst");
1409 	genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1410 	break;
1411 
1412      case i_SUBA:
1413 #ifdef DISABLE_I_SUBA
1414     failure;
1415 #endif
1416 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1417 	genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1418 	start_brace();
1419 	comprintf("\tint tmp=scratchie++;\n");
1420 	switch(curi->size) {
1421 	 case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
1422 	 case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
1423 	 case sz_long: comprintf("\ttmp=src;\n"); break;
1424 	 default: assert(0);
1425 	}
1426 	comprintf("\tsub_l(dst,tmp);\n");
1427 	genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1428 	break;
1429 
1430      case i_SUBX:
1431 #ifdef DISABLE_I_SUBX
1432     failure;
1433 #endif
1434 	isaddx;
1435 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1436 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1437 	genflags (flag_subx, curi->size, "", "src", "dst");
1438 	genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1439 	break;
1440 
1441      case i_SBCD:
1442 	failure;
1443 	/* I don't think so! */
1444 	break;
1445 
1446      case i_ADD:
1447 #ifdef DISABLE_I_ADD
1448     failure;
1449 #endif
1450 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1451 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1452 	genflags (flag_add, curi->size, "", "src", "dst");
1453 	genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1454 	break;
1455 
1456      case i_ADDA:
1457 #ifdef DISABLE_I_ADDA
1458 	failure;
1459 #endif
1460 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1461 	genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1462 	start_brace();
1463 	comprintf("\tint tmp=scratchie++;\n");
1464 	switch(curi->size) {
1465 	 case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
1466 	 case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
1467 	 case sz_long: comprintf("\ttmp=src;\n"); break;
1468 	 default: assert(0);
1469 	}
1470 	comprintf("\tadd_l(dst,tmp);\n");
1471 	genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1472 	break;
1473 
1474      case i_ADDX:
1475 #ifdef DISABLE_I_ADDX
1476     failure;
1477 #endif
1478 	isaddx;
1479 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1480 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1481 	start_brace();
1482 	genflags (flag_addx, curi->size, "", "src", "dst");
1483 	genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1484 	break;
1485 
1486      case i_ABCD:
1487 	failure;
1488 	/* No BCD maths for me.... */
1489 	break;
1490 
1491      case i_NEG:
1492 #ifdef DISABLE_I_NEG
1493     failure;
1494 #endif
1495 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1496 	start_brace ();
1497 	comprintf("\tint dst=scratchie++;\n");
1498 	comprintf("\tmov_l_ri(dst,0);\n");
1499 	genflags (flag_sub, curi->size, "", "src", "dst");
1500 	genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1501 	break;
1502 
1503      case i_NEGX:
1504 #ifdef DISABLE_I_NEGX
1505     failure;
1506 #endif
1507 	isaddx;
1508 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1509 	start_brace ();
1510 	comprintf("\tint dst=scratchie++;\n");
1511 	comprintf("\tmov_l_ri(dst,0);\n");
1512 	genflags (flag_subx, curi->size, "", "src", "dst");
1513 	genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1514 	break;
1515 
1516      case i_NBCD:
1517 	failure;
1518 	/* Nope! */
1519 	break;
1520 
1521      case i_CLR:
1522 #ifdef DISABLE_I_CLR
1523     failure;
1524 #endif
1525 	genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1526 	start_brace();
1527 	comprintf("\tint dst=scratchie++;\n");
1528 	comprintf("\tmov_l_ri(dst,0);\n");
1529 	genflags (flag_logical, curi->size, "dst", "", "");
1530 	genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1531 	break;
1532 
1533      case i_NOT:
1534 #ifdef DISABLE_I_NOT
1535     failure;
1536 #endif
1537 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1538 	start_brace ();
1539 	comprintf("\tint dst=scratchie++;\n");
1540 	comprintf("\tmov_l_ri(dst,0xffffffff);\n");
1541 	genflags (flag_eor, curi->size, "", "src", "dst");
1542 	genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1543 	break;
1544 
1545      case i_TST:
1546 #ifdef DISABLE_I_TST
1547     failure;
1548 #endif
1549 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1550 	genflags (flag_logical, curi->size, "src", "", "");
1551 	break;
1552      case i_BCHG:
1553      case i_BCLR:
1554      case i_BSET:
1555      case i_BTST:
1556 #ifdef DISABLE_I_BCHG_BCLR_BSET_BTST
1557     failure;
1558 #endif
1559 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1560 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1561 	start_brace();
1562 	comprintf("\tint s=scratchie++;\n"
1563 		  "\tint tmp=scratchie++;\n"
1564 		  "\tmov_l_rr(s,src);\n");
1565 	if (curi->size == sz_byte)
1566 	    comprintf("\tand_l_ri(s,7);\n");
1567 	else
1568 	    comprintf("\tand_l_ri(s,31);\n");
1569 
1570 	{
1571 	    const char* op;
1572 	    int need_write=1;
1573 
1574 	    switch(curi->mnemo) {
1575 	     case i_BCHG: op="btc"; break;
1576 	     case i_BCLR: op="btr"; break;
1577 	     case i_BSET: op="bts"; break;
1578 	     case i_BTST: op="bt"; need_write=0; break;
1579 	    default: op=""; assert(0);
1580 	    }
1581 	    comprintf("\t%s_l_rr(dst,s);\n"  /* Answer now in C */
1582 				  "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */
1583 				  "\tmake_flags_live();\n" /* Get the flags back */
1584 				  "\tdont_care_flags();\n",op);
1585 		if (!noflags) {
1586 		  comprintf("\tstart_needflags();\n"
1587 					"\tset_zero(s,tmp);\n"
1588 					"\tlive_flags();\n"
1589 					"\tend_needflags();\n");
1590 		}
1591 	    if (need_write)
1592 		genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1593 	}
1594 	break;
1595 
1596      case i_CMPM:
1597      case i_CMP:
1598 #ifdef DISABLE_I_CMPM_CMP
1599     failure;
1600 #endif
1601 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1602 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1603 	start_brace ();
1604 	genflags (flag_cmp, curi->size, "", "src", "dst");
1605 	break;
1606 
1607      case i_CMPA:
1608 #ifdef DISABLE_I_CMPA
1609     failure;
1610 #endif
1611 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1612 	genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1613 	start_brace();
1614 	comprintf("\tint tmps=scratchie++;\n");
1615 	switch(curi->size) {
1616 	 case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break;
1617 	 case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break;
1618 	 case sz_long: comprintf("tmps=src;\n"); break;
1619 	 default: assert(0);
1620 	}
1621 	genflags (flag_cmp, sz_long, "", "tmps", "dst");
1622 	break;
1623 	/* The next two are coded a little unconventional, but they are doing
1624 	 * weird things... */
1625 
1626      case i_MVPRM:
1627 	isjump;
1628 	failure;
1629 	break;
1630 
1631      case i_MVPMR:
1632 	isjump;
1633 	failure;
1634 	break;
1635 
1636      case i_MOVE:
1637 #ifdef DISABLE_I_MOVE
1638     failure;
1639 #endif
1640 	switch(curi->dmode) {
1641 	 case Dreg:
1642 	 case Areg:
1643 	    genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1644 	    genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1645 	    genflags (flag_mov, curi->size, "", "src", "dst");
1646 	    genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1647 	    break;
1648 	 default: /* It goes to memory, not a register */
1649 	    genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1650 	    genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1651 	    genflags (flag_logical, curi->size, "src", "", "");
1652 	    genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1653 	    break;
1654 	}
1655 	break;
1656 
1657      case i_MOVEA:
1658 #ifdef DISABLE_I_MOVEA
1659     failure;
1660 #endif
1661 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1662 	genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1663 
1664 	start_brace();
1665 	comprintf("\tint tmps=scratchie++;\n");
1666 	switch(curi->size) {
1667 	 case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break;
1668 	 case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break;
1669 	 default: assert(0);
1670 	}
1671 	genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1672 	break;
1673 
1674      case i_MVSR2:
1675 	isjump;
1676 	failure;
1677 	break;
1678 
1679      case i_MV2SR:
1680 	isjump;
1681 	failure;
1682 	break;
1683 
1684      case i_SWAP:
1685 #ifdef DISABLE_I_SWAP
1686     failure;
1687 #endif
1688 	genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1689 	comprintf("\tdont_care_flags();\n");
1690 	comprintf("\trol_l_ri(src,16);\n");
1691 	genflags (flag_logical, sz_long, "src", "", "");
1692 	genastore ("src", curi->smode, "srcreg", sz_long, "src");
1693 	break;
1694 
1695      case i_EXG:
1696 #ifdef DISABLE_I_EXG
1697     failure;
1698 #endif
1699 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1700 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1701 	start_brace();
1702 	comprintf("\tint tmp=scratchie++;\n"
1703 		  "\tmov_l_rr(tmp,src);\n");
1704 	genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1705 	genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst");
1706 	break;
1707 
1708 	 case i_EXT:
1709 #ifdef DISABLE_I_EXT
1710 	failure;
1711 #endif
1712 	genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1713 	comprintf("\tdont_care_flags();\n");
1714 	start_brace ();
1715 	switch (curi->size)
1716 	{
1717 	 case sz_byte:
1718 	    comprintf ("\tint dst = src;\n"
1719 		       "\tsign_extend_8_rr(src,src);\n");
1720 	    break;
1721 	 case sz_word:
1722 	    comprintf ("\tint dst = scratchie++;\n"
1723 		       "\tsign_extend_8_rr(dst,src);\n");
1724 	    break;
1725 	 case sz_long:
1726 	    comprintf ("\tint dst = src;\n"
1727 		       "\tsign_extend_16_rr(src,src);\n");
1728 	    break;
1729 	 default:
1730 	    assert(0);
1731 	}
1732 	genflags (flag_logical,
1733 		  curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
1734 	genastore ("dst", curi->smode, "srcreg",
1735 		   curi->size == sz_word ? sz_word : sz_long, "src");
1736 	break;
1737 
1738 	 case i_MVMEL:
1739 #ifdef DISABLE_I_MVEL
1740 	failure;
1741 #endif
1742 	genmovemel (opcode);
1743 	break;
1744 
1745      case i_MVMLE:
1746 #ifdef DISABLE_I_MVMLE
1747     failure;
1748 #endif
1749 	genmovemle (opcode);
1750 	break;
1751 
1752 	 case i_TRAP:
1753 	isjump;
1754 	failure;
1755 	break;
1756 
1757      case i_MVR2USP:
1758 	isjump;
1759 	failure;
1760 	break;
1761 
1762      case i_MVUSP2R:
1763 	isjump;
1764 	failure;
1765 	break;
1766 
1767      case i_RESET:
1768 	isjump;
1769 	failure;
1770 	break;
1771 
1772      case i_NOP:
1773 	break;
1774 
1775      case i_STOP:
1776 	isjump;
1777 	failure;
1778 	break;
1779 
1780      case i_RTE:
1781 	isjump;
1782 	failure;
1783 	break;
1784 
1785      case i_RTD:
1786 #ifdef DISABLE_I_RTD
1787     failure;
1788 #endif
1789 	genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0);
1790 	/* offs is constant */
1791 	comprintf("\tadd_l_ri(offs,4);\n");
1792 	start_brace();
1793 	comprintf("\tint newad=scratchie++;\n"
1794 		  "\treadlong(15,newad,scratchie);\n"
1795 		  "\tmov_l_mr((uintptr)&regs.pc,newad);\n"
1796 		  "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1797 		  "\tmov_l_mr((uintptr)&regs.pc_oldp,PC_P);\n"
1798 		  "\tm68k_pc_offset=0;\n"
1799 		  "\tadd_l(15,offs);\n");
1800 	gen_update_next_handler();
1801 	isjump;
1802 	break;
1803 
1804      case i_LINK:
1805 #ifdef DISABLE_I_LINK
1806     failure;
1807 #endif
1808 	genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1809 	genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1810 	comprintf("\tsub_l_ri(15,4);\n"
1811 		  "\twritelong_clobber(15,src,scratchie);\n"
1812 		  "\tmov_l_rr(src,15);\n");
1813 	if (curi->size==sz_word)
1814 	    comprintf("\tsign_extend_16_rr(offs,offs);\n");
1815 	comprintf("\tadd_l(15,offs);\n");
1816 	genastore ("src", curi->smode, "srcreg", sz_long, "src");
1817 	break;
1818 
1819      case i_UNLK:
1820 #ifdef DISABLE_I_UNLK
1821     failure;
1822 #endif
1823 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1824 	comprintf("\tmov_l_rr(15,src);\n"
1825 		  "\treadlong(15,src,scratchie);\n"
1826 		  "\tadd_l_ri(15,4);\n");
1827 	genastore ("src", curi->smode, "srcreg", curi->size, "src");
1828 	break;
1829 
1830 	 case i_RTS:
1831 #ifdef DISABLE_I_RTS
1832 	failure;
1833 #endif
1834 	comprintf("\tint newad=scratchie++;\n"
1835 		  "\treadlong(15,newad,scratchie);\n"
1836 		  "\tmov_l_mr((uintptr)&regs.pc,newad);\n"
1837 		  "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1838 		  "\tmov_l_mr((uintptr)&regs.pc_oldp,PC_P);\n"
1839 		  "\tm68k_pc_offset=0;\n"
1840 		  "\tlea_l_brr(15,15,4);\n");
1841 	gen_update_next_handler();
1842 	isjump;
1843 	break;
1844 
1845      case i_TRAPV:
1846 	isjump;
1847 	failure;
1848 	break;
1849 
1850      case i_RTR:
1851 	isjump;
1852 	failure;
1853 	break;
1854 
1855      case i_JSR:
1856 #ifdef DISABLE_I_JSR
1857     failure;
1858 #endif
1859 	isjump;
1860 	genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1861 	start_brace();
1862 	comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
1863 	comprintf("\tint ret=scratchie++;\n"
1864 		  "\tmov_l_ri(ret,retadd);\n"
1865 		  "\tsub_l_ri(15,4);\n"
1866 		  "\twritelong_clobber(15,ret,scratchie);\n");
1867 	comprintf("\tmov_l_mr((uintptr)&regs.pc,srca);\n"
1868 		  "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1869 		  "\tmov_l_mr((uintptr)&regs.pc_oldp,PC_P);\n"
1870 		  "\tm68k_pc_offset=0;\n");
1871 	gen_update_next_handler();
1872 	break;
1873 
1874      case i_JMP:
1875 #ifdef DISABLE_I_JMP
1876     failure;
1877 #endif
1878 	isjump;
1879 	genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1880 	comprintf("\tmov_l_mr((uintptr)&regs.pc,srca);\n"
1881 		  "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1882 		  "\tmov_l_mr((uintptr)&regs.pc_oldp,PC_P);\n"
1883 		  "\tm68k_pc_offset=0;\n");
1884 	gen_update_next_handler();
1885 	break;
1886 
1887      case i_BSR:
1888 #ifdef DISABLE_I_BSR
1889     failure;
1890 #endif
1891 	is_const_jump;
1892 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1893 	start_brace();
1894 	comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
1895 	comprintf("\tint ret=scratchie++;\n"
1896 		  "\tmov_l_ri(ret,retadd);\n"
1897 		  "\tsub_l_ri(15,4);\n"
1898 		  "\twritelong_clobber(15,ret,scratchie);\n");
1899 	comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n");
1900 	comprintf("\tm68k_pc_offset=0;\n");
1901 	comprintf("\tadd_l(PC_P,src);\n");
1902 
1903 	comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n");
1904 	break;
1905 
1906      case i_Bcc:
1907 #ifdef DISABLE_I_BCC
1908     failure;
1909 #endif
1910 	comprintf("\tuae_u32 v,v1,v2;\n");
1911 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1912 	/* That source is an immediate, so we can clobber it with abandon */
1913 	switch(curi->size) {
1914 	 case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break;
1915 	 case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break;
1916 	 case sz_long: break;
1917 	}
1918 	comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
1919 	/* Leave the following as "add" --- it will allow it to be optimized
1920 	   away due to src being a constant ;-) */
1921 	comprintf("\tadd_l_ri(src,(uintptr)comp_pc_p);\n");
1922 	comprintf("\tmov_l_ri(PC_P,(uintptr)comp_pc_p);\n");
1923 	/* Now they are both constant. Might as well fold in m68k_pc_offset */
1924 	comprintf("\tadd_l_ri(src,m68k_pc_offset);\n");
1925 	comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
1926 	comprintf("\tm68k_pc_offset=0;\n");
1927 
1928 	if (curi->cc>=2) {
1929 	    comprintf("\tv1=get_const(PC_P);\n"
1930 		      "\tv2=get_const(src);\n"
1931 		      "\tregister_branch(v1,v2,%d);\n",
1932 		      cond_codes[curi->cc]);
1933 	    comprintf("\tmake_flags_live();\n"); /* Load the flags */
1934 	    isjump;
1935 	}
1936 	else {
1937 	    is_const_jump;
1938 	}
1939 
1940 	switch(curi->cc) {
1941 	 case 0:  /* Unconditional jump */
1942 	    comprintf("\tmov_l_rr(PC_P,src);\n");
1943 	    comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n");
1944 	    break;
1945 	 case 1: break; /* This is silly! */
1946 	 case 8: failure; break;  /* Work out details! FIXME */
1947 	 case 9: failure; break;  /* Not critical, though! */
1948 
1949 	 case 2:
1950 	 case 3:
1951 	 case 4:
1952 	 case 5:
1953 	 case 6:
1954 	 case 7:
1955 	 case 10:
1956 	 case 11:
1957 	 case 12:
1958 	 case 13:
1959 	 case 14:
1960 	 case 15:
1961 	    break;
1962 	 default: assert(0);
1963 	}
1964 	break;
1965 
1966      case i_LEA:
1967 #ifdef DISABLE_I_LEA
1968     failure;
1969 #endif
1970 	genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1971 	genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1972 	genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
1973 	break;
1974 
1975      case i_PEA:
1976 #ifdef DISABLE_I_PEA
1977     failure;
1978 #endif
1979 	if (table68k[opcode].smode==Areg ||
1980 	    table68k[opcode].smode==Aind ||
1981 	    table68k[opcode].smode==Aipi ||
1982 	    table68k[opcode].smode==Apdi ||
1983 	    table68k[opcode].smode==Ad16 ||
1984 	    table68k[opcode].smode==Ad8r)
1985 	    comprintf("if (srcreg==7) dodgy=1;\n");
1986 
1987 	genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1988 	genamode (Apdi, "7", sz_long, "dst", 2, 0);
1989 	genastore ("srca", Apdi, "7", sz_long, "dst");
1990 	break;
1991 
1992      case i_DBcc:
1993 #ifdef DISABLE_I_DBCC
1994     failure;
1995 #endif
1996 	isjump;
1997 	uses_cmov;
1998 	genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1999 	genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
2000 
2001 	/* That offs is an immediate, so we can clobber it with abandon */
2002 	switch(curi->size) {
2003 	 case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break;
2004 	 default: assert(0);  /* Seems this only comes in word flavour */
2005 	}
2006 	comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
2007 	comprintf("\tadd_l_ri(offs,(uintptr)comp_pc_p);\n"); /* New PC,
2008 								once the
2009 								offset_68k is
2010 								* also added */
2011 	/* Let's fold in the m68k_pc_offset at this point */
2012 	comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n");
2013 	comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
2014 	comprintf("\tm68k_pc_offset=0;\n");
2015 
2016 	start_brace();
2017 	comprintf("\tint nsrc=scratchie++;\n");
2018 
2019 	if (curi->cc>=2) {
2020 	    comprintf("\tmake_flags_live();\n"); /* Load the flags */
2021 	}
2022 
2023 	assert (curi->size==sz_word);
2024 
2025 	switch(curi->cc) {
2026 	 case 0: /* This is an elaborate nop? */
2027 	    break;
2028 	 case 1:
2029 	    comprintf("\tstart_needflags();\n");
2030 	    comprintf("\tsub_w_ri(src,1);\n");
2031 	    comprintf("\t end_needflags();\n");
2032 	    start_brace();
2033 	    comprintf("\tuae_u32 v2,v;\n"
2034 		      "\tuae_u32 v1=get_const(PC_P);\n");
2035 	    comprintf("\tv2=get_const(offs);\n"
2036 		      "\tregister_branch(v1,v2,%d);\n", NATIVE_CC_CC);
2037 	    break;
2038 
2039 	 case 8: failure; break;  /* Work out details! FIXME */
2040 	 case 9: failure; break;  /* Not critical, though! */
2041 
2042 	 case 2:
2043 	 case 3:
2044 	 case 4:
2045 	 case 5:
2046 	 case 6:
2047 	 case 7:
2048 	 case 10:
2049 	 case 11:
2050 	 case 12:
2051 	 case 13:
2052 	 case 14:
2053 	 case 15:
2054 	    comprintf("\tmov_l_rr(nsrc,src);\n");
2055 	    comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n"
2056 		      "\tmov_w_rr(src,scratchie);\n");
2057 	    comprintf("\tcmov_l_rr(offs,PC_P,%d);\n",
2058 		      cond_codes[curi->cc]);
2059 	    comprintf("\tcmov_l_rr(src,nsrc,%d);\n",
2060 		      cond_codes[curi->cc]);
2061 	    /* OK, now for cc=true, we have src==nsrc and offs==PC_P,
2062 	       so whether we move them around doesn't matter. However,
2063 	       if cc=false, we have offs==jump_pc, and src==nsrc-1 */
2064 
2065 	    comprintf("\t start_needflags();\n");
2066 	    comprintf("\ttest_w_rr(nsrc,nsrc);\n");
2067 	    comprintf("\t end_needflags();\n");
2068 	    comprintf("\tcmov_l_rr(PC_P,offs,%d);\n", NATIVE_CC_NE);
2069 	    break;
2070 	 default: assert(0);
2071 	}
2072 	genastore ("src", curi->smode, "srcreg", curi->size, "src");
2073 	gen_update_next_handler();
2074 	break;
2075 
2076      case i_Scc:
2077 #ifdef DISABLE_I_SCC
2078     failure;
2079 #endif
2080 	genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
2081 	start_brace ();
2082 	comprintf ("\tint val = scratchie++;\n");
2083 
2084 	/* We set val to 0 if we really should use 255, and to 1 for real 0 */
2085 	switch(curi->cc) {
2086 	 case 0:  /* Unconditional set */
2087 	    comprintf("\tmov_l_ri(val,0);\n");
2088 	    break;
2089 	 case 1:
2090 	    /* Unconditional not-set */
2091 	    comprintf("\tmov_l_ri(val,1);\n");
2092 	    break;
2093 	 case 8: failure; break;  /* Work out details! FIXME */
2094 	 case 9: failure; break;  /* Not critical, though! */
2095 
2096 	 case 2:
2097 	 case 3:
2098 	 case 4:
2099 	 case 5:
2100 	 case 6:
2101 	 case 7:
2102 	 case 10:
2103 	 case 11:
2104 	 case 12:
2105 	 case 13:
2106 	 case 14:
2107 	 case 15:
2108 	    comprintf("\tmake_flags_live();\n"); /* Load the flags */
2109 	    /* All condition codes can be inverted by changing the LSB */
2110 	    comprintf("\tsetcc(val,%d);\n",
2111 		      cond_codes[curi->cc]^1); break;
2112 	 default: assert(0);
2113 	}
2114 	comprintf("\tsub_b_ri(val,1);\n");
2115 	genastore ("val", curi->smode, "srcreg", curi->size, "src");
2116 	break;
2117 
2118 	 case i_DIVU:
2119 	isjump;
2120 	failure;
2121 	break;
2122 
2123      case i_DIVS:
2124 	isjump;
2125 	failure;
2126 	break;
2127 
2128 	 case i_MULU:
2129 #ifdef DISABLE_I_MULU
2130 	failure;
2131 #endif
2132 	comprintf("\tdont_care_flags();\n");
2133 	genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
2134 	genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
2135 	/* To do 16x16 unsigned multiplication, we actually use
2136 	   32x32 signed, and zero-extend the registers first.
2137 	   That solves the problem of MUL needing dedicated registers
2138 	   on the x86 */
2139 	comprintf("\tzero_extend_16_rr(scratchie,src);\n"
2140 		  "\tzero_extend_16_rr(dst,dst);\n"
2141 		  "\timul_32_32(dst,scratchie);\n");
2142 	genflags (flag_logical, sz_long, "dst", "", "");
2143 	genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
2144 	break;
2145 
2146      case i_MULS:
2147 #ifdef DISABLE_I_MULS
2148     failure;
2149 #endif
2150 	comprintf("\tdont_care_flags();\n");
2151 	genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
2152 	genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
2153 	comprintf("\tsign_extend_16_rr(scratchie,src);\n"
2154 		  "\tsign_extend_16_rr(dst,dst);\n"
2155 		  "\timul_32_32(dst,scratchie);\n");
2156 	genflags (flag_logical, sz_long, "dst", "", "");
2157 	genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
2158 	break;
2159 
2160 	 case i_CHK:
2161 	isjump;
2162 	failure;
2163 	break;
2164 
2165      case i_CHK2:
2166 	isjump;
2167 	failure;
2168 	break;
2169 
2170      case i_ASR:
2171 #ifdef DISABLE_I_ASR
2172     failure;
2173 #endif
2174 	mayfail;
2175 	if (curi->smode==Dreg) {
2176 	    comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2177 		"  FAIL(1);\n"
2178 		"  " RETURN "\n"
2179 		"} \n");
2180 	    start_brace();
2181 	}
2182 	comprintf("\tdont_care_flags();\n");
2183 
2184 	genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2185 	genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2186 
2187 	start_brace();
2188 	if (!noflags)
2189 		comprintf("\tstart_needflags();\n");
2190 	if (curi->smode!=immi) {
2191 		uses_cmov;
2192 		start_brace();
2193 		comprintf("\tint zero = scratchie++;\n");
2194 		comprintf("\tint minus1 = scratchie++;\n");
2195 		comprintf("\tand_l_ri(cnt,63);\n");
2196 		comprintf("\tmov_l_ri(zero, 0);\n");
2197 		comprintf("\tmov_l_ri(minus1, -1);\n");
2198 		switch(curi->size) {
2199 		 case sz_byte:
2200 		 	comprintf("\ttest_b_rr(data,data);\n");
2201 		 	comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n");
2202 		 	comprintf("\ttest_l_ri(cnt, 0x38);\n");
2203 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2204 		 	comprintf("\tshra_b_rr(data,cnt);\n");
2205 		 	break;
2206 		 case sz_word:
2207 		 	comprintf("\ttest_w_rr(data,data);\n");
2208 		 	comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n");
2209 		 	comprintf("\ttest_l_ri(cnt, 0x30);\n");
2210 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2211 		 	comprintf("\tshra_w_rr(data,cnt);\n");
2212 		 	break;
2213 		 case sz_long:
2214 		 	comprintf("\ttest_l_rr(data,data);\n");
2215 		 	comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n");
2216 		 	comprintf("\ttest_l_ri(cnt, 0x20);\n");
2217 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2218 		 	comprintf("\tshra_l_rr(data,cnt);\n");
2219 		 	break;
2220 		 default: assert(0);
2221 		}
2222 		/* Result of shift is now in data. */
2223 	}
2224 	else {
2225 	    switch(curi->size) {
2226 	     case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n"); break;
2227 	     case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n"); break;
2228 	     case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n"); break;
2229 	     default: assert(0);
2230 	    }
2231 	}
2232 	/* And create the flags */
2233 	if (!noflags) {
2234 		comprintf("\tlive_flags();\n");
2235 		comprintf("\tend_needflags();\n");
2236 		if (curi->smode!=immi)
2237 			comprintf("\tsetcc_for_cntzero(cnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
2238 		else
2239 			comprintf("\tduplicate_carry();\n");
2240 		comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2241 	}
2242 	genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2243 	break;
2244 
2245      case i_ASL:
2246 #ifdef DISABLE_I_ASL
2247     failure;
2248 #endif
2249 	mayfail;
2250 	if (curi->smode==Dreg) {
2251 	    comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2252 		"  FAIL(1);\n"
2253 		"  " RETURN "\n"
2254 		"} \n");
2255 	    start_brace();
2256 	}
2257 	comprintf("\tdont_care_flags();\n");
2258 	/* Except for the handling of the V flag, this is identical to
2259 	   LSL. The handling of V is, uhm, unpleasant, so if it's needed,
2260 	   let the normal emulation handle it. Shoulders of giants kinda
2261 	   thing ;-) */
2262 	comprintf("if (needed_flags & FLAG_V) {\n"
2263 		  "  FAIL(1);\n"
2264 		  "  " RETURN "\n"
2265 		  "} \n");
2266 
2267 	genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2268 	genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2269 
2270 	if (!noflags)
2271 		comprintf("\tstart_needflags();\n");
2272 	if (curi->smode!=immi) {
2273 		uses_cmov;
2274 		start_brace();
2275 		comprintf("\tint zero = scratchie++;\n");
2276 		comprintf("\tand_l_ri(cnt,63);\n");
2277 		comprintf("\tmov_l_ri(zero, 0);\n");
2278 		switch(curi->size) {
2279 		 case sz_byte:
2280 		 	comprintf("\ttest_l_ri(cnt, 0x38);\n");
2281 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2282 		 	comprintf("\tshll_b_rr(data,cnt);\n");
2283 		 	break;
2284 		 case sz_word:
2285 		 	comprintf("\ttest_l_ri(cnt, 0x30);\n");
2286 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2287 		 	comprintf("\tshll_w_rr(data,cnt);\n");
2288 		 	break;
2289 		 case sz_long:
2290 		 	comprintf("\ttest_l_ri(cnt, 0x20);\n");
2291 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2292 		 	comprintf("\tshll_l_rr(data,cnt);\n");
2293 		 	break;
2294 		 default: assert(0);
2295 		}
2296 		/* Result of shift is now in data. */
2297 	}
2298 	else {
2299 	    switch(curi->size) {
2300 	     case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break;
2301 	     case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break;
2302 	     case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break;
2303 	     default: assert(0);
2304 	    }
2305 	}
2306 	/* And create the flags */
2307 	if (!noflags) {
2308 		comprintf("\tlive_flags();\n");
2309 		comprintf("\tend_needflags();\n");
2310 		if (curi->smode!=immi)
2311 			comprintf("\tsetcc_for_cntzero(cnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
2312 		else
2313 			comprintf("\tduplicate_carry();\n");
2314 		comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2315 	}
2316 	genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2317 	break;
2318 
2319 	 case i_LSR:
2320 #ifdef DISABLE_I_LSR
2321 	failure;
2322 #endif
2323 	mayfail;
2324 	if (curi->smode==Dreg) {
2325 	    comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2326 		"  FAIL(1);\n"
2327 		"  " RETURN "\n"
2328 		"} \n");
2329 	    start_brace();
2330 	}
2331 	comprintf("\tdont_care_flags();\n");
2332 
2333 	genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2334 	genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2335 
2336 	start_brace();
2337 	if (!noflags)
2338 		comprintf("\tstart_needflags();\n");
2339 	if (curi->smode!=immi) {
2340 		uses_cmov;
2341 		start_brace();
2342 		comprintf("\tint zero = scratchie++;\n");
2343 		comprintf("\tand_l_ri(cnt,63);\n");
2344 		comprintf("\tmov_l_ri(zero, 0);\n");
2345 		switch(curi->size) {
2346 		 case sz_byte:
2347 		 	comprintf("\ttest_l_ri(cnt, 0x38);\n");
2348 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2349 		 	comprintf("\tshrl_b_rr(data,cnt);\n");
2350 		 	break;
2351 		 case sz_word:
2352 		 	comprintf("\ttest_l_ri(cnt, 0x30);\n");
2353 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2354 		 	comprintf("\tshrl_w_rr(data,cnt);\n");
2355 		 	break;
2356 		 case sz_long:
2357 		 	comprintf("\ttest_l_ri(cnt, 0x20);\n");
2358 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2359 		 	comprintf("\tshrl_l_rr(data, cnt);\n");
2360 		 	break;
2361 		 default: assert(0);
2362 		}
2363 		/* Result of shift is now in data. */
2364 	}
2365 	else {
2366 	    switch(curi->size) {
2367 	     case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n"); break;
2368 	     case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n"); break;
2369 	     case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n"); break;
2370 	     default: assert(0);
2371 	    }
2372 	}
2373 	/* And create the flags */
2374 	if (!noflags) {
2375 		comprintf("\tlive_flags();\n");
2376 		comprintf("\tend_needflags();\n");
2377 		if (curi->smode!=immi)
2378 			comprintf("\tsetcc_for_cntzero(cnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
2379 		else
2380 			comprintf("\tduplicate_carry();\n");
2381 		comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2382 	}
2383 	genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2384 	break;
2385 
2386 	 case i_LSL:
2387 #ifdef DISABLE_I_LSL
2388 	failure;
2389 #endif
2390 	mayfail;
2391 	if (curi->smode==Dreg) {
2392 		comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2393 				"  FAIL(1);\n"
2394 				"  " RETURN "\n"
2395 				"} \n");
2396 		start_brace();
2397 	}
2398 	comprintf("\tdont_care_flags();\n");
2399 
2400 	genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2401 	genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2402 
2403 	start_brace();
2404 	if (!noflags)
2405 		comprintf("\tstart_needflags();\n");
2406 	if (curi->smode!=immi) {
2407 		uses_cmov;
2408 		start_brace();
2409 		comprintf("\tint zero = scratchie++;\n");
2410 		comprintf("\tand_l_ri(cnt,63);\n");
2411 		comprintf("\tmov_l_ri(zero, 0);\n");
2412 		switch(curi->size) {
2413 		 case sz_byte:
2414 		 	comprintf("\ttest_l_ri(cnt, 0x38);\n");
2415 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2416 		 	comprintf("\tshll_b_rr(data,cnt);\n");
2417 		 	break;
2418 		 case sz_word:
2419 		 	comprintf("\ttest_l_ri(cnt, 0x30);\n");
2420 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2421 		 	comprintf("\tshll_w_rr(data,cnt);\n");
2422 		 	break;
2423 		 case sz_long:
2424 		 	comprintf("\ttest_l_ri(cnt, 0x20);\n");
2425 		 	comprintf("\tcmov_l_rr(data, zero, NATIVE_CC_NE);\n");
2426 		 	comprintf("\tshll_l_rr(data,cnt);\n");
2427 		 	break;
2428 		 default: assert(0);
2429 		}
2430 		/* Result of shift is now in data. */
2431 	}
2432 	else {
2433 	    switch(curi->size) {
2434 	     case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break;
2435 	     case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break;
2436 	     case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break;
2437 	     default: assert(0);
2438 	    }
2439 	}
2440 	/* And create the flags */
2441 	if (!noflags) {
2442 		comprintf("\tlive_flags();\n");
2443 		comprintf("\tend_needflags();\n");
2444 		if (curi->smode!=immi)
2445 			comprintf("\tsetcc_for_cntzero(cnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4);
2446 		else
2447 			comprintf("\tduplicate_carry();\n");
2448 		comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2449 	}
2450 	genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2451 	break;
2452 
2453 	 case i_ROL:
2454 #ifdef DISABLE_I_ROL
2455 	failure;
2456 #endif
2457 	mayfail;
2458 	if (curi->smode==Dreg) {
2459 	    comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2460 		"  FAIL(1);\n"
2461 		"  " RETURN "\n"
2462 		"} \n");
2463 	    start_brace();
2464 	}
2465 	comprintf("\tdont_care_flags();\n");
2466 	genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2467 	genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2468 	start_brace ();
2469 
2470 	switch(curi->size) {
2471 	 case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break;
2472 	 case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break;
2473 	 case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break;
2474 	}
2475 
2476 	if (!noflags) {
2477 	    comprintf("\tstart_needflags();\n");
2478 	    /*
2479 	     * x86 ROL instruction does not set ZF/SF, so we need extra checks here
2480 	     */
2481 	    comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2482 	    switch(curi->size) {
2483 	     case sz_byte: comprintf("\t  test_b_rr(data,data);\n"); break;
2484 	     case sz_word: comprintf("\t  test_w_rr(data,data);\n"); break;
2485 	     case sz_long: comprintf("\t  test_l_rr(data,data);\n"); break;
2486 	    }
2487 	    comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */
2488 	    comprintf("\t live_flags();\n");
2489 	    comprintf("\t end_needflags();\n");
2490 	}
2491 	genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2492 	break;
2493 
2494      case i_ROR:
2495 #ifdef DISABLE_I_ROR
2496     failure;
2497 #endif
2498 	mayfail;
2499 	if (curi->smode==Dreg) {
2500 	    comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2501 		"  FAIL(1);\n"
2502 		"  " RETURN "\n"
2503 		"} \n");
2504 	    start_brace();
2505 	}
2506 	comprintf("\tdont_care_flags();\n");
2507 	genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2508 	genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2509 	start_brace ();
2510 
2511 	switch(curi->size) {
2512 	 case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break;
2513 	 case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break;
2514 	 case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break;
2515 	}
2516 
2517 	if (!noflags) {
2518 	    comprintf("\tstart_needflags();\n");
2519 	    /*
2520 	     * x86 ROR instruction does not set ZF/SF, so we need extra checks here
2521 	     */
2522 	    comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2523 	    switch(curi->size) {
2524 	     case sz_byte: comprintf("\t  test_b_rr(data,data);\n"); break;
2525 	     case sz_word: comprintf("\t  test_w_rr(data,data);\n"); break;
2526 	     case sz_long: comprintf("\t  test_l_rr(data,data);\n"); break;
2527 	    }
2528 	    switch(curi->size) {
2529 	     case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break;
2530 	     case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break;
2531 	     case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break;
2532 	    }
2533 	    comprintf("\t live_flags();\n");
2534 	    comprintf("\t end_needflags();\n");
2535 	}
2536 	genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2537 	break;
2538 
2539      case i_ROXL:
2540 	failure;
2541 	break;
2542 
2543      case i_ROXR:
2544 	failure;
2545 	break;
2546 
2547      case i_ASRW:
2548 	failure;
2549 	break;
2550 
2551      case i_ASLW:
2552 	failure;
2553 	break;
2554 
2555      case i_LSRW:
2556 	failure;
2557 	break;
2558 
2559      case i_LSLW:
2560 	failure;
2561 	break;
2562 
2563      case i_ROLW:
2564 	failure;
2565 	break;
2566 
2567      case i_RORW:
2568 	failure;
2569 	break;
2570 
2571      case i_ROXLW:
2572 	failure;
2573 	break;
2574 
2575      case i_ROXRW:
2576 	failure;
2577 	break;
2578 
2579      case i_MOVEC2:
2580 	isjump;
2581 	failure;
2582 	break;
2583 
2584      case i_MOVE2C:
2585 	isjump;
2586 	failure;
2587 	break;
2588 
2589      case i_CAS:
2590 	failure;
2591 	break;
2592 
2593      case i_CAS2:
2594 	failure;
2595 	break;
2596 
2597      case i_MOVES:		/* ignore DFC and SFC because we have no MMU */
2598 	isjump;
2599 	failure;
2600 	break;
2601 
2602      case i_BKPT:		/* only needed for hardware emulators */
2603 	isjump;
2604 	failure;
2605 	break;
2606 
2607      case i_CALLM:		/* not present in 68030 */
2608 	isjump;
2609 	failure;
2610 	break;
2611 
2612      case i_RTM:		/* not present in 68030 */
2613 	isjump;
2614 	failure;
2615 	break;
2616 
2617      case i_TRAPcc:
2618 	isjump;
2619 	failure;
2620 	break;
2621 
2622      case i_DIVL:
2623 	isjump;
2624 	failure;
2625 	break;
2626 
2627      case i_MULL:
2628 #ifdef DISABLE_I_MULL
2629     failure;
2630 #endif
2631 	if (!noflags) {
2632 	    failure;
2633 	    break;
2634 	}
2635 	comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2636 	comprintf("\tint r2=(extra>>12)&7;\n"
2637 		  "\tint tmp=scratchie++;\n");
2638 
2639 	genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2640 	/* The two operands are in dst and r2 */
2641 	comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */
2642 		  "\tint r3=(extra&7);\n"
2643 		  "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */
2644 	comprintf("\tif (extra&0x0800) { \n" /* signed */
2645 		  "\t\timul_64_32(r2,r3);\n"
2646 		  "\t} else { \n"
2647 		  "\t\tmul_64_32(r2,r3);\n"
2648 		  "\t} \n");
2649 	/* The result is in r2/tmp, with r2 holding the lower 32 bits */
2650 	comprintf("\t} else {\n");  /* Only want 32 bit result */
2651 	/* operands in dst and r2, result foes into r2 */
2652 	/* shouldn't matter whether it's signed or unsigned?!? */
2653 	comprintf("\timul_32_32(r2,dst);\n"
2654 		  "\t}\n");
2655 	break;
2656 
2657      case i_BFTST:
2658      case i_BFEXTU:
2659      case i_BFCHG:
2660      case i_BFEXTS:
2661      case i_BFCLR:
2662      case i_BFFFO:
2663      case i_BFSET:
2664      case i_BFINS:
2665 	failure;
2666 	break;
2667 
2668      case i_PACK:
2669 	failure;
2670 	break;
2671 
2672      case i_UNPK:
2673 	failure;
2674 	break;
2675 
2676 	 case i_TAS:
2677 	failure;
2678 	break;
2679 
2680      case i_FPP:
2681 #ifdef DISABLE_I_FPP
2682     failure;
2683 #endif
2684 	uses_fpu;
2685 	mayfail;
2686 	comprintf("#ifdef USE_JIT_FPU\n");
2687 	comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2688 	swap_opcode();
2689 	comprintf("\tcomp_fpp_opp(opcode,extra);\n");
2690 	comprintf("#else\n");
2691 	comprintf("\tfailure = 1;\n");
2692 	comprintf("#endif\n");
2693 	break;
2694 
2695      case i_FBcc:
2696 #ifdef DISABLE_I_FBCC
2697     failure;
2698 #endif
2699 	uses_fpu;
2700 	isjump;
2701 	uses_cmov;
2702 	mayfail;
2703 	comprintf("#ifdef USE_JIT_FPU\n");
2704 	swap_opcode();
2705 	comprintf("\tcomp_fbcc_opp(opcode);\n");
2706 	comprintf("#else\n");
2707 	comprintf("\tfailure = 1;\n");
2708 	comprintf("#endif\n");
2709 	break;
2710 
2711      case i_FDBcc:
2712 	uses_fpu;
2713 	isjump;
2714 	failure;
2715 	break;
2716 
2717      case i_FScc:
2718 #ifdef DISABLE_I_FSCC
2719     failure;
2720 #endif
2721 	uses_fpu;
2722 	mayfail;
2723 	uses_cmov;
2724 	comprintf("#ifdef USE_JIT_FPU\n");
2725 	comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2726 	swap_opcode();
2727 	comprintf("\tcomp_fscc_opp(opcode,extra);\n");
2728 	comprintf("#else\n");
2729 	comprintf("\tfailure = 1;\n");
2730 	comprintf("#endif\n");
2731 	break;
2732 
2733      case i_FTRAPcc:
2734 	uses_fpu;
2735 	isjump;
2736 	failure;
2737 	break;
2738 
2739      case i_FSAVE:
2740 	uses_fpu;
2741 	failure;
2742 	break;
2743 
2744      case i_FRESTORE:
2745 	uses_fpu;
2746 	failure;
2747 	break;
2748 
2749      case i_CINVL:
2750      case i_CINVP:
2751      case i_CINVA:
2752 	isjump;  /* Not really, but it's probably a good idea to stop
2753 		    translating at this point */
2754 	failure;
2755 	comprintf ("\tflush_icache();\n");  /* Differentiate a bit more? */
2756 	break;
2757 
2758      case i_CPUSHL:
2759      case i_CPUSHP:
2760      case i_CPUSHA:
2761 	isjump;  /* Not really, but it's probably a good idea to stop
2762 		    translating at this point */
2763 	failure;
2764 	break;
2765 
2766      case i_MOVE16:
2767 #ifdef DISABLE_I_MOVE16
2768     failure;
2769 #endif
2770 	genmov16(opcode,curi);
2771 	break;
2772 
2773 #ifdef UAE
2774      case i_MMUOP030:
2775      case i_PFLUSHN:
2776      case i_PFLUSH:
2777      case i_PFLUSHAN:
2778      case i_PFLUSHA:
2779      case i_PLPAR:
2780      case i_PLPAW:
2781      case i_PTESTR:
2782      case i_PTESTW:
2783      case i_LPSTOP:
2784 	isjump;
2785 	failure;
2786 	break;
2787 #endif
2788 
2789 #ifdef WINUAE_ARANYM
2790      case i_EMULOP_RETURN:
2791 	isjump;
2792 	failure;
2793 	break;
2794 
2795      case i_EMULOP:
2796 	failure;
2797 	break;
2798 
2799      case i_NATFEAT_ID:
2800      case i_NATFEAT_CALL:
2801 	failure;
2802 	break;
2803 
2804      case i_MMUOP:
2805 	isjump;
2806 	failure;
2807 	break;
2808 #endif
2809 
2810 	 default:
2811 		assert(0);
2812 	break;
2813     }
2814     comprintf("%s",endstr);
2815     finish_braces ();
2816     sync_m68k_pc ();
2817     if (global_mayfail)
2818 	comprintf("\tif (failure)  m68k_pc_offset=m68k_pc_offset_thisinst;\n");
2819     return global_failure;
2820 }
2821 
2822 static void
generate_includes(FILE * f)2823 generate_includes (FILE * f)
2824 {
2825 	fprintf (f, "#include \"sysconfig.h\"\n");
2826 	fprintf (f, "#if defined(JIT)\n");
2827 	fprintf (f, "#include \"sysdeps.h\"\n");
2828 #ifdef UAE
2829 	fprintf (f, "#include \"options.h\"\n");
2830 	fprintf (f, "#include \"uae/memory.h\"\n");
2831 #else
2832 	fprintf (f, "#include \"m68k.h\"\n");
2833 	fprintf (f, "#include \"memory-uae.h\"\n");
2834 #endif
2835 	fprintf (f, "#include \"readcpu.h\"\n");
2836 	fprintf (f, "#include \"newcpu.h\"\n");
2837 	fprintf (f, "#include \"comptbl.h\"\n");
2838 	fprintf (f, "#include \"debug.h\"\n");
2839 }
2840 
2841 static int postfix;
2842 
2843 
decodeEA(amodes mode,wordsizes size)2844 static char *decodeEA (amodes mode, wordsizes size)
2845 {
2846 	static char buffer[80];
2847 
2848 	buffer[0] = 0;
2849 	switch (mode){
2850 	case Dreg:
2851 		strcpy (buffer,"Dn");
2852 		break;
2853 	case Areg:
2854 		strcpy (buffer,"An");
2855 		break;
2856 	case Aind:
2857 		strcpy (buffer,"(An)");
2858 		break;
2859 	case Aipi:
2860 		strcpy (buffer,"(An)+");
2861 		break;
2862 	case Apdi:
2863 		strcpy (buffer,"-(An)");
2864 		break;
2865 	case Ad16:
2866 		strcpy (buffer,"(d16,An)");
2867 		break;
2868 	case Ad8r:
2869 		strcpy (buffer,"(d8,An,Xn)");
2870 		break;
2871 	case PC16:
2872 		strcpy (buffer,"(d16,PC)");
2873 		break;
2874 	case PC8r:
2875 		strcpy (buffer,"(d8,PC,Xn)");
2876 		break;
2877 	case absw:
2878 		strcpy (buffer,"(xxx).W");
2879 		break;
2880 	case absl:
2881 		strcpy (buffer,"(xxx).L");
2882 		break;
2883 	case imm:
2884 		switch (size){
2885 		case sz_byte:
2886 			strcpy (buffer,"#<data>.B");
2887 			break;
2888 		case sz_word:
2889 			strcpy (buffer,"#<data>.W");
2890 			break;
2891 		case sz_long:
2892 			strcpy (buffer,"#<data>.L");
2893 			break;
2894 		default:
2895 			break;
2896 		}
2897 		break;
2898 	case imm0:
2899 		strcpy (buffer,"#<data>.B");
2900 		break;
2901 	case imm1:
2902 		strcpy (buffer,"#<data>.W");
2903 		break;
2904 	case imm2:
2905 		strcpy (buffer,"#<data>.L");
2906 		break;
2907 	case immi:
2908 		strcpy (buffer,"#<data>");
2909 		break;
2910 
2911 	default:
2912 		break;
2913 	}
2914 	return buffer;
2915 }
2916 
outopcode(const char * name,int opcode)2917 static char *outopcode (const char *name, int opcode)
2918 {
2919 	static char out[100];
2920 	struct instr *ins;
2921 
2922 	ins = &table68k[opcode];
2923 	strcpy (out, name);
2924 	if (ins->smode == immi)
2925 		strcat (out, "Q");
2926 	if (ins->size == sz_byte)
2927 		strcat (out,".B");
2928 	if (ins->size == sz_word)
2929 		strcat (out,".W");
2930 	if (ins->size == sz_long)
2931 		strcat (out,".L");
2932 	strcat (out," ");
2933 	if (ins->suse)
2934 		strcat (out, decodeEA (ins->smode, ins->size));
2935 	if (ins->duse) {
2936 		if (ins->suse) strcat (out,",");
2937 		strcat (out, decodeEA (ins->dmode, ins->size));
2938 	}
2939 	return out;
2940 }
2941 
2942 
2943 static void
generate_one_opcode(int rp,int noflags)2944 generate_one_opcode (int rp, int noflags)
2945 {
2946     int i;
2947     uae_u16 smsk, dmsk;
2948     unsigned int opcode = opcode_map[rp];
2949     int aborted=0;
2950     int have_srcreg=0;
2951     int have_dstreg=0;
2952 	const char *name;
2953 
2954     if (table68k[opcode].mnemo == i_ILLG
2955 	|| table68k[opcode].clev > cpu_level)
2956 	return;
2957 
2958     for (i = 0; lookuptab[i].name[0]; i++)
2959     {
2960 	if (table68k[opcode].mnemo == lookuptab[i].mnemo)
2961 	    break;
2962     }
2963 
2964     if (table68k[opcode].handler != -1)
2965 	return;
2966 
2967     switch (table68k[opcode].stype)
2968     {
2969     case 0:
2970 	smsk = 7;
2971 	break;
2972     case 1:
2973 	smsk = 255;
2974 	break;
2975     case 2:
2976 	smsk = 15;
2977 	break;
2978     case 3:
2979 	smsk = 7;
2980 	break;
2981     case 4:
2982 	smsk = 7;
2983 	break;
2984     case 5:
2985 	smsk = 63;
2986 	break;
2987 #ifndef UAE
2988     case 6:
2989 	smsk = 255;
2990 	break;
2991 #endif
2992 	case 7:
2993 	smsk = 3;
2994 	break;
2995     default:
2996     smsk = 0;
2997 	assert(0);
2998     }
2999     dmsk = 7;
3000 
3001     next_cpu_level = -1;
3002     if (table68k[opcode].suse
3003 	&& table68k[opcode].smode != imm && table68k[opcode].smode != imm0
3004 	&& table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
3005 	&& table68k[opcode].smode != absw && table68k[opcode].smode != absl
3006 	&& table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
3007     {
3008 	have_srcreg=1;
3009 	if (table68k[opcode].spos == -1)
3010 	{
3011 	    if (((int) table68k[opcode].sreg) >= 128)
3012 		comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
3013 	    else
3014 		comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg);
3015 	}
3016 	else
3017 	{
3018 	    char source[100];
3019 	    int pos = table68k[opcode].spos;
3020 
3021 #ifndef UAE
3022 	    comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n");
3023 
3024 	    if (pos < 8 && (smsk >> (8 - pos)) != 0)
3025 		sprintf (source, "(((opcode >> %d) | (opcode << %d)) & %d)",
3026 			pos ^ 8, 8 - pos, dmsk);
3027 	    else if (pos != 8)
3028 		sprintf (source, "((opcode >> %d) & %d)", pos ^ 8, smsk);
3029 	    else
3030 		sprintf (source, "(opcode & %d)", smsk);
3031 
3032 	    if (table68k[opcode].stype == 3)
3033 		comprintf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
3034 	    else if (table68k[opcode].stype == 1)
3035 		comprintf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
3036 	    else
3037 		comprintf ("\tuae_u32 srcreg = %s;\n", source);
3038 
3039 	    comprintf ("#else\n");
3040 #endif
3041 
3042 	    if (pos)
3043 		sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
3044 	    else
3045 		sprintf (source, "(opcode & %d)", smsk);
3046 
3047 	    if (table68k[opcode].stype == 3)
3048 		comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source);
3049 	    else if (table68k[opcode].stype == 1)
3050 		comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
3051 	    else
3052 		comprintf ("\tuae_s32 srcreg = %s;\n", source);
3053 
3054 #ifndef UAE
3055 		comprintf ("#endif\n");
3056 #endif
3057 	}
3058     }
3059     if (table68k[opcode].duse
3060 	/* Yes, the dmode can be imm, in case of LINK or DBcc */
3061 	&& table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
3062 	&& table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
3063 	&& table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
3064     {
3065 	have_dstreg=1;
3066 	if (table68k[opcode].dpos == -1)
3067 	{
3068 	    if (((int) table68k[opcode].dreg) >= 128)
3069 		comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
3070 	    else
3071 		comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg);
3072 	}
3073 	else
3074 	{
3075 	    int pos = table68k[opcode].dpos;
3076 
3077 #ifndef UAE
3078 	    comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n");
3079 
3080 	    if (pos < 8 && (dmsk >> (8 - pos)) != 0)
3081 		comprintf ("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n",
3082 			pos ^ 8, 8 - pos, dmsk);
3083 	    else if (pos != 8)
3084 		comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
3085 			pos ^ 8, dmsk);
3086 	    else
3087 			comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
3088 
3089 		comprintf ("#else\n");
3090 #endif
3091 
3092 	    if (pos)
3093 		comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
3094 			   pos, dmsk);
3095 	    else
3096 			comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
3097 
3098 #ifndef UAE
3099 		comprintf ("#endif\n");
3100 #endif
3101 	}
3102     }
3103 
3104     if (have_srcreg && have_dstreg &&
3105 	(table68k[opcode].dmode==Areg ||
3106 	 table68k[opcode].dmode==Aind ||
3107 	 table68k[opcode].dmode==Aipi ||
3108 	 table68k[opcode].dmode==Apdi ||
3109 	 table68k[opcode].dmode==Ad16 ||
3110 	 table68k[opcode].dmode==Ad8r) &&
3111 	(table68k[opcode].smode==Areg ||
3112 	 table68k[opcode].smode==Aind ||
3113 	 table68k[opcode].smode==Aipi ||
3114 	 table68k[opcode].smode==Apdi ||
3115 	 table68k[opcode].smode==Ad16 ||
3116 	 table68k[opcode].smode==Ad8r)
3117 	) {
3118 	comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n");
3119     }
3120     else {
3121 	comprintf("\tuae_u32 dodgy=0;\n");
3122     }
3123     comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n");
3124     comprintf("\tm68k_pc_offset+=2;\n");
3125 
3126     aborted=gen_opcode (opcode);
3127     {
3128 	char flags[64 * 6];
3129 	*flags = '\0';
3130 	if (global_isjump)	strcat(flags, "COMP_OPCODE_ISJUMP|");
3131 	if (long_opcode)	strcat(flags, "COMP_OPCODE_LONG_OPCODE|");
3132 	if (global_cmov)	strcat(flags, "COMP_OPCODE_CMOV|");
3133 	if (global_isaddx)	strcat(flags, "COMP_OPCODE_ISADDX|");
3134 	if (global_iscjump)	strcat(flags, "COMP_OPCODE_ISCJUMP|");
3135 	if (global_fpu)		strcat(flags, "COMP_OPCODE_USES_FPU|");
3136 	if (*flags)
3137 		flags[strlen(flags) - 1] = '\0';
3138 	else
3139 		strcpy(flags, "0");
3140 
3141 #ifdef UAE /* RETTYPE != void */
3142 	comprintf ("return 0;\n");
3143 #endif
3144 	comprintf ("}\n");
3145 
3146 	name = lookuptab[i].name;
3147 	if (aborted) {
3148 	    fprintf (stblfile, "{ NULL, %u, %s }, /* %s */\n", opcode, flags, name);
3149 	    com_discard();
3150 	} else {
3151 		const char *tbl = noflags ? "nf" : "ff";
3152 		fprintf (stblfile, "{ op_%x_%d_comp_%s, %u, %s }, /* %s */\n", opcode, postfix, tbl, opcode, flags, name);
3153 		fprintf (headerfile, "extern compop_func op_%x_%d_comp_%s;\n", opcode, postfix, tbl);
3154 		printf ("/* %s */\n", outopcode (name, opcode));
3155 		printf (RETTYPE " REGPARAM2 op_%x_%d_comp_%s(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, tbl, name);
3156 	    com_flush();
3157 	}
3158     }
3159     opcode_next_clev[rp] = next_cpu_level;
3160     opcode_last_postfix[rp] = postfix;
3161 }
3162 
3163 static void
generate_func(int noflags)3164 generate_func (int noflags)
3165 {
3166     int i, j, rp;
3167 	const char *tbl = noflags ? "nf" : "ff";
3168 
3169     using_prefetch = 0;
3170     using_exception_3 = 0;
3171     for (i = 0; i < 1; i++) /* We only do one level! */
3172     {
3173 	cpu_level = NEXT_CPU_LEVEL - i;
3174 	postfix = i;
3175 
3176 	fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_%s[] = {\n", postfix, tbl);
3177 
3178 	/* sam: this is for people with low memory (eg. me :)) */
3179 	printf ("\n"
3180 		 "#if !defined(PART_1) && !defined(PART_2) && "
3181 		 "!defined(PART_3) && !defined(PART_4) && "
3182 		 "!defined(PART_5) && !defined(PART_6) && "
3183 		 "!defined(PART_7) && !defined(PART_8)"
3184 		 "\n"
3185 		 "#define PART_1 1\n"
3186 		 "#define PART_2 1\n"
3187 		 "#define PART_3 1\n"
3188 		 "#define PART_4 1\n"
3189 		 "#define PART_5 1\n"
3190 		 "#define PART_6 1\n"
3191 		 "#define PART_7 1\n"
3192 		 "#define PART_8 1\n"
3193 		 "#endif\n\n");
3194 #ifdef UAE
3195 	printf ("extern void comp_fpp_opp();\n"
3196 		"extern void comp_fscc_opp();\n"
3197 		"extern void comp_fbcc_opp();\n\n");
3198 #endif
3199 
3200 	rp = 0;
3201 	for (j = 1; j <= 8; ++j)
3202 	{
3203 	    int k = (j * nr_cpuop_funcs) / 8;
3204 	    printf ("#ifdef PART_%d\n", j);
3205 	    for (; rp < k; rp++)
3206 		generate_one_opcode (rp,noflags);
3207 	    printf ("#endif\n\n");
3208 	}
3209 
3210 	fprintf (stblfile, "{ 0, 65536, 0 }};\n");
3211     }
3212 
3213 }
3214 
3215 #if (defined(OS_cygwin) || defined(OS_mingw)) && defined(EXTENDED_SIGSEGV)
cygwin_mingw_abort()3216 void cygwin_mingw_abort()
3217 {
3218 #undef abort
3219 	abort();
3220 }
3221 #endif
3222 
3223 #if defined(FSUAE) && defined (WINDOWS)
3224 #include "windows.h"
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)3225 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
3226 #else
3227 int main(void)
3228 #endif
3229 {
3230     init_table68k ();
3231 
3232     opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3233     opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3234     opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3235     counts = (unsigned long *) malloc (65536 * sizeof (unsigned long));
3236     read_counts ();
3237 
3238     /* It would be a lot nicer to put all in one file (we'd also get rid of
3239      * cputbl.h that way), but cpuopti can't cope.  That could be fixed, but
3240      * I don't dare to touch the 68k version.  */
3241 
3242 	headerfile = fopen (GEN_PATH "comptbl.h", "wb");
3243 	fprintf (headerfile, ""
3244 		"extern const struct comptbl op_smalltbl_0_comp_nf[];\n"
3245 		"extern const struct comptbl op_smalltbl_0_comp_ff[];\n"
3246 		"");
3247 
3248 	stblfile = fopen (GEN_PATH "compstbl.cpp", "wb");
3249 	if (freopen (GEN_PATH "compemu.cpp", "wb", stdout) == NULL) {
3250 		abort();
3251 	}
3252 
3253     generate_includes (stdout);
3254     generate_includes (stblfile);
3255 
3256     printf("#include \"" JIT_PATH "compemu.h\"\n");
3257     printf("#include \"" JIT_PATH "flags_x86.h\"\n");
3258 
3259     noflags=0;
3260     generate_func (noflags);
3261 
3262 	free(opcode_map);
3263 	free(opcode_last_postfix);
3264 	free(opcode_next_clev);
3265 	free(counts);
3266 
3267     opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3268     opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3269     opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3270     counts = (unsigned long *) malloc (65536 * sizeof (unsigned long));
3271     read_counts ();
3272     noflags=1;
3273     generate_func (noflags);
3274 
3275     printf ("#endif\n");
3276     fprintf (stblfile, "#endif\n");
3277 
3278 	free(opcode_map);
3279 	free(opcode_last_postfix);
3280 	free(opcode_next_clev);
3281 	free(counts);
3282 
3283     free (table68k);
3284 	fclose (stblfile);
3285 	fclose (headerfile);
3286     return 0;
3287 }
3288 
3289 #ifdef UAE
write_log(const TCHAR * format,...)3290 void write_log (const TCHAR *format,...)
3291 {
3292 }
3293 #endif
3294