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