|
|
1.1 root 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:
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:
52: static void com_discard(void)
53: {
54: comp_index=0;
55: }
56:
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
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
127: start_brace (void)
128: {
129: n_braces++;
130: comprintf ("{");
131: }
132:
133: static void
134: close_brace (void)
135: {
136: assert (n_braces > 0);
137: n_braces--;
138: comprintf ("}");
139: }
140:
141: static void
142: finish_braces (void)
143: {
144: while (n_braces > 0)
145: close_brace ();
146: }
147:
148: static void
149: pop_braces (int to)
150: {
151: while (n_braces > to)
152: close_brace ();
153: }
154:
155: static int
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 *
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:
189: static __inline__ void gen_update_next_handler(void)
190: {
191: return; /* Can anything clever be done here? */
192: }
193:
194: static void gen_writebyte (char* address, char* source)
195: {
196: comprintf("\twritebyte(%s,%s,scratchie);\n",address,source);
197: }
198:
199: static void gen_writeword (char* address, char* source)
200: {
201: comprintf("\twriteword(%s,%s,scratchie);\n",address,source);
202: }
203:
204: static void gen_writelong (char* address, char* source)
205: {
206: comprintf("\twritelong(%s,%s,scratchie);\n",address,source);
207: }
208:
209: static void gen_readbyte (char* address, char* dest)
210: {
211: comprintf("\treadbyte(%s,%s,scratchie);\n",address,dest);
212: }
213:
214: static void gen_readword (char* address, char* dest)
215: {
216: comprintf("\treadword(%s,%s,scratchie);\n",address,dest);
217: }
218:
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 *
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 *
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 *
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
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
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
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: }
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
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
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
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
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
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 *
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
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 */
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
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
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
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
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.