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