ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/compiler/gencomp.c
Revision: 1.2
Committed: 2002-10-03T14:59:35Z (22 years ago) by gbeauche
Content type: text/plain
Branch: MAIN
Changes since 1.1: +0 -2 lines
Log Message:
Do translate BSR.L, we don't have any issue with that even if we are
doing block inlining since we have a complete chain of information about
the blocks to checksum.

File Contents

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