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