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)®s.pc,newad);\n"
1698 "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1699 "\tmov_l_mr((uae_u32)®s.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)®s.pc,newad);\n"
1728 "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1729 "\tmov_l_mr((uae_u32)®s.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)®s.pc,srca);\n"
1754 "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1755 "\tmov_l_mr((uae_u32)®s.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)®s.pc,srca);\n"
1764 "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1765 "\tmov_l_mr((uae_u32)®s.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