|
|
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: {
1.1.1.2 ! root 265: comprintf("\t if (m68k_pc_offset>JIT_M68K_PC_SYNC) sync_m68k_pc();\n");
1.1 root 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);
1.1.1.2 ! root 717: if (table68k[opcode].size == sz_long)
! 718: comprintf("\tif (1 && !special_mem) {\n");
! 719: else
! 720: comprintf("\tif (1 && !special_mem) {\n");
1.1 root 721:
722: /* Fast but unsafe... */
1.1.1.2 ! root 723: comprintf("\t\tget_n_addr(srca,native,scratchie);\n");
1.1 root 724:
725:
1.1.1.2 ! root 726: comprintf("\t\tfor (i=0;i<16;i++) {\n"
! 727: "\t\t\tif ((mask>>i)&1) {\n");
1.1 root 728: switch(table68k[opcode].size) {
729: case sz_long:
1.1.1.2 ! root 730: comprintf("\t\t\t\tmov_l_rR(i,native,offset);\n"
! 731: "\t\t\t\tgen_bswap_32(i);\n"
! 732: "\t\t\t\toffset+=4;\n");
1.1 root 733: break;
734: case sz_word:
1.1.1.2 ! root 735: comprintf("\t\t\t\tmov_w_rR(i,native,offset);\n"
! 736: "\t\t\t\tgen_bswap_16(i);\n"
! 737: "\t\t\t\tsign_extend_16_rr(i,i);\n"
! 738: "\t\t\t\toffset+=2;\n");
1.1 root 739: break;
740: default: abort();
741: }
1.1.1.2 ! root 742: comprintf("\t\t\t}\n"
! 743: "\t\t}\n");
1.1 root 744: if (table68k[opcode].dmode == Aipi) {
1.1.1.2 ! root 745: comprintf("\t\tlea_l_brr(8+dstreg,srca,offset);\n");
1.1 root 746: }
747: /* End fast but unsafe. */
748:
749: comprintf("\t} else {\n");
750:
1.1.1.2 ! root 751: comprintf ("\t\tint tmp=scratchie++;\n");
1.1 root 752:
1.1.1.2 ! root 753: comprintf("\t\tmov_l_rr(tmp,srca);\n");
! 754: comprintf("\t\tfor (i=0;i<16;i++) {\n"
! 755: "\t\t\tif ((mask>>i)&1) {\n");
1.1 root 756: switch(table68k[opcode].size) {
757: case sz_long:
1.1.1.2 ! root 758: comprintf("\t\t\t\treadlong(tmp,i,scratchie);\n"
! 759: "\t\t\t\tadd_l_ri(tmp,4);\n");
1.1 root 760: break;
761: case sz_word:
1.1.1.2 ! root 762: comprintf("\t\t\t\treadword(tmp,i,scratchie);\n"
! 763: "\t\t\t\tadd_l_ri(tmp,2);\n");
1.1 root 764: break;
765: default: abort();
766: }
767:
1.1.1.2 ! root 768: comprintf("\t\t\t}\n"
! 769: "\t\t}\n");
1.1 root 770: if (table68k[opcode].dmode == Aipi) {
1.1.1.2 ! root 771: comprintf("\t\tmov_l_rr(8+dstreg,tmp);\n");
1.1 root 772: }
773: comprintf("\t}\n");
774:
775: }
776:
777:
778: static void
779: genmovemle (uae_u16 opcode)
780: {
781: comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ());
782: comprintf ("\tint native=scratchie++;\n");
783: comprintf ("\tint i;\n");
784: comprintf ("\tint tmp=scratchie++;\n");
785: comprintf ("\tsigned char offset=0;\n");
786: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
787:
788: /* *Sigh* Some clever geek realized that the fastest way to copy a
789: buffer from main memory to the gfx card is by using movmle. Good
790: on her, but unfortunately, gfx mem isn't "real" mem, and thus that
791: act of cleverness means that movmle must pay attention to special_mem,
792: or Genetic Species is a rather boring-looking game ;-) */
1.1.1.2 ! root 793: if (table68k[opcode].size == sz_long)
! 794: comprintf("\tif (1 && !special_mem) {\n");
! 795: else
! 796: comprintf("\tif (1 && !special_mem) {\n");
1.1 root 797: comprintf("\tget_n_addr(srca,native,scratchie);\n");
798:
799: if (table68k[opcode].dmode!=Apdi) {
800: comprintf("\tfor (i=0;i<16;i++) {\n"
801: "\t\tif ((mask>>i)&1) {\n");
802: switch(table68k[opcode].size) {
803: case sz_long:
804: comprintf("\t\t\tmov_l_rr(tmp,i);\n"
805: "\t\t\tgen_bswap_32(tmp);\n"
806: "\t\t\tmov_l_Rr(native,tmp,offset);\n"
807: "\t\t\toffset+=4;\n");
808: break;
809: case sz_word:
810: comprintf("\t\t\tmov_l_rr(tmp,i);\n"
811: "\t\t\tgen_bswap_16(tmp);\n"
812: "\t\t\tmov_w_Rr(native,tmp,offset);\n"
813: "\t\t\toffset+=2;\n");
814: break;
815: default: abort();
816: }
817: } else { /* Pre-decrement */
818: comprintf("\tfor (i=0;i<16;i++) {\n"
819: "\t\tif ((mask>>i)&1) {\n");
820: switch(table68k[opcode].size) {
821: case sz_long:
822: comprintf("\t\t\toffset-=4;\n"
823: "\t\t\tmov_l_rr(tmp,15-i);\n"
824: "\t\t\tgen_bswap_32(tmp);\n"
825: "\t\t\tmov_l_Rr(native,tmp,offset);\n"
826: );
827: break;
828: case sz_word:
829: comprintf("\t\t\toffset-=2;\n"
830: "\t\t\tmov_l_rr(tmp,15-i);\n"
831: "\t\t\tgen_bswap_16(tmp);\n"
832: "\t\t\tmov_w_Rr(native,tmp,offset);\n"
833: );
834: break;
835: default: abort();
836: }
837: }
838:
839: comprintf("\t\t}\n"
840: "\t}");
841: if (table68k[opcode].dmode == Apdi) {
842: comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n");
843: }
844: comprintf("\t} else {\n");
845:
846: if (table68k[opcode].dmode!=Apdi) {
847: comprintf("\tmov_l_rr(tmp,srca);\n");
848: comprintf("\tfor (i=0;i<16;i++) {\n"
849: "\t\tif ((mask>>i)&1) {\n");
850: switch(table68k[opcode].size) {
851: case sz_long:
852: comprintf("\t\t\twritelong(tmp,i,scratchie);\n"
853: "\t\t\tadd_l_ri(tmp,4);\n");
854: break;
855: case sz_word:
856: comprintf("\t\t\twriteword(tmp,i,scratchie);\n"
857: "\t\t\tadd_l_ri(tmp,2);\n");
858: break;
859: default: abort();
860: }
861: }
862: else { /* Pre-decrement */
863: comprintf("\tfor (i=0;i<16;i++) {\n"
864: "\t\tif ((mask>>i)&1) {\n");
865: switch(table68k[opcode].size) {
866: case sz_long:
867: comprintf("\t\t\tsub_l_ri(srca,4);\n"
868: "\t\t\twritelong(srca,15-i,scratchie);\n");
869: break;
870: case sz_word:
871: comprintf("\t\t\tsub_l_ri(srca,2);\n"
872: "\t\t\twriteword(srca,15-i,scratchie);\n");
873: break;
874: default: abort();
875: }
876: }
877:
878:
879: comprintf("\t\t}\n"
880: "\t}");
881: if (table68k[opcode].dmode == Apdi) {
882: comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n");
883: }
884: comprintf("\t}\n");
885: }
886:
887:
888: static void
889: duplicate_carry (void)
890: {
891: comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n");
892: }
893:
894: typedef enum
895: {
896: flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp,
897: flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or,
898: flag_eor, flag_mov
899: }
900: flagtypes;
901:
902:
903: static void
904: genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst)
905: {
906: if (noflags) {
907: switch(type) {
908: case flag_cmp:
909: comprintf("\tdont_care_flags();\n");
910: comprintf("/* Weird --- CMP with noflags ;-) */\n");
911: return;
912: case flag_add:
913: case flag_sub:
914: comprintf("\tdont_care_flags();\n");
915: {
916: char* op;
917: switch(type) {
918: case flag_add: op="add"; break;
919: case flag_sub: op="sub"; break;
920: default: abort();
921: }
922: switch (size)
923: {
924: case sz_byte:
925: comprintf("\t%s_b(%s,%s);\n",op,dst,src);
926: break;
927: case sz_word:
928: comprintf("\t%s_w(%s,%s);\n",op,dst,src);
929: break;
930: case sz_long:
931: comprintf("\t%s_l(%s,%s);\n",op,dst,src);
932: break;
933: }
934: return;
935: }
936: break;
937:
938: case flag_and:
939: comprintf("\tdont_care_flags();\n");
940: switch (size)
941: {
942: case sz_byte:
943: comprintf("if (kill_rodent(dst)) {\n");
944: comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
945: comprintf("\tor_l_ri(scratchie,0xffffff00);\n");
946: comprintf("\tand_l(%s,scratchie);\n",dst);
947: comprintf("\tforget_about(scratchie);\n");
948: comprintf("\t} else \n"
949: "\tand_b(%s,%s);\n",dst,src);
950: break;
951: case sz_word:
952: comprintf("if (kill_rodent(dst)) {\n");
953: comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
954: comprintf("\tor_l_ri(scratchie,0xffff0000);\n");
955: comprintf("\tand_l(%s,scratchie);\n",dst);
956: comprintf("\tforget_about(scratchie);\n");
957: comprintf("\t} else \n"
958: "\tand_w(%s,%s);\n",dst,src);
959: break;
960: case sz_long:
961: comprintf("\tand_l(%s,%s);\n",dst,src);
962: break;
963: }
964: return;
965:
966: case flag_mov:
967: comprintf("\tdont_care_flags();\n");
968: switch (size)
969: {
970: case sz_byte:
971: comprintf("if (kill_rodent(dst)) {\n");
972: comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
973: comprintf("\tand_l_ri(%s,0xffffff00);\n",dst);
974: comprintf("\tor_l(%s,scratchie);\n",dst);
975: comprintf("\tforget_about(scratchie);\n");
976: comprintf("\t} else \n"
977: "\tmov_b_rr(%s,%s);\n",dst,src);
978: break;
979: case sz_word:
980: comprintf("if (kill_rodent(dst)) {\n");
981: comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
982: comprintf("\tand_l_ri(%s,0xffff0000);\n",dst);
983: comprintf("\tor_l(%s,scratchie);\n",dst);
984: comprintf("\tforget_about(scratchie);\n");
985: comprintf("\t} else \n"
986: "\tmov_w_rr(%s,%s);\n",dst,src);
987: break;
988: case sz_long:
989: comprintf("\tmov_l_rr(%s,%s);\n",dst,src);
990: break;
991: }
992: return;
993:
994: case flag_or:
995: case flag_eor:
996: comprintf("\tdont_care_flags();\n");
997: start_brace();
998: {
999: char* op;
1000: switch(type) {
1001: case flag_or: op="or"; break;
1002: case flag_eor: op="xor"; break;
1003: default: abort();
1004: }
1005: switch (size)
1006: {
1007: case sz_byte:
1008: comprintf("if (kill_rodent(dst)) {\n");
1009: comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src);
1010: comprintf("\t%s_l(%s,scratchie);\n",op,dst);
1011: comprintf("\tforget_about(scratchie);\n");
1012: comprintf("\t} else \n"
1013: "\t%s_b(%s,%s);\n",op,dst,src);
1014: break;
1015: case sz_word:
1016: comprintf("if (kill_rodent(dst)) {\n");
1017: comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src);
1018: comprintf("\t%s_l(%s,scratchie);\n",op,dst);
1019: comprintf("\tforget_about(scratchie);\n");
1020: comprintf("\t} else \n"
1021: "\t%s_w(%s,%s);\n",op,dst,src);
1022: break;
1023: case sz_long:
1024: comprintf("\t%s_l(%s,%s);\n",op,dst,src);
1025: break;
1026: }
1027: close_brace();
1028: return;
1029: }
1030:
1031:
1032: case flag_addx:
1033: case flag_subx:
1034:
1035: comprintf("\tdont_care_flags();\n");
1036: {
1037: char* op;
1038: switch(type) {
1039: case flag_addx: op="adc"; break;
1040: case flag_subx: op="sbb"; break;
1041: default: abort();
1042: }
1043: comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
1044: switch (size)
1045: {
1046: case sz_byte:
1047: comprintf("\t%s_b(%s,%s);\n",op,dst,src);
1048: break;
1049: case sz_word:
1050: comprintf("\t%s_w(%s,%s);\n",op,dst,src);
1051: break;
1052: case sz_long:
1053: comprintf("\t%s_l(%s,%s);\n",op,dst,src);
1054: break;
1055: }
1056: return;
1057: }
1058: break;
1059: default: return;
1060: }
1061: }
1062:
1063: /* Need the flags, but possibly not all of them */
1064: switch (type)
1065: {
1066: case flag_logical_noclobber:
1067: failure;
1068:
1069: case flag_and:
1070: case flag_or:
1071: case flag_eor:
1072: comprintf("\tdont_care_flags();\n");
1073: start_brace();
1074: {
1075: char* op;
1076: switch(type) {
1077: case flag_and: op="and"; break;
1078: case flag_or: op="or"; break;
1079: case flag_eor: op="xor"; break;
1080: default: abort();
1081: }
1082: switch (size)
1083: {
1084: case sz_byte:
1085: comprintf("\tstart_needflags();\n"
1086: "\t%s_b(%s,%s);\n",op,dst,src);
1087: break;
1088: case sz_word:
1089: comprintf("\tstart_needflags();\n"
1090: "\t%s_w(%s,%s);\n",op,dst,src);
1091: break;
1092: case sz_long:
1093: comprintf("\tstart_needflags();\n"
1094: "\t%s_l(%s,%s);\n",op,dst,src);
1095: break;
1096: }
1097: comprintf("\tlive_flags();\n");
1098: comprintf("\tend_needflags();\n");
1099: close_brace();
1100: return;
1101: }
1102:
1103: case flag_mov:
1104: comprintf("\tdont_care_flags();\n");
1105: start_brace();
1106: {
1107: switch (size)
1108: {
1109: case sz_byte:
1110: comprintf("\tif (%s!=%s) {\n",src,dst);
1111: comprintf("\tmov_b_ri(%s,0);\n"
1112: "\tstart_needflags();\n",dst);
1113: comprintf("\tor_b(%s,%s);\n",dst,src);
1114: comprintf("\t} else {\n");
1115: comprintf("\tmov_b_rr(%s,%s);\n",dst,src);
1116: comprintf("\ttest_b_rr(%s,%s);\n",dst,dst);
1117: comprintf("\t}\n");
1118: break;
1119: case sz_word:
1120: comprintf("\tif (%s!=%s) {\n",src,dst);
1121: comprintf("\tmov_w_ri(%s,0);\n"
1122: "\tstart_needflags();\n",dst);
1123: comprintf("\tor_w(%s,%s);\n",dst,src);
1124: comprintf("\t} else {\n");
1125: comprintf("\tmov_w_rr(%s,%s);\n",dst,src);
1126: comprintf("\ttest_w_rr(%s,%s);\n",dst,dst);
1127: comprintf("\t}\n");
1128: break;
1129: case sz_long:
1130: comprintf("\tif (%s!=%s) {\n",src,dst);
1131: comprintf("\tmov_l_ri(%s,0);\n"
1132: "\tstart_needflags();\n",dst);
1133: comprintf("\tor_l(%s,%s);\n",dst,src);
1134: comprintf("\t} else {\n");
1135: comprintf("\tmov_l_rr(%s,%s);\n",dst,src);
1136: comprintf("\ttest_l_rr(%s,%s);\n",dst,dst);
1137: comprintf("\t}\n");
1138: break;
1139: }
1140: comprintf("\tlive_flags();\n");
1141: comprintf("\tend_needflags();\n");
1142: close_brace();
1143: return;
1144: }
1145:
1146: case flag_logical:
1147: comprintf("\tdont_care_flags();\n");
1148: start_brace();
1149: switch (size)
1150: {
1151: case sz_byte:
1152: comprintf("\tstart_needflags();\n"
1153: "\ttest_b_rr(%s,%s);\n",value,value);
1154: break;
1155: case sz_word:
1156: comprintf("\tstart_needflags();\n"
1157: "\ttest_w_rr(%s,%s);\n",value,value);
1158: break;
1159: case sz_long:
1160: comprintf("\tstart_needflags();\n"
1161: "\ttest_l_rr(%s,%s);\n",value,value);
1162: break;
1163: }
1164: comprintf("\tlive_flags();\n");
1165: comprintf("\tend_needflags();\n");
1166: close_brace();
1167: return;
1168:
1169:
1170: case flag_add:
1171: case flag_sub:
1172: case flag_cmp:
1173: comprintf("\tdont_care_flags();\n");
1174: {
1175: char* op;
1176: switch(type) {
1177: case flag_add: op="add"; break;
1178: case flag_sub: op="sub"; break;
1179: case flag_cmp: op="cmp"; break;
1180: default: abort();
1181: }
1182: switch (size)
1183: {
1184: case sz_byte:
1185: comprintf("\tstart_needflags();\n"
1186: "\t%s_b(%s,%s);\n",op,dst,src);
1187: break;
1188: case sz_word:
1189: comprintf("\tstart_needflags();\n"
1190: "\t%s_w(%s,%s);\n",op,dst,src);
1191: break;
1192: case sz_long:
1193: comprintf("\tstart_needflags();\n"
1194: "\t%s_l(%s,%s);\n",op,dst,src);
1195: break;
1196: }
1197: comprintf("\tlive_flags();\n");
1198: comprintf("\tend_needflags();\n");
1199: if (type!=flag_cmp) {
1200: duplicate_carry();
1201: }
1202: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
1203:
1204: return;
1205: }
1206:
1207: case flag_addx:
1208: case flag_subx:
1209: uses_cmov;
1210: comprintf("\tdont_care_flags();\n");
1211: {
1212: char* op;
1213: switch(type) {
1214: case flag_addx: op="adc"; break;
1215: case flag_subx: op="sbb"; break;
1216: default: abort();
1217: }
1218: start_brace();
1219: comprintf("\tint zero=scratchie++;\n"
1220: "\tint one=scratchie++;\n"
1221: "\tif (needed_flags&FLAG_Z) {\n"
1222: "\tmov_l_ri(zero,0);\n"
1223: "\tmov_l_ri(one,1);\n"
1224: "\tmake_flags_live();\n"
1225: "\tcmov_l_rr(zero,one,5);\n"
1226: "\t}\n");
1227: comprintf("\trestore_carry();\n"); /* Reload the X flag into C */
1228: switch (size)
1229: {
1230: case sz_byte:
1231: comprintf("\tstart_needflags();\n"
1232: "\t%s_b(%s,%s);\n",op,dst,src);
1233: break;
1234: case sz_word:
1235: comprintf("\tstart_needflags();\n"
1236: "\t%s_w(%s,%s);\n",op,dst,src);
1237: break;
1238: case sz_long:
1239: comprintf("\tstart_needflags();\n"
1240: "\t%s_l(%s,%s);\n",op,dst,src);
1241: break;
1242: }
1243: comprintf("\tlive_flags();\n");
1244: comprintf("\tif (needed_flags&FLAG_Z) {\n"
1245: "\tcmov_l_rr(zero,one,5);\n"
1246: "\tsetzflg_l(zero);\n"
1247: "\tlive_flags();\n"
1248: "\t}\n");
1249: comprintf("\tend_needflags();\n");
1250: duplicate_carry();
1251: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
1252: return;
1253: }
1254: default:
1255: failure;
1256: break;
1257: }
1258: }
1259:
1260: static void
1261: force_range_for_rox (const char *var, wordsizes size)
1262: {
1263: /* Could do a modulo operation here... which one is faster? */
1264: switch (size)
1265: {
1266: case sz_long:
1267: comprintf ("\tif (%s >= 33) %s -= 33;\n", var, var);
1268: break;
1269: case sz_word:
1270: comprintf ("\tif (%s >= 34) %s -= 34;\n", var, var);
1271: comprintf ("\tif (%s >= 17) %s -= 17;\n", var, var);
1272: break;
1273: case sz_byte:
1274: comprintf ("\tif (%s >= 36) %s -= 36;\n", var, var);
1275: comprintf ("\tif (%s >= 18) %s -= 18;\n", var, var);
1276: comprintf ("\tif (%s >= 9) %s -= 9;\n", var, var);
1277: break;
1278: }
1279: }
1280:
1281: static const char *
1282: cmask (wordsizes size)
1283: {
1284: switch (size)
1285: {
1286: case sz_byte:
1287: return "0x80";
1288: case sz_word:
1289: return "0x8000";
1290: case sz_long:
1291: return "0x80000000";
1292: default:
1293: abort ();
1294: }
1295: }
1296:
1297: static int
1298: source_is_imm1_8 (struct instr *i)
1299: {
1300: return i->stype == 3;
1301: }
1302:
1303: static int /* returns zero for success, non-zero for failure */
1304: gen_opcode (unsigned long int opcode)
1305: {
1306: struct instr *curi = table68k + opcode;
1307: char* ssize=NULL;
1308:
1309: insn_n_cycles = 2;
1310: global_failure=0;
1311: long_opcode=0;
1312: global_isjump=0;
1313: global_iscjump=0;
1314: global_isaddx=0;
1315: global_cmov=0;
1316: global_mayfail=0;
1317: hack_opcode=opcode;
1318: endstr[0]=0;
1319:
1320: start_brace ();
1321: comprintf("\tuae_u8 scratchie=S1;\n");
1322: switch (curi->plev)
1323: {
1324: case 0: /* not privileged */
1325: break;
1326: case 1: /* unprivileged only on 68000 */
1327: if (cpu_level == 0)
1328: break;
1329: if (next_cpu_level < 0)
1330: next_cpu_level = 0;
1331:
1332: /* fall through */
1333: case 2: /* priviledged */
1334: failure; /* Easy ones first */
1335: break;
1336: case 3: /* privileged if size == word */
1337: if (curi->size == sz_byte)
1338: break;
1339: failure;
1340: break;
1341: }
1342: switch (curi->size) {
1343: case sz_byte: ssize="b"; break;
1344: case sz_word: ssize="w"; break;
1345: case sz_long: ssize="l"; break;
1346: default: abort();
1347: }
1348:
1349: switch (curi->mnemo)
1350: {
1351: case i_OR:
1352: case i_AND:
1353: case i_EOR:
1354: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1355: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1356: switch(curi->mnemo) {
1357: case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break;
1358: case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break;
1359: case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break;
1360: }
1361: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1362: break;
1363:
1364: case i_ORSR:
1365: case i_EORSR:
1366: failure;
1367: isjump;
1368: break;
1369: case i_ANDSR:
1370: failure;
1371: isjump;
1372: break;
1373: case i_SUB:
1374: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1375: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1376: genflags (flag_sub, curi->size, "", "src", "dst");
1377: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1378: break;
1379: case i_SUBA:
1380: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1381: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1382: start_brace();
1383: comprintf("\tint tmp=scratchie++;\n");
1384: switch(curi->size) {
1385: case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
1386: case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
1387: case sz_long: comprintf("\ttmp=src;\n"); break;
1388: default: abort();
1389: }
1390: comprintf("\tsub_l(dst,tmp);\n");
1391: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1392: break;
1393: case i_SUBX:
1394: isaddx;
1395: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1396: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1397: genflags (flag_subx, curi->size, "", "src", "dst");
1398: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1399: break;
1400: case i_SBCD:
1401: failure;
1402: /* I don't think so! */
1403: break;
1404: case i_ADD:
1405: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1406: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1407: genflags (flag_add, curi->size, "", "src", "dst");
1408: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1409: break;
1410: case i_ADDA:
1411: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1412: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1413: start_brace();
1414: comprintf("\tint tmp=scratchie++;\n");
1415: switch(curi->size) {
1416: case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
1417: case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
1418: case sz_long: comprintf("\ttmp=src;\n"); break;
1419: default: abort();
1420: }
1421: comprintf("\tadd_l(dst,tmp);\n");
1422: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1423: break;
1424: case i_ADDX:
1425: isaddx;
1426: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1427: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1428: start_brace();
1429: genflags (flag_addx, curi->size, "", "src", "dst");
1430: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1431: break;
1432: case i_ABCD:
1433: failure;
1434: /* No BCD maths for me.... */
1435: break;
1436: case i_NEG:
1437: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1438: start_brace ();
1439: comprintf("\tint dst=scratchie++;\n");
1440: comprintf("\tmov_l_ri(dst,0);\n");
1441: genflags (flag_sub, curi->size, "", "src", "dst");
1442: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1443: break;
1444: case i_NEGX:
1445: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1446: start_brace ();
1447: comprintf("\tint dst=scratchie++;\n");
1448: comprintf("\tmov_l_ri(dst,0);\n");
1449: genflags (flag_subx, curi->size, "", "src", "dst");
1450: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1451: break;
1452:
1453: case i_NBCD:
1454: failure;
1455: /* Nope! */
1456: break;
1457: case i_CLR:
1458: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1459: start_brace();
1460: comprintf("\tint dst=scratchie++;\n");
1461: comprintf("\tmov_l_ri(dst,0);\n");
1462: genflags (flag_logical, curi->size, "dst", "", "");
1463: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1464: break;
1465: case i_NOT:
1466: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1467: start_brace ();
1468: comprintf("\tint dst=scratchie++;\n");
1469: comprintf("\tmov_l_ri(dst,0xffffffff);\n");
1470: genflags (flag_eor, curi->size, "", "src", "dst");
1471: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1472: break;
1473: case i_TST:
1474: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1475: genflags (flag_logical, curi->size, "src", "", "");
1476: break;
1477: case i_BCHG:
1478: case i_BCLR:
1479: case i_BSET:
1480: case i_BTST:
1481: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1482: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1483: start_brace();
1484: comprintf("\tint s=scratchie++;\n"
1485: "\tmov_l_rr(s,src);\n");
1486: if (curi->size == sz_byte)
1487: comprintf("\tand_l_ri(s,7);\n");
1488: else
1489: comprintf("\tand_l_ri(s,31);\n");
1490:
1491: {
1492: char* op;
1493: int need_write=1;
1494:
1495: switch(curi->mnemo) {
1496: case i_BCHG: op="btc"; break;
1497: case i_BCLR: op="btr"; break;
1498: case i_BSET: op="bts"; break;
1499: case i_BTST: op="bt"; need_write=0; break;
1500: }
1501: comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */
1502: "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */
1503: "\tmake_flags_live();\n" /* Get the flags back */
1504: "\tdont_care_flags();\n",op);
1505: if (!noflags) {
1506: comprintf("\tstart_needflags();\n"
1507: "\tsetzflg_l(s);\n"
1508: "\tlive_flags();\n"
1509: "\tend_needflags();\n");
1510: }
1511: if (need_write)
1512: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1513: }
1514: break;
1515: /*if (!noflags) {
1516: failure;
1517: break;
1518: }
1519: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1520: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1521: start_brace();
1522: comprintf("\tint s=scratchie++;\n"
1523: "\tmov_l_rr(s,src);\n");
1524: if (curi->size == sz_byte)
1525: comprintf("\tand_l_ri(s,7);\n");
1526: else
1527: comprintf("\tand_l_ri(s,31);\n");
1528:
1529: {
1530: char* op;
1531: int need_write=1;
1532:
1533: switch(curi->mnemo) {
1534: case i_BCHG: op="btc"; break;
1535: case i_BCLR: op="btr"; break;
1536: case i_BSET: op="bts"; break;
1537: case i_BTST: op="bt"; need_write=0; break;
1538: }
1539: comprintf("\t%s_l_rr(dst,s);\n" // Answer now in C
1540: "\tsbb_l(s,s);\n" // s is 0 if bit was 0, -1 otherwise
1541: "\tmake_flags_live();\n" // Get the flags back
1542: "\tdont_care_flags();\n"
1543: "\tstart_needflags();\n"
1544: "\tbsf_l_rr(s,s);\n"
1545: "\tlive_flags();\n"
1546: "\tend_needflags();\n",op);
1547: if (need_write)
1548: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1549: }
1550: break;
1551: */
1552: case i_CMPM:
1553: case i_CMP:
1554: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1555: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1556: start_brace ();
1557: genflags (flag_cmp, curi->size, "", "src", "dst");
1558: break;
1559: case i_CMPA:
1560: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1561: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1562: start_brace();
1563: comprintf("\tint tmps=scratchie++;\n");
1564: switch(curi->size) {
1565: case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break;
1566: case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break;
1567: case sz_long: comprintf("tmps=src;\n"); break;
1568: default: abort();
1569: }
1570: genflags (flag_cmp, sz_long, "", "tmps", "dst");
1571: break;
1572: /* The next two are coded a little unconventional, but they are doing
1573: * weird things... */
1574: case i_MVPRM:
1575: isjump;
1576: failure;
1577: break;
1578: case i_MVPMR:
1579: isjump;
1580: failure;
1581: break;
1582: case i_MOVE:
1583: switch(curi->dmode) {
1584: case Dreg:
1585: case Areg:
1586: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1587: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1588: genflags (flag_mov, curi->size, "", "src", "dst");
1589: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1590: break;
1591: default: /* It goes to memory, not a register */
1592: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1593: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1594: genflags (flag_logical, curi->size, "src", "", "");
1595: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1596: break;
1597: }
1598: break;
1599: case i_MOVEA:
1600: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1601: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1602:
1603: start_brace();
1604: comprintf("\tint tmps=scratchie++;\n");
1605: switch(curi->size) {
1606: case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break;
1607: case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break;
1608: default: abort();
1609: }
1610: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1611: break;
1612:
1613: case i_MVSR2:
1614: isjump;
1615: failure;
1616: break;
1617: case i_MV2SR:
1618: isjump;
1619: failure;
1620: break;
1621: case i_SWAP:
1622: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1623: comprintf("\tdont_care_flags();\n");
1624: comprintf("\trol_l_ri(src,16);\n");
1625: genflags (flag_logical, sz_long, "src", "", "");
1626: genastore ("src", curi->smode, "srcreg", sz_long, "src");
1627: break;
1628: case i_EXG:
1629: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1630: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1631: start_brace();
1632: comprintf("\tint tmp=scratchie++;\n"
1633: "\tmov_l_rr(tmp,src);\n");
1634: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1635: genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst");
1636: break;
1637: case i_EXT:
1638: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1639: comprintf("\tdont_care_flags();\n");
1640: start_brace ();
1641: switch (curi->size)
1642: {
1643: case sz_byte:
1644: comprintf ("\tint dst = src;\n"
1645: "\tsign_extend_8_rr(src,src);\n");
1646: break;
1647: case sz_word:
1648: comprintf ("\tint dst = scratchie++;\n"
1649: "\tsign_extend_8_rr(dst,src);\n");
1650: break;
1651: case sz_long:
1652: comprintf ("\tint dst = src;\n"
1653: "\tsign_extend_16_rr(src,src);\n");
1654: break;
1655: default:
1656: abort ();
1657: }
1658: genflags (flag_logical,
1659: curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
1660: genastore ("dst", curi->smode, "srcreg",
1661: curi->size == sz_word ? sz_word : sz_long, "src");
1662: break;
1663: case i_MVMEL:
1664: genmovemel (opcode);
1665: break;
1666: case i_MVMLE:
1667: genmovemle (opcode);
1668: break;
1669: case i_TRAP:
1670: isjump;
1671: failure;
1672: break;
1673: case i_MVR2USP:
1674: isjump;
1675: failure;
1676: break;
1677: case i_MVUSP2R:
1678: isjump;
1679: failure;
1680: break;
1681: case i_RESET:
1682: isjump;
1683: failure;
1684: break;
1685: case i_NOP:
1686: break;
1687: case i_STOP:
1688: isjump;
1689: failure;
1690: break;
1691: case i_RTE:
1692: isjump;
1693: failure;
1694: break;
1695: case i_RTD:
1696: genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0);
1697: /* offs is constant */
1698: comprintf("\tadd_l_ri(offs,4);\n");
1699: start_brace();
1700: comprintf("\tint newad=scratchie++;\n"
1701: "\treadlong(15,newad,scratchie);\n"
1702: "\tand_l_ri(newad,~1);\n"
1703: "\tmov_l_mr((uae_u32)®s.pc,newad);\n"
1704: "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1705: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n"
1706: "\tm68k_pc_offset=0;\n"
1707: "\tadd_l(15,offs);\n");
1708: gen_update_next_handler();
1709: isjump;
1710: break;
1711: case i_LINK:
1712: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1713: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1714: comprintf("\tsub_l_ri(15,4);\n"
1715: "\twritelong_clobber(15,src,scratchie);\n"
1716: "\tmov_l_rr(src,15);\n");
1717: if (curi->size==sz_word)
1718: comprintf("\tsign_extend_16_rr(offs,offs);\n");
1719: comprintf("\tadd_l(15,offs);\n");
1720: genastore ("src", curi->smode, "srcreg", sz_long, "src");
1721: break;
1722: case i_UNLK:
1723: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1724: comprintf("\tmov_l_rr(15,src);\n"
1725: "\treadlong(15,src,scratchie);\n"
1726: "\tadd_l_ri(15,4);\n");
1727: genastore ("src", curi->smode, "srcreg", curi->size, "src");
1728: break;
1729: case i_RTS:
1730: comprintf("\tint newad=scratchie++;\n"
1731: "\treadlong(15,newad,scratchie);\n"
1732: "\tand_l_ri(newad,~1);\n"
1733: "\tmov_l_mr((uae_u32)®s.pc,newad);\n"
1734: "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1735: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n"
1736: "\tm68k_pc_offset=0;\n"
1737: "\tlea_l_brr(15,15,4);\n");
1738: gen_update_next_handler();
1739: isjump;
1740: break;
1741: case i_TRAPV:
1742: isjump;
1743: failure;
1744: break;
1745: case i_RTR:
1746: isjump;
1747: failure;
1748: break;
1749: case i_JSR:
1750: isjump;
1751: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1752: start_brace();
1753: comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
1754: comprintf("\tint ret=scratchie++;\n"
1755: "\tmov_l_ri(ret,retadd);\n"
1756: "\tsub_l_ri(15,4);\n"
1757: "\twritelong_clobber(15,ret,scratchie);\n");
1758: comprintf("\tand_l_ri(srca,~1);\n"
1759: "\tmov_l_mr((uae_u32)®s.pc,srca);\n"
1760: "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1761: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n"
1762: "\tm68k_pc_offset=0;\n");
1763: gen_update_next_handler();
1764: break;
1765: case i_JMP:
1766: isjump;
1767: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1768: comprintf("\tand_l_ri(srca,~1);\n"
1769: "\tmov_l_mr((uae_u32)®s.pc,srca);\n"
1770: "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1771: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n"
1772: "\tm68k_pc_offset=0;\n");
1773: gen_update_next_handler();
1774: break;
1775: case i_BSR:
1776: if (curi->size==sz_long)
1777: failure;
1778: is_const_jump;
1779: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1780: comprintf("\tand_l_ri(src,~1);\n");
1781: start_brace();
1782: comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
1783: comprintf("\tint ret=scratchie++;\n"
1784: "\tmov_l_ri(ret,retadd);\n"
1785: "\tsub_l_ri(15,4);\n"
1786: "\twritelong_clobber(15,ret,scratchie);\n");
1787: comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n");
1788: comprintf("\tm68k_pc_offset=0;\n");
1789: comprintf("\tadd_l(PC_P,src);\n");
1790:
1791: comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n");
1792: break;
1793: case i_Bcc:
1794: comprintf("\tuae_u32 v1,v2;\n");
1795: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1796: /* That source is an immediate, so we can clobber it with abandon */
1797: switch(curi->size) {
1798: case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break;
1799: case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break;
1800: case sz_long: break;
1801: }
1802: comprintf("\tand_l_ri(src,~1);\n");
1803: comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
1804: /* Leave the following as "add" --- it will allow it to be optimized
1805: away due to src being a constant ;-) */
1806: comprintf("\tadd_l_ri(src,(uae_u32)comp_pc_p);\n");
1807: comprintf("\tmov_l_ri(PC_P,(uae_u32)comp_pc_p);\n");
1808: /* Now they are both constant. Might as well fold in m68k_pc_offset */
1809: comprintf("\tadd_l_ri(src,m68k_pc_offset);\n");
1810: comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
1811: comprintf("\tm68k_pc_offset=0;\n");
1812:
1813: if (curi->cc>=2) {
1814: comprintf("\tv1=get_const(PC_P);\n"
1815: "\tv2=get_const(src);\n"
1816: "\tregister_branch(v1,v2,%d);\n",
1817: cond_codes_x86[curi->cc]);
1818: comprintf("\tmake_flags_live();\n"); /* Load the flags */
1819: isjump;
1820: }
1821: else {
1822: is_const_jump;
1823: }
1824:
1825: switch(curi->cc) {
1826: case 0: /* Unconditional jump */
1827: comprintf("\tmov_l_rr(PC_P,src);\n");
1828: comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n");
1829: break;
1830: case 1: break; /* This is silly! */
1831: case 8: failure; break; /* Work out details! FIXME */
1832: case 9: failure; break; /* Not critical, though! */
1833:
1834: case 2:
1835: case 3:
1836: case 4:
1837: case 5:
1838: case 6:
1839: case 7:
1840: case 10:
1841: case 11:
1842: case 12:
1843: case 13:
1844: case 14:
1845: case 15:
1846: break;
1847: default: abort();
1848: }
1849: break;
1850: case i_LEA:
1851: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1852: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1853: genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
1854: break;
1855: case i_PEA:
1856: if (table68k[opcode].smode==Areg ||
1857: table68k[opcode].smode==Aind ||
1858: table68k[opcode].smode==Aipi ||
1859: table68k[opcode].smode==Apdi ||
1860: table68k[opcode].smode==Ad16 ||
1861: table68k[opcode].smode==Ad8r)
1862: comprintf("if (srcreg==7) dodgy=1;\n");
1863:
1864: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1865: genamode (Apdi, "7", sz_long, "dst", 2, 0);
1866: genastore ("srca", Apdi, "7", sz_long, "dst");
1867: break;
1868: case i_DBcc:
1869: isjump;
1870: uses_cmov;
1871: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1872: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1873:
1874: /* That offs is an immediate, so we can clobber it with abandon */
1875: switch(curi->size) {
1876: case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break;
1877: default: abort(); /* Seems this only comes in word flavour */
1878: }
1879: comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
1880: comprintf("\tadd_l_ri(offs,(uae_u32)comp_pc_p);\n"); /* New PC,
1881: once the
1882: offset_68k is
1883: * also added */
1884: /* Let's fold in the m68k_pc_offset at this point */
1885: comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n");
1886: comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
1887: comprintf("\tm68k_pc_offset=0;\n");
1888:
1889: start_brace();
1890: comprintf("\tint nsrc=scratchie++;\n");
1891:
1892: if (curi->cc>=2) {
1893: comprintf("\tmake_flags_live();\n"); /* Load the flags */
1894: }
1895:
1896: if (curi->size!=sz_word)
1897: abort();
1898:
1899:
1900: switch(curi->cc) {
1901: case 0: /* This is an elaborate nop? */
1902: break;
1903: case 1:
1904: comprintf("\tstart_needflags();\n");
1905: comprintf("\tsub_w_ri(src,1);\n");
1906: comprintf("\t end_needflags();\n");
1907: start_brace();
1908: comprintf("\tuae_u32 v2;\n"
1909: "\tuae_u32 v1=get_const(PC_P);\n");
1910: comprintf("\tv2=get_const(offs);\n"
1911: "\tregister_branch(v1,v2,3);\n");
1912: break;
1913:
1914: case 8: failure; break; /* Work out details! FIXME */
1915: case 9: failure; break; /* Not critical, though! */
1916:
1917: case 2:
1918: case 3:
1919: case 4:
1920: case 5:
1921: case 6:
1922: case 7:
1923: case 10:
1924: case 11:
1925: case 12:
1926: case 13:
1927: case 14:
1928: case 15:
1929: comprintf("\tmov_l_rr(nsrc,src);\n");
1930: comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n"
1931: "\tmov_w_rr(src,scratchie);\n");
1932: comprintf("\tcmov_l_rr(offs,PC_P,%d);\n",
1933: cond_codes_x86[curi->cc]);
1934: comprintf("\tcmov_l_rr(src,nsrc,%d);\n",
1935: cond_codes_x86[curi->cc]);
1936: /* OK, now for cc=true, we have src==nsrc and offs==PC_P,
1937: so whether we move them around doesn't matter. However,
1938: if cc=false, we have offs==jump_pc, and src==nsrc-1 */
1939:
1940: comprintf("\t start_needflags();\n");
1941: comprintf("\ttest_w_rr(nsrc,nsrc);\n");
1942: comprintf("\t end_needflags();\n");
1943: comprintf("\tcmov_l_rr(PC_P,offs,5);\n");
1944: break;
1945: default: abort();
1946: }
1947: genastore ("src", curi->smode, "srcreg", curi->size, "src");
1948: gen_update_next_handler();
1949: break;
1950:
1951: case i_Scc:
1952: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1953: start_brace ();
1954: comprintf ("\tint val = scratchie++;\n");
1955:
1956: /* We set val to 0 if we really should use 255, and to 1 for real 0 */
1957: switch(curi->cc) {
1958: case 0: /* Unconditional set */
1959: comprintf("\tmov_l_ri(val,0);\n");
1960: break;
1961: case 1:
1962: /* Unconditional not-set */
1963: comprintf("\tmov_l_ri(val,1);\n");
1964: break;
1965: case 8: failure; break; /* Work out details! FIXME */
1966: case 9: failure; break; /* Not critical, though! */
1967:
1968: case 2:
1969: case 3:
1970: case 4:
1971: case 5:
1972: case 6:
1973: case 7:
1974: case 10:
1975: case 11:
1976: case 12:
1977: case 13:
1978: case 14:
1979: case 15:
1980: comprintf("\tmake_flags_live();\n"); /* Load the flags */
1981: /* All condition codes can be inverted by changing the LSB */
1982: comprintf("\tsetcc(val,%d);\n",
1983: cond_codes_x86[curi->cc]^1); break;
1984: default: abort();
1985: }
1986: comprintf("\tsub_b_ri(val,1);\n");
1987: genastore ("val", curi->smode, "srcreg", curi->size, "src");
1988: break;
1989: case i_DIVU:
1990: isjump;
1991: failure;
1992: break;
1993: case i_DIVS:
1994: isjump;
1995: failure;
1996: break;
1997: case i_MULU:
1998: comprintf("\tdont_care_flags();\n");
1999: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
2000: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
2001: /* To do 16x16 unsigned multiplication, we actually use
2002: 32x32 signed, and zero-extend the registers first.
2003: That solves the problem of MUL needing dedicated registers
2004: on the x86 */
2005: comprintf("\tzero_extend_16_rr(scratchie,src);\n"
2006: "\tzero_extend_16_rr(dst,dst);\n"
2007: "\timul_32_32(dst,scratchie);\n");
2008: genflags (flag_logical, sz_long, "dst", "", "");
2009: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
2010: break;
2011: case i_MULS:
2012: comprintf("\tdont_care_flags();\n");
2013: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
2014: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
2015: comprintf("\tsign_extend_16_rr(scratchie,src);\n"
2016: "\tsign_extend_16_rr(dst,dst);\n"
2017: "\timul_32_32(dst,scratchie);\n");
2018: genflags (flag_logical, sz_long, "dst", "", "");
2019: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
2020: break;
2021: case i_CHK:
2022: isjump;
2023: failure;
2024: break;
2025:
2026: case i_CHK2:
2027: isjump;
2028: failure;
2029: break;
2030:
2031: case i_ASR:
2032: mayfail;
2033: if (curi->smode==Dreg) {
2034: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2035: " FAIL(1);\n"
2036: " return 0;\n"
2037: "} \n");
2038: start_brace();
2039: }
2040: comprintf("\tdont_care_flags();\n");
2041:
2042: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2043: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2044: if (curi->smode!=immi) {
2045: if (!noflags) {
2046: uses_cmov;
2047: start_brace();
2048: comprintf("\tint highmask;\n"
2049: "\tint width;\n"
2050: "\tint cdata=scratchie++;\n"
2051: "\tint tmpcnt=scratchie++;\n"
2052: "\tint highshift=scratchie++;\n");
2053: comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
2054: "\tand_l_ri(tmpcnt,63);\n"
2055: "\tmov_l_ri(cdata,0);\n"
2056: "\tcmov_l_rr(cdata,data,5);\n");
2057: /* cdata is now either data (for shift count!=0) or
2058: 0 (for shift count==0) */
2059: switch(curi->size) {
2060: case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
2061: "\thighmask=0x38;\n"
2062: "\twidth=8;\n");
2063: break;
2064: case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
2065: "\thighmask=0x30;\n"
2066: "\twidth=16;\n");
2067: break;
2068: case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
2069: "\thighmask=0x20;\n"
2070: "\twidth=32;\n");
2071: break;
2072: default: abort();
2073: }
2074: comprintf("test_l_ri(cnt,highmask);\n"
2075: "mov_l_ri(highshift,0);\n"
2076: "mov_l_ri(scratchie,width/2);\n"
2077: "cmov_l_rr(highshift,scratchie,5);\n");
2078: /* The x86 masks out bits, so we now make sure that things
2079: really get shifted as much as planned */
2080: switch(curi->size) {
2081: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
2082: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
2083: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
2084: default: abort();
2085: }
2086: /* And again */
2087: switch(curi->size) {
2088: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
2089: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
2090: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
2091: default: abort();
2092: }
2093:
2094: /* Result of shift is now in data. Now we need to determine
2095: the carry by shifting cdata one less */
2096: comprintf("\tsub_l_ri(tmpcnt,1);\n");
2097: switch(curi->size) {
2098: case sz_byte: comprintf("\tshra_b_rr(cdata,tmpcnt);\n");break;
2099: case sz_word: comprintf("\tshra_w_rr(cdata,tmpcnt);\n");break;
2100: case sz_long: comprintf("\tshra_l_rr(cdata,tmpcnt);\n");break;
2101: default: abort();
2102: }
2103: /* If the shift count was higher than the width, we need
2104: to pick up the sign from data */
2105: comprintf("test_l_ri(tmpcnt,highmask);\n"
2106: "cmov_l_rr(cdata,data,5);\n");
2107: /* And create the flags */
2108: comprintf("\tstart_needflags();\n");
2109: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2110: switch(curi->size) {
2111: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2112: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2113: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2114: }
2115: comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
2116: comprintf("\t live_flags();\n");
2117: comprintf("\t end_needflags();\n");
2118: comprintf("\t duplicate_carry();\n");
2119: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2120: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2121: }
2122: else {
2123: uses_cmov;
2124: start_brace();
2125: comprintf("\tint highmask;\n"
2126: "\tint width;\n"
2127: "\tint highshift=scratchie++;\n");
2128: switch(curi->size) {
2129: case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
2130: "\thighmask=0x38;\n"
2131: "\twidth=8;\n");
2132: break;
2133: case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
2134: "\thighmask=0x30;\n"
2135: "\twidth=16;\n");
2136: break;
2137: case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
2138: "\thighmask=0x20;\n"
2139: "\twidth=32;\n");
2140: break;
2141: default: abort();
2142: }
2143: comprintf("test_l_ri(cnt,highmask);\n"
2144: "mov_l_ri(highshift,0);\n"
2145: "mov_l_ri(scratchie,width/2);\n"
2146: "cmov_l_rr(highshift,scratchie,5);\n");
2147: /* The x86 masks out bits, so we now make sure that things
2148: really get shifted as much as planned */
2149: switch(curi->size) {
2150: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
2151: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
2152: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
2153: default: abort();
2154: }
2155: /* And again */
2156: switch(curi->size) {
2157: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
2158: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
2159: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
2160: default: abort();
2161: }
2162: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2163: }
2164: }
2165: else {
2166: start_brace();
2167: comprintf("\tint tmp=scratchie++;\n"
2168: "\tint bp;\n"
2169: "\tmov_l_rr(tmp,data);\n");
2170: switch(curi->size) {
2171: case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n"
2172: "\tbp=srcreg-1;\n"); break;
2173: case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n"
2174: "\tbp=srcreg-1;\n"); break;
2175: case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n"
2176: "\tbp=srcreg-1;\n"); break;
2177: default: abort();
2178: }
2179:
2180: if (!noflags) {
2181: comprintf("\tstart_needflags();\n");
2182: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2183: switch(curi->size) {
2184: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2185: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2186: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2187: }
2188: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2189: comprintf("\t live_flags();\n");
2190: comprintf("\t end_needflags();\n");
2191: comprintf("\t duplicate_carry();\n");
2192: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2193: }
2194: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2195: }
2196: break;
2197:
2198: case i_ASL:
2199: mayfail;
2200: if (curi->smode==Dreg) {
2201: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2202: " FAIL(1);\n"
2203: " return 0;\n"
2204: "} \n");
2205: start_brace();
2206: }
2207: comprintf("\tdont_care_flags();\n");
2208: /* Except for the handling of the V flag, this is identical to
2209: LSL. The handling of V is, uhm, unpleasant, so if it's needed,
2210: let the normal emulation handle it. Shoulders of giants kinda
2211: thing ;-) */
2212: comprintf("if (needed_flags & FLAG_V) {\n"
2213: " FAIL(1);\n"
2214: " return 0;\n"
2215: "} \n");
2216:
2217: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2218: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2219: if (curi->smode!=immi) {
2220: if (!noflags) {
2221: uses_cmov;
2222: start_brace();
2223: comprintf("\tint highmask;\n"
2224: "\tint cdata=scratchie++;\n"
2225: "\tint tmpcnt=scratchie++;\n");
2226: comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
2227: "\tand_l_ri(tmpcnt,63);\n"
2228: "\tmov_l_ri(cdata,0);\n"
2229: "\tcmov_l_rr(cdata,data,5);\n");
2230: /* cdata is now either data (for shift count!=0) or
2231: 0 (for shift count==0) */
2232: switch(curi->size) {
2233: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2234: "\thighmask=0x38;\n");
2235: break;
2236: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2237: "\thighmask=0x30;\n");
2238: break;
2239: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2240: "\thighmask=0x20;\n");
2241: break;
2242: default: abort();
2243: }
2244: comprintf("test_l_ri(cnt,highmask);\n"
2245: "mov_l_ri(scratchie,0);\n"
2246: "cmov_l_rr(scratchie,data,4);\n");
2247: switch(curi->size) {
2248: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2249: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2250: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2251: default: abort();
2252: }
2253: /* Result of shift is now in data. Now we need to determine
2254: the carry by shifting cdata one less */
2255: comprintf("\tsub_l_ri(tmpcnt,1);\n");
2256: switch(curi->size) {
2257: case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break;
2258: case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break;
2259: case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break;
2260: default: abort();
2261: }
2262: comprintf("test_l_ri(tmpcnt,highmask);\n"
2263: "mov_l_ri(scratchie,0);\n"
2264: "cmov_l_rr(cdata,scratchie,5);\n");
2265: /* And create the flags */
2266: comprintf("\tstart_needflags();\n");
2267:
2268: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2269: switch(curi->size) {
2270: case sz_byte: comprintf("\t test_b_rr(data,data);\n");
2271: comprintf("\t bt_l_ri(cdata,7);\n"); break;
2272: case sz_word: comprintf("\t test_w_rr(data,data);\n");
2273: comprintf("\t bt_l_ri(cdata,15);\n"); break;
2274: case sz_long: comprintf("\t test_l_rr(data,data);\n");
2275: comprintf("\t bt_l_ri(cdata,31);\n"); break;
2276: }
2277: comprintf("\t live_flags();\n");
2278: comprintf("\t end_needflags();\n");
2279: comprintf("\t duplicate_carry();\n");
2280: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2281: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2282: }
2283: else {
2284: uses_cmov;
2285: start_brace();
2286: comprintf("\tint highmask;\n");
2287: switch(curi->size) {
2288: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2289: "\thighmask=0x38;\n");
2290: break;
2291: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2292: "\thighmask=0x30;\n");
2293: break;
2294: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2295: "\thighmask=0x20;\n");
2296: break;
2297: default: abort();
2298: }
2299: comprintf("test_l_ri(cnt,highmask);\n"
2300: "mov_l_ri(scratchie,0);\n"
2301: "cmov_l_rr(scratchie,data,4);\n");
2302: switch(curi->size) {
2303: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2304: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2305: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2306: default: abort();
2307: }
2308: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2309: }
2310: }
2311: else {
2312: start_brace();
2313: comprintf("\tint tmp=scratchie++;\n"
2314: "\tint bp;\n"
2315: "\tmov_l_rr(tmp,data);\n");
2316: switch(curi->size) {
2317: case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"
2318: "\tbp=8-srcreg;\n"); break;
2319: case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"
2320: "\tbp=16-srcreg;\n"); break;
2321: case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"
2322: "\tbp=32-srcreg;\n"); break;
2323: default: abort();
2324: }
2325:
2326: if (!noflags) {
2327: comprintf("\tstart_needflags();\n");
2328: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2329: switch(curi->size) {
2330: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2331: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2332: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2333: }
2334: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2335: comprintf("\t live_flags();\n");
2336: comprintf("\t end_needflags();\n");
2337: comprintf("\t duplicate_carry();\n");
2338: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2339: }
2340: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2341: }
2342: break;
2343:
2344: case i_LSR:
2345: mayfail;
2346: if (curi->smode==Dreg) {
2347: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2348: " FAIL(1);\n"
2349: " return 0;\n"
2350: "} \n");
2351: start_brace();
2352: }
2353: comprintf("\tdont_care_flags();\n");
2354:
2355: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2356: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2357: if (curi->smode!=immi) {
2358: if (!noflags) {
2359: uses_cmov;
2360: start_brace();
2361: comprintf("\tint highmask;\n"
2362: "\tint cdata=scratchie++;\n"
2363: "\tint tmpcnt=scratchie++;\n");
2364: comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
2365: "\tand_l_ri(tmpcnt,63);\n"
2366: "\tmov_l_ri(cdata,0);\n"
2367: "\tcmov_l_rr(cdata,data,5);\n");
2368: /* cdata is now either data (for shift count!=0) or
2369: 0 (for shift count==0) */
2370: switch(curi->size) {
2371: case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
2372: "\thighmask=0x38;\n");
2373: break;
2374: case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
2375: "\thighmask=0x30;\n");
2376: break;
2377: case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
2378: "\thighmask=0x20;\n");
2379: break;
2380: default: abort();
2381: }
2382: comprintf("test_l_ri(cnt,highmask);\n"
2383: "mov_l_ri(scratchie,0);\n"
2384: "cmov_l_rr(scratchie,data,4);\n");
2385: switch(curi->size) {
2386: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2387: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2388: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2389: default: abort();
2390: }
2391: /* Result of shift is now in data. Now we need to determine
2392: the carry by shifting cdata one less */
2393: comprintf("\tsub_l_ri(tmpcnt,1);\n");
2394: switch(curi->size) {
2395: case sz_byte: comprintf("\tshrl_b_rr(cdata,tmpcnt);\n");break;
2396: case sz_word: comprintf("\tshrl_w_rr(cdata,tmpcnt);\n");break;
2397: case sz_long: comprintf("\tshrl_l_rr(cdata,tmpcnt);\n");break;
2398: default: abort();
2399: }
2400: comprintf("test_l_ri(tmpcnt,highmask);\n"
2401: "mov_l_ri(scratchie,0);\n"
2402: "cmov_l_rr(cdata,scratchie,5);\n");
2403: /* And create the flags */
2404: comprintf("\tstart_needflags();\n");
2405: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2406: switch(curi->size) {
2407: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2408: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2409: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2410: }
2411: comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
2412: comprintf("\t live_flags();\n");
2413: comprintf("\t end_needflags();\n");
2414: comprintf("\t duplicate_carry();\n");
2415: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2416: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2417: }
2418: else {
2419: uses_cmov;
2420: start_brace();
2421: comprintf("\tint highmask;\n");
2422: switch(curi->size) {
2423: case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
2424: "\thighmask=0x38;\n");
2425: break;
2426: case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
2427: "\thighmask=0x30;\n");
2428: break;
2429: case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
2430: "\thighmask=0x20;\n");
2431: break;
2432: default: abort();
2433: }
2434: comprintf("test_l_ri(cnt,highmask);\n"
2435: "mov_l_ri(scratchie,0);\n"
2436: "cmov_l_rr(scratchie,data,4);\n");
2437: switch(curi->size) {
2438: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2439: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2440: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2441: default: abort();
2442: }
2443: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2444: }
2445: }
2446: else {
2447: start_brace();
2448: comprintf("\tint tmp=scratchie++;\n"
2449: "\tint bp;\n"
2450: "\tmov_l_rr(tmp,data);\n");
2451: switch(curi->size) {
2452: case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n"
2453: "\tbp=srcreg-1;\n"); break;
2454: case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n"
2455: "\tbp=srcreg-1;\n"); break;
2456: case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n"
2457: "\tbp=srcreg-1;\n"); break;
2458: default: abort();
2459: }
2460:
2461: if (!noflags) {
2462: comprintf("\tstart_needflags();\n");
2463: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2464: switch(curi->size) {
2465: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2466: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2467: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2468: }
2469: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2470: comprintf("\t live_flags();\n");
2471: comprintf("\t end_needflags();\n");
2472: comprintf("\t duplicate_carry();\n");
2473: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2474: }
2475: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2476: }
2477: break;
2478:
2479: case i_LSL:
2480: comprintf("\tdont_care_flags();\n");
2481:
2482: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2483: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2484: if (curi->smode!=immi) {
2485: if (!noflags) {
2486: uses_cmov;
2487: start_brace();
2488: comprintf("\tint highmask;\n"
2489: "\tint cdata=scratchie++;\n"
2490: "\tint tmpcnt=scratchie++;\n");
2491: comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
2492: "\tand_l_ri(tmpcnt,63);\n"
2493: "\tmov_l_ri(cdata,0);\n"
2494: "\tcmov_l_rr(cdata,data,5);\n");
2495: /* cdata is now either data (for shift count!=0) or
2496: 0 (for shift count==0) */
2497: switch(curi->size) {
2498: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2499: "\thighmask=0x38;\n");
2500: break;
2501: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2502: "\thighmask=0x30;\n");
2503: break;
2504: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2505: "\thighmask=0x20;\n");
2506: break;
2507: default: abort();
2508: }
2509: comprintf("test_l_ri(cnt,highmask);\n"
2510: "mov_l_ri(scratchie,0);\n"
2511: "cmov_l_rr(scratchie,data,4);\n");
2512: switch(curi->size) {
2513: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2514: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2515: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2516: default: abort();
2517: }
2518: /* Result of shift is now in data. Now we need to determine
2519: the carry by shifting cdata one less */
2520: comprintf("\tsub_l_ri(tmpcnt,1);\n");
2521: switch(curi->size) {
2522: case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break;
2523: case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break;
2524: case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break;
2525: default: abort();
2526: }
2527: comprintf("test_l_ri(tmpcnt,highmask);\n"
2528: "mov_l_ri(scratchie,0);\n"
2529: "cmov_l_rr(cdata,scratchie,5);\n");
2530: /* And create the flags */
2531: comprintf("\tstart_needflags();\n");
2532: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2533: switch(curi->size) {
2534: case sz_byte: comprintf("\t test_b_rr(data,data);\n");
2535: comprintf("\t bt_l_ri(cdata,7);\n"); break;
2536: case sz_word: comprintf("\t test_w_rr(data,data);\n");
2537: comprintf("\t bt_l_ri(cdata,15);\n"); break;
2538: case sz_long: comprintf("\t test_l_rr(data,data);\n");
2539: comprintf("\t bt_l_ri(cdata,31);\n"); break;
2540: }
2541: comprintf("\t live_flags();\n");
2542: comprintf("\t end_needflags();\n");
2543: comprintf("\t duplicate_carry();\n");
2544: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2545: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2546: }
2547: else {
2548: uses_cmov;
2549: start_brace();
2550: comprintf("\tint highmask;\n");
2551: switch(curi->size) {
2552: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2553: "\thighmask=0x38;\n");
2554: break;
2555: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2556: "\thighmask=0x30;\n");
2557: break;
2558: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2559: "\thighmask=0x20;\n");
2560: break;
2561: default: abort();
2562: }
2563: comprintf("test_l_ri(cnt,highmask);\n"
2564: "mov_l_ri(scratchie,0);\n"
2565: "cmov_l_rr(scratchie,data,4);\n");
2566: switch(curi->size) {
2567: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2568: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2569: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2570: default: abort();
2571: }
2572: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2573: }
2574: }
2575: else {
2576: start_brace();
2577: comprintf("\tint tmp=scratchie++;\n"
2578: "\tint bp;\n"
2579: "\tmov_l_rr(tmp,data);\n");
2580: switch(curi->size) {
2581: case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"
2582: "\tbp=8-srcreg;\n"); break;
2583: case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"
2584: "\tbp=16-srcreg;\n"); break;
2585: case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"
2586: "\tbp=32-srcreg;\n"); break;
2587: default: abort();
2588: }
2589:
2590: if (!noflags) {
2591: comprintf("\tstart_needflags();\n");
2592: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2593: switch(curi->size) {
2594: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2595: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2596: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2597: }
2598: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2599: comprintf("\t live_flags();\n");
2600: comprintf("\t end_needflags();\n");
2601: comprintf("\t duplicate_carry();\n");
2602: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2603: }
2604: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2605: }
2606: break;
2607:
2608: case i_ROL:
2609: mayfail;
2610: if (curi->smode==Dreg) {
2611: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2612: " FAIL(1);\n"
2613: " return 0;\n"
2614: "} \n");
2615: start_brace();
2616: }
2617: comprintf("\tdont_care_flags();\n");
2618: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2619: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2620: start_brace ();
2621:
2622: switch(curi->size) {
2623: case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break;
2624: case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break;
2625: case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break;
2626: }
2627:
2628: if (!noflags) {
2629: comprintf("\tstart_needflags();\n");
2630: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2631: switch(curi->size) {
2632: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2633: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2634: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2635: }
2636: comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */
2637: comprintf("\t live_flags();\n");
2638: comprintf("\t end_needflags();\n");
2639: }
2640: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2641: break;
2642:
2643: case i_ROR:
2644: mayfail;
2645: if (curi->smode==Dreg) {
2646: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2647: " FAIL(1);\n"
2648: " return 0;\n"
2649: "} \n");
2650: start_brace();
2651: }
2652: comprintf("\tdont_care_flags();\n");
2653: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2654: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2655: start_brace ();
2656:
2657: switch(curi->size) {
2658: case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break;
2659: case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break;
2660: case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break;
2661: }
2662:
2663: if (!noflags) {
2664: comprintf("\tstart_needflags();\n");
2665: comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2666: switch(curi->size) {
2667: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2668: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2669: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2670: }
2671: switch(curi->size) {
2672: case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break;
2673: case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break;
2674: case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break;
2675: }
2676: comprintf("\t live_flags();\n");
2677: comprintf("\t end_needflags();\n");
2678: }
2679: genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2680: break;
2681:
2682: case i_ROXL:
2683: failure;
2684: break;
2685: case i_ROXR:
2686: failure;
2687: break;
2688: case i_ASRW:
2689: failure;
2690: break;
2691: case i_ASLW:
2692: failure;
2693: break;
2694: case i_LSRW:
2695: failure;
2696: break;
2697: case i_LSLW:
2698: failure;
2699: break;
2700: case i_ROLW:
2701: failure;
2702: break;
2703: case i_RORW:
2704: failure;
2705: break;
2706: case i_ROXLW:
2707: failure;
2708: break;
2709: case i_ROXRW:
2710: failure;
2711: break;
2712: case i_MOVEC2:
2713: isjump;
2714: failure;
2715: break;
2716: case i_MOVE2C:
2717: isjump;
2718: failure;
2719: break;
2720: case i_CAS:
2721: failure;
2722: break;
2723: case i_CAS2:
2724: failure;
2725: break;
2726: case i_MOVES: /* ignore DFC and SFC because we have no MMU */
2727: isjump;
2728: failure;
2729: break;
2730: case i_BKPT: /* only needed for hardware emulators */
2731: isjump;
2732: failure;
2733: break;
2734: case i_CALLM: /* not present in 68030 */
2735: isjump;
2736: failure;
2737: break;
2738: case i_RTM: /* not present in 68030 */
2739: isjump;
2740: failure;
2741: break;
2742: case i_TRAPcc:
2743: isjump;
2744: failure;
2745: break;
2746: case i_DIVL:
2747: isjump;
2748: failure;
2749: break;
2750: case i_MULL:
2751: if (!noflags) {
2752: failure;
2753: break;
2754: }
2755: comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2756: comprintf("\tint r2=(extra>>12)&7;\n"
2757: "\tint tmp=scratchie++;\n");
2758:
2759: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2760: /* The two operands are in dst and r2 */
2761: comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */
2762: "\tint r3=(extra&7);\n"
2763: "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */
2764: comprintf("\tif (extra&0x0800) { \n" /* signed */
2765: "\t\timul_64_32(r2,r3);\n"
2766: "\t} else { \n"
2767: "\t\tmul_64_32(r2,r3);\n"
2768: "\t} \n");
2769: /* The result is in r2/tmp, with r2 holding the lower 32 bits */
2770: comprintf("\t} else {\n"); /* Only want 32 bit result */
2771: /* operands in dst and r2, result foes into r2 */
2772: /* shouldn't matter whether it's signed or unsigned?!? */
2773: comprintf("\timul_32_32(r2,dst);\n"
2774: "\t}\n");
2775: break;
2776:
2777: case i_BFTST:
2778: case i_BFEXTU:
2779: case i_BFCHG:
2780: case i_BFEXTS:
2781: case i_BFCLR:
2782: case i_BFFFO:
2783: case i_BFSET:
2784: case i_BFINS:
2785: failure;
2786: break;
2787: case i_PACK:
2788: failure;
2789: break;
2790: case i_UNPK:
2791: failure;
2792: break;
2793: case i_TAS:
2794: failure;
2795: break;
2796: case i_FPP:
2797: mayfail;
2798: comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2799: comprintf("\tcomp_fpp_opp(opcode,extra);\n");
2800: break;
2801: case i_FBcc:
2802: isjump;
2803: uses_cmov;
2804: mayfail;
2805: comprintf("\tcomp_fbcc_opp(opcode);\n");
2806: break;
2807: case i_FDBcc:
2808: isjump;
2809: failure;
2810: break;
2811: case i_FScc:
2812: mayfail;
2813: uses_cmov;
2814: comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2815: comprintf("\tcomp_fscc_opp(opcode,extra);\n");
2816: break;
2817: case i_FTRAPcc:
2818: isjump;
2819: failure;
2820: break;
2821: case i_FSAVE:
2822: failure;
2823: break;
2824: case i_FRESTORE:
2825: failure;
2826: break;
2827:
2828: case i_CINVL:
2829: case i_CINVP:
2830: case i_CINVA:
2831: isjump; /* Not really, but it's probably a good idea to stop
2832: translating at this point */
2833: failure;
2834: comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */
2835: break;
2836: case i_CPUSHL:
2837: case i_CPUSHP:
2838: case i_CPUSHA:
2839: isjump; /* Not really, but it's probably a good idea to stop
2840: translating at this point */
2841: failure;
2842: break;
2843: case i_MOVE16:
2844: //if ((opcode & 0xfff8) == 0xf620) {
2845: genmov16(opcode,curi);
2846: //} else {
2847: // isjump;
2848: // failure;
2849: //}
2850: break;
2851:
2852: case i_MMUOP030:
2853: case i_PFLUSHN:
2854: case i_PFLUSH:
2855: case i_PFLUSHAN:
2856: case i_PFLUSHA:
2857: case i_PLPAR:
2858: case i_PLPAW:
2859: case i_PTESTR:
2860: case i_PTESTW:
2861: case i_LPSTOP:
2862: isjump;
2863: failure;
2864: break;
2865: default:
2866: abort ();
2867: break;
2868: }
2869: comprintf("%s",endstr);
2870: finish_braces ();
2871: sync_m68k_pc ();
2872: if (global_mayfail)
2873: comprintf("\tif (failure) m68k_pc_offset=m68k_pc_offset_thisinst;\n");
2874: return global_failure;
2875: }
2876:
2877: static void
2878: generate_includes (FILE * f, int bigger)
2879: {
2880: fprintf (f, "#include \"sysconfig.h\"\n");
2881: fprintf (f, "#if defined(JIT)\n");
2882: fprintf (f, "#include \"sysdeps.h\"\n");
2883: if (bigger)
2884: fprintf (f, "#include \"options.h\"\n");
2885: fprintf (f, "#include \"memory.h\"\n");
2886: fprintf (f, "#include \"newcpu.h\"\n");
2887: fprintf (f, "#include \"comptbl.h\"\n");
2888: }
2889:
2890: static int postfix;
2891:
1.1.1.2 ! root 2892:
! 2893: static char *decodeEA (amodes mode, wordsizes size)
! 2894: {
! 2895: static char buffer[80];
! 2896:
! 2897: buffer[0] = 0;
! 2898: switch (mode){
! 2899: case Dreg:
! 2900: strcpy (buffer,"Dn");
! 2901: break;
! 2902: case Areg:
! 2903: strcpy (buffer,"An");
! 2904: break;
! 2905: case Aind:
! 2906: strcpy (buffer,"(An)");
! 2907: break;
! 2908: case Aipi:
! 2909: strcpy (buffer,"(An)+");
! 2910: break;
! 2911: case Apdi:
! 2912: strcpy (buffer,"-(An)");
! 2913: break;
! 2914: case Ad16:
! 2915: strcpy (buffer,"(d16,An)");
! 2916: break;
! 2917: case Ad8r:
! 2918: strcpy (buffer,"(d8,An,Xn)");
! 2919: break;
! 2920: case PC16:
! 2921: strcpy (buffer,"(d16,PC)");
! 2922: break;
! 2923: case PC8r:
! 2924: strcpy (buffer,"(d8,PC,Xn)");
! 2925: break;
! 2926: case absw:
! 2927: strcpy (buffer,"(xxx).W");
! 2928: break;
! 2929: case absl:
! 2930: strcpy (buffer,"(xxx).L");
! 2931: break;
! 2932: case imm:
! 2933: switch (size){
! 2934: case sz_byte:
! 2935: strcpy (buffer,"#<data>.B");
! 2936: break;
! 2937: case sz_word:
! 2938: strcpy (buffer,"#<data>.W");
! 2939: break;
! 2940: case sz_long:
! 2941: strcpy (buffer,"#<data>.L");
! 2942: break;
! 2943: default:
! 2944: break;
! 2945: }
! 2946: break;
! 2947: case imm0:
! 2948: strcpy (buffer,"#<data>.B");
! 2949: break;
! 2950: case imm1:
! 2951: strcpy (buffer,"#<data>.W");
! 2952: break;
! 2953: case imm2:
! 2954: strcpy (buffer,"#<data>.L");
! 2955: break;
! 2956: case immi:
! 2957: strcpy (buffer,"#<data>");
! 2958: break;
! 2959:
! 2960: default:
! 2961: break;
! 2962: }
! 2963: return buffer;
! 2964: }
! 2965:
! 2966: static char *outopcode (int opcode)
! 2967: {
! 2968: static char out[100];
! 2969: struct instr *ins;
! 2970: int i;
! 2971:
! 2972: ins = &table68k[opcode];
! 2973: for (i = 0; lookuptab[i].name[0]; i++) {
! 2974: if (ins->mnemo == lookuptab[i].mnemo)
! 2975: break;
! 2976: }
! 2977: {
! 2978: char *s = ua (lookuptab[i].name);
! 2979: strcpy (out, s);
! 2980: xfree (s);
! 2981: }
! 2982: if (ins->smode == immi)
! 2983: strcat (out, "Q");
! 2984: if (ins->size == sz_byte)
! 2985: strcat (out,".B");
! 2986: if (ins->size == sz_word)
! 2987: strcat (out,".W");
! 2988: if (ins->size == sz_long)
! 2989: strcat (out,".L");
! 2990: strcat (out," ");
! 2991: if (ins->suse)
! 2992: strcat (out, decodeEA (ins->smode, ins->size));
! 2993: if (ins->duse) {
! 2994: if (ins->suse) strcat (out,",");
! 2995: strcat (out, decodeEA (ins->dmode, ins->size));
! 2996: }
! 2997: return out;
! 2998: }
! 2999:
1.1 root 3000: static void
3001: generate_one_opcode (int rp, int noflags)
3002: {
3003: int i;
3004: uae_u16 smsk, dmsk;
3005: long int opcode = opcode_map[rp];
3006: int aborted=0;
3007: int have_srcreg=0;
3008: int have_dstreg=0;
3009:
3010: if (table68k[opcode].mnemo == i_ILLG
3011: || table68k[opcode].clev > cpu_level)
3012: return;
3013:
3014: for (i = 0; lookuptab[i].name[0]; i++)
3015: {
3016: if (table68k[opcode].mnemo == lookuptab[i].mnemo)
3017: break;
3018: }
3019:
3020: if (table68k[opcode].handler != -1)
3021: return;
3022:
3023: switch (table68k[opcode].stype)
3024: {
3025: case 0: smsk = 7; break;
3026: case 1: smsk = 255; break;
3027: case 2: smsk = 15; break;
3028: case 3: smsk = 7; break;
3029: case 4: smsk = 7; break;
3030: case 5: smsk = 63; break;
3031: case 7: smsk = 3; break;
3032: default: abort ();
3033: }
3034: dmsk = 7;
3035:
3036: next_cpu_level = -1;
3037: if (table68k[opcode].suse
3038: && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
3039: && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
3040: && table68k[opcode].smode != absw && table68k[opcode].smode != absl
3041: && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
3042: {
3043: have_srcreg=1;
3044: if (table68k[opcode].spos == -1)
3045: {
3046: if (((int) table68k[opcode].sreg) >= 128)
3047: comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
3048: else
3049: comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg);
3050: }
3051: else
3052: {
3053: char source[100];
3054: int pos = table68k[opcode].spos;
3055:
3056: if (pos)
3057: sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
3058: else
3059: sprintf (source, "(opcode & %d)", smsk);
3060:
3061: if (table68k[opcode].stype == 3)
3062: comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source);
3063: else if (table68k[opcode].stype == 1)
3064: comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
3065: else
3066: comprintf ("\tuae_s32 srcreg = %s;\n", source);
3067: }
3068: }
3069: if (table68k[opcode].duse
3070: /* Yes, the dmode can be imm, in case of LINK or DBcc */
3071: && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
3072: && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
3073: && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
3074: {
3075: have_dstreg=1;
3076: if (table68k[opcode].dpos == -1)
3077: {
3078: if (((int) table68k[opcode].dreg) >= 128)
3079: comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
3080: else
3081: comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg);
3082: }
3083: else
3084: {
3085: int pos = table68k[opcode].dpos;
3086:
3087: if (pos)
3088: comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
3089: pos, dmsk);
3090: else
3091: comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
3092: }
3093: }
3094:
3095: if (have_srcreg && have_dstreg &&
3096: (table68k[opcode].dmode==Areg ||
3097: table68k[opcode].dmode==Aind ||
3098: table68k[opcode].dmode==Aipi ||
3099: table68k[opcode].dmode==Apdi ||
3100: table68k[opcode].dmode==Ad16 ||
3101: table68k[opcode].dmode==Ad8r) &&
3102: (table68k[opcode].smode==Areg ||
3103: table68k[opcode].smode==Aind ||
3104: table68k[opcode].smode==Aipi ||
3105: table68k[opcode].smode==Apdi ||
3106: table68k[opcode].smode==Ad16 ||
3107: table68k[opcode].smode==Ad8r)
3108: ) {
3109: comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n");
3110: }
3111: else {
3112: comprintf("\tuae_u32 dodgy=0;\n");
3113: }
3114: comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n");
3115: comprintf("\tm68k_pc_offset+=2;\n");
3116:
3117: aborted=gen_opcode (opcode);
3118: {
3119: int flags=0;
3120: if (global_isjump) flags|=1;
3121: if (long_opcode) flags|=2;
3122: if (global_cmov) flags|=4;
3123: if (global_isaddx) flags|=8;
3124: if (global_iscjump) flags|=16;
3125: comprintf ("return 0;\n");
3126: comprintf ("}\n");
3127:
1.1.1.2 ! root 3128: char *name = ua (lookuptab[i].name);
1.1 root 3129: if (aborted) {
3130: fprintf (stblfile, "{ NULL, %ld, 0x%08x }, /* %s */\n", opcode, flags, name);
3131: com_discard();
3132: } else {
1.1.1.2 ! root 3133: printf ("/* %s */\n", outopcode (opcode));
! 3134: if (noflags) {
1.1 root 3135: fprintf (stblfile, "{ op_%lx_%d_comp_nf, %ld, 0x%08x }, /* %s */\n", opcode, postfix, opcode, flags, name);
3136: fprintf (headerfile, "extern compop_func op_%lx_%d_comp_nf;\n", opcode, postfix);
1.1.1.2 ! root 3137: printf ("uae_u32 REGPARAM2 op_%lx_%d_comp_nf(uae_u32 opcode)\n{\n", opcode, postfix);
1.1 root 3138: } else {
3139: fprintf (stblfile, "{ op_%lx_%d_comp_ff, %ld, 0x%08x }, /* %s */\n", opcode, postfix, opcode, flags, name);
3140: fprintf (headerfile, "extern compop_func op_%lx_%d_comp_ff;\n", opcode, postfix);
1.1.1.2 ! root 3141: printf ("uae_u32 REGPARAM2 op_%lx_%d_comp_ff(uae_u32 opcode)\n{\n", opcode, postfix);
1.1 root 3142: }
3143: com_flush();
3144: }
1.1.1.2 ! root 3145: xfree (name);
1.1 root 3146: }
3147: opcode_next_clev[rp] = next_cpu_level;
3148: opcode_last_postfix[rp] = postfix;
3149: }
3150:
3151: static void
3152: generate_func (int noflags)
3153: {
3154: int i, j, rp;
3155:
3156: using_prefetch = 0;
3157: using_exception_3 = 0;
3158: for (i = 0; i < 1; i++) /* We only do one level! */
3159: {
3160: cpu_level = 5 - i;
3161: postfix = i;
3162:
3163: if (noflags)
3164: fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_nf[] = {\n", postfix);
3165: else
3166: fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_ff[] = {\n", postfix);
3167:
3168:
3169: /* sam: this is for people with low memory (eg. me :)) */
3170: printf ("\n"
3171: "#if !defined(PART_1) && !defined(PART_2) && "
3172: "!defined(PART_3) && !defined(PART_4) && "
3173: "!defined(PART_5) && !defined(PART_6) && "
3174: "!defined(PART_7) && !defined(PART_8)"
3175: "\n"
3176: "#define PART_1 1\n"
3177: "#define PART_2 1\n"
3178: "#define PART_3 1\n"
3179: "#define PART_4 1\n"
3180: "#define PART_5 1\n"
3181: "#define PART_6 1\n"
3182: "#define PART_7 1\n"
3183: "#define PART_8 1\n"
3184: "#endif\n\n"
3185: "extern void setzflg_l(uae_u32);\n"
3186: "extern void comp_fpp_opp();\n"
3187: "extern void comp_fscc_opp();\n"
3188: "extern void comp_fbcc_opp();\n\n");
3189:
1.1.1.2 ! root 3190: printf ("#define JIT_M68K_PC_SYNC 100\n\n");
! 3191:
1.1 root 3192: rp = 0;
3193: for (j = 1; j <= 8; ++j)
3194: {
3195: int k = (j * nr_cpuop_funcs) / 8;
3196: printf ("#ifdef PART_%d\n", j);
3197: for (; rp < k; rp++)
3198: generate_one_opcode (rp,noflags);
3199: printf ("#endif\n\n");
3200: }
3201:
3202: fprintf (stblfile, "{ 0, 65536, 0 }};\n");
3203: }
3204:
3205: }
3206:
3207: int
3208: main (int argc, char **argv)
3209: {
3210: read_table68k ();
3211: do_merges ();
3212:
3213: opcode_map = xmalloc (int, nr_cpuop_funcs);
3214: opcode_last_postfix = xmalloc (int, nr_cpuop_funcs);
3215: opcode_next_clev = xmalloc (int, nr_cpuop_funcs);
3216: counts = xmalloc (unsigned long, 65536);
3217: read_counts ();
3218:
3219: /* It would be a lot nicer to put all in one file (we'd also get rid of
3220: * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
3221: * I don't dare to touch the 68k version. */
3222:
3223: headerfile = fopen ("jit/comptbl.h", "wb");
3224:
3225: fprintf (headerfile, "" \
3226: "#ifdef NOFLAGS_SUPPORT\n" \
3227: "/* 68040 */\n" \
3228: "extern const struct comptbl op_smalltbl_0_nf[];\n" \
3229: "#endif\n" \
3230: "extern const struct comptbl op_smalltbl_0_comp_nf[];\n" \
3231: "extern const struct comptbl op_smalltbl_0_comp_ff[];\n" \
3232: "");
3233:
3234: stblfile = fopen ("jit/compstbl.cpp", "wb");
3235: freopen ("jit/compemu.cpp", "wb", stdout);
3236:
3237: generate_includes (stdout, 1);
3238: generate_includes (stblfile, 1);
3239:
3240: printf("#include \"compemu.h\"\n");
3241:
3242: noflags=0;
3243: generate_func (noflags);
3244:
3245:
3246: opcode_map = xmalloc (int, nr_cpuop_funcs);
3247: opcode_last_postfix = xmalloc (int, nr_cpuop_funcs);
3248: opcode_next_clev = xmalloc (int, nr_cpuop_funcs);
3249: counts = xmalloc (unsigned long, 65536);
3250: read_counts ();
3251: noflags=1;
3252: generate_func (noflags);
3253:
3254: printf ("#endif\n");
3255: fprintf (stblfile, "#endif\n");
3256:
3257: free (table68k);
3258: return 0;
3259: }
1.1.1.2 ! root 3260:
! 3261: void write_log (const TCHAR *format,...)
! 3262: {
! 3263: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.