ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/compiler/gencomp.c
Revision: 1.3
Committed: 2002-10-03T16:13:46Z (22 years, 1 month ago) by gbeauche
Content type: text/plain
Branch: MAIN
Changes since 1.2: +21 -5 lines
Log Message:
JIT add copyright notices just to notify people that's real derivative
work from GPL code (UAE-JIT). Additions and improvements are from B2
developers.

File Contents

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