ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/compiler/gencomp.c
Revision: 1.5
Committed: 2003-03-13T20:34:34Z (21 years, 4 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
CVS Tags: nigel-build-12, nigel-build-13
Changes since 1.4: +2 -6 lines
Log Message:
Implement a generic setzflg_l() for P4, thus permitting to re-enable
translation of ADDX/SUBX/BCLR/BTST/BSET/BCHG instructions. i.e. make
it faster. ;-)

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 gbeauche 1.5 comprintf("\tlive_flags();\n");
1124 gbeauche 1.1 comprintf("\tif (needed_flags&FLAG_Z) {\n"
1125     "\tcmov_l_rr(zero,one,5);\n"
1126 gbeauche 1.4 "\tsetzflg_l(zero);\n"
1127 gbeauche 1.5 "\tlive_flags();\n"
1128 gbeauche 1.1 "\t}\n");
1129     comprintf("\tend_needflags();\n");
1130     duplicate_carry();
1131     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
1132     return;
1133     }
1134     default:
1135     failure;
1136     break;
1137     }
1138     }
1139    
1140     static void
1141     force_range_for_rox (const char *var, wordsizes size)
1142     {
1143     /* Could do a modulo operation here... which one is faster? */
1144     switch (size)
1145     {
1146     case sz_long:
1147     comprintf ("\tif (%s >= 33) %s -= 33;\n", var, var);
1148     break;
1149     case sz_word:
1150     comprintf ("\tif (%s >= 34) %s -= 34;\n", var, var);
1151     comprintf ("\tif (%s >= 17) %s -= 17;\n", var, var);
1152     break;
1153     case sz_byte:
1154     comprintf ("\tif (%s >= 36) %s -= 36;\n", var, var);
1155     comprintf ("\tif (%s >= 18) %s -= 18;\n", var, var);
1156     comprintf ("\tif (%s >= 9) %s -= 9;\n", var, var);
1157     break;
1158     }
1159     }
1160    
1161     static const char *
1162     cmask (wordsizes size)
1163     {
1164     switch (size)
1165     {
1166     case sz_byte:
1167     return "0x80";
1168     case sz_word:
1169     return "0x8000";
1170     case sz_long:
1171     return "0x80000000";
1172     default:
1173     abort ();
1174     }
1175     }
1176    
1177     static int
1178     source_is_imm1_8 (struct instr *i)
1179     {
1180     return i->stype == 3;
1181     }
1182    
1183     static int /* returns zero for success, non-zero for failure */
1184     gen_opcode (unsigned long int opcode)
1185     {
1186     struct instr *curi = table68k + opcode;
1187     char* ssize=NULL;
1188    
1189     insn_n_cycles = 2;
1190     global_failure=0;
1191     long_opcode=0;
1192     global_isjump=0;
1193     global_iscjump=0;
1194     global_isaddx=0;
1195     global_cmov=0;
1196     global_fpu=0;
1197     global_mayfail=0;
1198     hack_opcode=opcode;
1199     endstr[0]=0;
1200    
1201     start_brace ();
1202     comprintf("\tuae_u8 scratchie=S1;\n");
1203     switch (curi->plev)
1204     {
1205     case 0: /* not privileged */
1206     break;
1207     case 1: /* unprivileged only on 68000 */
1208     if (cpu_level == 0)
1209     break;
1210     if (next_cpu_level < 0)
1211     next_cpu_level = 0;
1212    
1213     /* fall through */
1214     case 2: /* priviledged */
1215     failure; /* Easy ones first */
1216     break;
1217     case 3: /* privileged if size == word */
1218     if (curi->size == sz_byte)
1219     break;
1220     failure;
1221     break;
1222     }
1223     switch (curi->size) {
1224     case sz_byte: ssize="b"; break;
1225     case sz_word: ssize="w"; break;
1226     case sz_long: ssize="l"; break;
1227     default: abort();
1228     }
1229    
1230     switch (curi->mnemo)
1231     {
1232     case i_OR:
1233     case i_AND:
1234     case i_EOR:
1235     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1236     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1237     switch(curi->mnemo) {
1238     case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break;
1239     case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break;
1240     case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break;
1241     }
1242     genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1243     break;
1244    
1245     case i_ORSR:
1246     case i_EORSR:
1247     failure;
1248     isjump;
1249     break;
1250     case i_ANDSR:
1251     failure;
1252     isjump;
1253     break;
1254     case i_SUB:
1255     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1256     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1257     genflags (flag_sub, curi->size, "", "src", "dst");
1258     genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1259     break;
1260     case i_SUBA:
1261     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1262     genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1263     start_brace();
1264     comprintf("\tint tmp=scratchie++;\n");
1265     switch(curi->size) {
1266     case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
1267     case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
1268     case sz_long: comprintf("\ttmp=src;\n"); break;
1269     default: abort();
1270     }
1271     comprintf("\tsub_l(dst,tmp);\n");
1272     genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1273     break;
1274     case i_SUBX:
1275     isaddx;
1276     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1277     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1278     genflags (flag_subx, curi->size, "", "src", "dst");
1279     genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1280     break;
1281     case i_SBCD:
1282     failure;
1283     /* I don't think so! */
1284     break;
1285     case i_ADD:
1286     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1287     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1288     genflags (flag_add, curi->size, "", "src", "dst");
1289     genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1290     break;
1291     case i_ADDA:
1292     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1293     genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1294     start_brace();
1295     comprintf("\tint tmp=scratchie++;\n");
1296     switch(curi->size) {
1297     case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break;
1298     case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break;
1299     case sz_long: comprintf("\ttmp=src;\n"); break;
1300     default: abort();
1301     }
1302     comprintf("\tadd_l(dst,tmp);\n");
1303     genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1304     break;
1305     case i_ADDX:
1306     isaddx;
1307     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1308     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1309     start_brace();
1310     genflags (flag_addx, curi->size, "", "src", "dst");
1311     genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1312     break;
1313     case i_ABCD:
1314     failure;
1315     /* No BCD maths for me.... */
1316     break;
1317     case i_NEG:
1318     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1319     start_brace ();
1320     comprintf("\tint dst=scratchie++;\n");
1321     comprintf("\tmov_l_ri(dst,0);\n");
1322     genflags (flag_sub, curi->size, "", "src", "dst");
1323     genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1324     break;
1325     case i_NEGX:
1326     isaddx;
1327     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1328     start_brace ();
1329     comprintf("\tint dst=scratchie++;\n");
1330     comprintf("\tmov_l_ri(dst,0);\n");
1331     genflags (flag_subx, curi->size, "", "src", "dst");
1332     genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1333     break;
1334    
1335     case i_NBCD:
1336     failure;
1337     /* Nope! */
1338     break;
1339     case i_CLR:
1340     genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1341     start_brace();
1342     comprintf("\tint dst=scratchie++;\n");
1343     comprintf("\tmov_l_ri(dst,0);\n");
1344     genflags (flag_logical, curi->size, "dst", "", "");
1345     genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1346     break;
1347     case i_NOT:
1348     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1349     start_brace ();
1350     comprintf("\tint dst=scratchie++;\n");
1351     comprintf("\tmov_l_ri(dst,0xffffffff);\n");
1352     genflags (flag_eor, curi->size, "", "src", "dst");
1353     genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1354     break;
1355     case i_TST:
1356     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1357     genflags (flag_logical, curi->size, "src", "", "");
1358     break;
1359     case i_BCHG:
1360     case i_BCLR:
1361     case i_BSET:
1362     case i_BTST:
1363     /* failure; /* NEW: from "Ipswitch Town" release */
1364     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1365     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1366     start_brace();
1367     comprintf("\tint s=scratchie++;\n"
1368     "\tmov_l_rr(s,src);\n");
1369     if (curi->size == sz_byte)
1370     comprintf("\tand_l_ri(s,7);\n");
1371     else
1372     comprintf("\tand_l_ri(s,31);\n");
1373    
1374     {
1375     char* op;
1376     int need_write=1;
1377    
1378     switch(curi->mnemo) {
1379     case i_BCHG: op="btc"; break;
1380     case i_BCLR: op="btr"; break;
1381     case i_BSET: op="bts"; break;
1382     case i_BTST: op="bt"; need_write=0; break;
1383     }
1384     comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */
1385 gbeauche 1.4 "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */
1386     "\tmake_flags_live();\n" /* Get the flags back */
1387     "\tdont_care_flags();\n",op);
1388     if (!noflags) {
1389     comprintf("\tstart_needflags();\n"
1390     "\tsetzflg_l(s);\n"
1391     "\tlive_flags();\n"
1392     "\tend_needflags();\n");
1393     }
1394 gbeauche 1.1 if (need_write)
1395     genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1396     }
1397     break;
1398    
1399     case i_CMPM:
1400     case i_CMP:
1401     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1402     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1403     start_brace ();
1404     genflags (flag_cmp, curi->size, "", "src", "dst");
1405     break;
1406     case i_CMPA:
1407     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1408     genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1409     start_brace();
1410     comprintf("\tint tmps=scratchie++;\n");
1411     switch(curi->size) {
1412     case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break;
1413     case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break;
1414     case sz_long: comprintf("tmps=src;\n"); break;
1415     default: abort();
1416     }
1417     genflags (flag_cmp, sz_long, "", "tmps", "dst");
1418     break;
1419     /* The next two are coded a little unconventional, but they are doing
1420     * weird things... */
1421     case i_MVPRM:
1422     isjump;
1423     failure;
1424     break;
1425     case i_MVPMR:
1426     isjump;
1427     failure;
1428     break;
1429     case i_MOVE:
1430     switch(curi->dmode) {
1431     case Dreg:
1432     case Areg:
1433     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1434     genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1435     genflags (flag_mov, curi->size, "", "src", "dst");
1436     genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1437     break;
1438     default: /* It goes to memory, not a register */
1439     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1440     genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1441     genflags (flag_logical, curi->size, "src", "", "");
1442     genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1443     break;
1444     }
1445     break;
1446     case i_MOVEA:
1447     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1448     genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1449    
1450     start_brace();
1451     comprintf("\tint tmps=scratchie++;\n");
1452     switch(curi->size) {
1453     case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break;
1454     case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break;
1455     default: abort();
1456     }
1457     genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1458     break;
1459    
1460     case i_MVSR2:
1461     isjump;
1462     failure;
1463     break;
1464     case i_MV2SR:
1465     isjump;
1466     failure;
1467     break;
1468     case i_SWAP:
1469     genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1470     comprintf("\tdont_care_flags();\n");
1471     comprintf("\trol_l_ri(src,16);\n");
1472     genflags (flag_logical, sz_long, "src", "", "");
1473     genastore ("src", curi->smode, "srcreg", sz_long, "src");
1474     break;
1475     case i_EXG:
1476     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1477     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
1478     start_brace();
1479     comprintf("\tint tmp=scratchie++;\n"
1480     "\tmov_l_rr(tmp,src);\n");
1481     genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1482     genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst");
1483     break;
1484     case i_EXT:
1485     genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1486     comprintf("\tdont_care_flags();\n");
1487     start_brace ();
1488     switch (curi->size)
1489     {
1490     case sz_byte:
1491     comprintf ("\tint dst = src;\n"
1492     "\tsign_extend_8_rr(src,src);\n");
1493     break;
1494     case sz_word:
1495     comprintf ("\tint dst = scratchie++;\n"
1496     "\tsign_extend_8_rr(dst,src);\n");
1497     break;
1498     case sz_long:
1499     comprintf ("\tint dst = src;\n"
1500     "\tsign_extend_16_rr(src,src);\n");
1501     break;
1502     default:
1503     abort ();
1504     }
1505     genflags (flag_logical,
1506     curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
1507     genastore ("dst", curi->smode, "srcreg",
1508     curi->size == sz_word ? sz_word : sz_long, "src");
1509     break;
1510     case i_MVMEL:
1511     genmovemel (opcode);
1512     break;
1513     case i_MVMLE:
1514     genmovemle (opcode);
1515     break;
1516     case i_TRAP:
1517     isjump;
1518     failure;
1519     break;
1520     case i_MVR2USP:
1521     isjump;
1522     failure;
1523     break;
1524     case i_MVUSP2R:
1525     isjump;
1526     failure;
1527     break;
1528     case i_RESET:
1529     isjump;
1530     failure;
1531     break;
1532     case i_NOP:
1533     break;
1534     case i_STOP:
1535     isjump;
1536     failure;
1537     break;
1538     case i_RTE:
1539     isjump;
1540     failure;
1541     break;
1542     case i_RTD:
1543     /* failure; /* NEW: from "Ipswitch Town" release */
1544     genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0);
1545     /* offs is constant */
1546     comprintf("\tadd_l_ri(offs,4);\n");
1547     start_brace();
1548     comprintf("\tint newad=scratchie++;\n"
1549     "\treadlong(15,newad,scratchie);\n"
1550     "\tmov_l_mr((uae_u32)&regs.pc,newad);\n"
1551     "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1552     "\tmov_l_mr((uae_u32)&regs.pc_oldp,PC_P);\n"
1553     "\tm68k_pc_offset=0;\n"
1554     "\tadd_l(15,offs);\n");
1555     gen_update_next_handler();
1556     isjump;
1557     break;
1558     case i_LINK:
1559     /* failure; /* NEW: from "Ipswitch Town" release */
1560     genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
1561     genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1562     comprintf("\tsub_l_ri(15,4);\n"
1563     "\twritelong_clobber(15,src,scratchie);\n"
1564     "\tmov_l_rr(src,15);\n");
1565     if (curi->size==sz_word)
1566     comprintf("\tsign_extend_16_rr(offs,offs);\n");
1567     comprintf("\tadd_l(15,offs);\n");
1568     genastore ("src", curi->smode, "srcreg", sz_long, "src");
1569     break;
1570     case i_UNLK:
1571     /* failure; /* NEW: from "Ipswitch Town" release */
1572     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1573     comprintf("\tmov_l_rr(15,src);\n"
1574     "\treadlong(15,src,scratchie);\n"
1575     "\tadd_l_ri(15,4);\n");
1576     genastore ("src", curi->smode, "srcreg", curi->size, "src");
1577     break;
1578     case i_RTS:
1579     comprintf("\tint newad=scratchie++;\n"
1580     "\treadlong(15,newad,scratchie);\n"
1581     "\tmov_l_mr((uae_u32)&regs.pc,newad);\n"
1582     "\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
1583     "\tmov_l_mr((uae_u32)&regs.pc_oldp,PC_P);\n"
1584     "\tm68k_pc_offset=0;\n"
1585     "\tlea_l_brr(15,15,4);\n");
1586     gen_update_next_handler();
1587     isjump;
1588     break;
1589     case i_TRAPV:
1590     isjump;
1591     failure;
1592     break;
1593     case i_RTR:
1594     isjump;
1595     failure;
1596     break;
1597     case i_JSR:
1598     isjump;
1599     genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1600     start_brace();
1601     comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
1602     comprintf("\tint ret=scratchie++;\n"
1603     "\tmov_l_ri(ret,retadd);\n"
1604     "\tsub_l_ri(15,4);\n"
1605     "\twritelong_clobber(15,ret,scratchie);\n");
1606     comprintf("\tmov_l_mr((uae_u32)&regs.pc,srca);\n"
1607     "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1608     "\tmov_l_mr((uae_u32)&regs.pc_oldp,PC_P);\n"
1609     "\tm68k_pc_offset=0;\n");
1610     gen_update_next_handler();
1611     break;
1612     case i_JMP:
1613     isjump;
1614     genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1615     comprintf("\tmov_l_mr((uae_u32)&regs.pc,srca);\n"
1616     "\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
1617     "\tmov_l_mr((uae_u32)&regs.pc_oldp,PC_P);\n"
1618     "\tm68k_pc_offset=0;\n");
1619     gen_update_next_handler();
1620     break;
1621     case i_BSR:
1622     is_const_jump;
1623     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1624     start_brace();
1625     comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
1626     comprintf("\tint ret=scratchie++;\n"
1627     "\tmov_l_ri(ret,retadd);\n"
1628     "\tsub_l_ri(15,4);\n"
1629     "\twritelong_clobber(15,ret,scratchie);\n");
1630     comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n");
1631     comprintf("\tm68k_pc_offset=0;\n");
1632     comprintf("\tadd_l(PC_P,src);\n");
1633    
1634     comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n");
1635     break;
1636     case i_Bcc:
1637     comprintf("\tuae_u32 v,v1,v2;\n");
1638     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1639     /* That source is an immediate, so we can clobber it with abandon */
1640     switch(curi->size) {
1641     case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break;
1642     case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break;
1643     case sz_long: break;
1644     }
1645     comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
1646     /* Leave the following as "add" --- it will allow it to be optimized
1647     away due to src being a constant ;-) */
1648     comprintf("\tadd_l_ri(src,(uae_u32)comp_pc_p);\n");
1649     comprintf("\tmov_l_ri(PC_P,(uae_u32)comp_pc_p);\n");
1650     /* Now they are both constant. Might as well fold in m68k_pc_offset */
1651     comprintf("\tadd_l_ri(src,m68k_pc_offset);\n");
1652     comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
1653     comprintf("\tm68k_pc_offset=0;\n");
1654    
1655     if (curi->cc>=2) {
1656     comprintf("\tv1=get_const(PC_P);\n"
1657     "\tv2=get_const(src);\n"
1658     "\tregister_branch(v1,v2,%d);\n",
1659     cond_codes_x86[curi->cc]);
1660     comprintf("\tmake_flags_live();\n"); /* Load the flags */
1661     isjump;
1662     }
1663     else {
1664     is_const_jump;
1665     }
1666    
1667     switch(curi->cc) {
1668     case 0: /* Unconditional jump */
1669     comprintf("\tmov_l_rr(PC_P,src);\n");
1670     comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n");
1671     break;
1672     case 1: break; /* This is silly! */
1673     case 8: failure; break; /* Work out details! FIXME */
1674     case 9: failure; break; /* Not critical, though! */
1675    
1676     case 2:
1677     case 3:
1678     case 4:
1679     case 5:
1680     case 6:
1681     case 7:
1682     case 10:
1683     case 11:
1684     case 12:
1685     case 13:
1686     case 14:
1687     case 15:
1688     break;
1689     default: abort();
1690     }
1691     break;
1692     case i_LEA:
1693     genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1694     genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0);
1695     genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
1696     break;
1697     case i_PEA:
1698     if (table68k[opcode].smode==Areg ||
1699     table68k[opcode].smode==Aind ||
1700     table68k[opcode].smode==Aipi ||
1701     table68k[opcode].smode==Apdi ||
1702     table68k[opcode].smode==Ad16 ||
1703     table68k[opcode].smode==Ad8r)
1704     comprintf("if (srcreg==7) dodgy=1;\n");
1705    
1706     genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
1707     genamode (Apdi, "7", sz_long, "dst", 2, 0);
1708     genastore ("srca", Apdi, "7", sz_long, "dst");
1709     break;
1710     case i_DBcc:
1711     isjump;
1712     uses_cmov;
1713     genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
1714     genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
1715    
1716     /* That offs is an immediate, so we can clobber it with abandon */
1717     switch(curi->size) {
1718     case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break;
1719     default: abort(); /* Seems this only comes in word flavour */
1720     }
1721     comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n");
1722     comprintf("\tadd_l_ri(offs,(uae_u32)comp_pc_p);\n"); /* New PC,
1723     once the
1724     offset_68k is
1725     * also added */
1726     /* Let's fold in the m68k_pc_offset at this point */
1727     comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n");
1728     comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n");
1729     comprintf("\tm68k_pc_offset=0;\n");
1730    
1731     start_brace();
1732     comprintf("\tint nsrc=scratchie++;\n");
1733    
1734     if (curi->cc>=2) {
1735     comprintf("\tmake_flags_live();\n"); /* Load the flags */
1736     }
1737    
1738     if (curi->size!=sz_word)
1739     abort();
1740    
1741    
1742     switch(curi->cc) {
1743     case 0: /* This is an elaborate nop? */
1744     break;
1745     case 1:
1746     comprintf("\tstart_needflags();\n");
1747     comprintf("\tsub_w_ri(src,1);\n");
1748     comprintf("\t end_needflags();\n");
1749     start_brace();
1750     comprintf("\tuae_u32 v2,v;\n"
1751     "\tuae_u32 v1=get_const(PC_P);\n");
1752     comprintf("\tv2=get_const(offs);\n"
1753     "\tregister_branch(v1,v2,3);\n");
1754     break;
1755    
1756     case 8: failure; break; /* Work out details! FIXME */
1757     case 9: failure; break; /* Not critical, though! */
1758    
1759     case 2:
1760     case 3:
1761     case 4:
1762     case 5:
1763     case 6:
1764     case 7:
1765     case 10:
1766     case 11:
1767     case 12:
1768     case 13:
1769     case 14:
1770     case 15:
1771     comprintf("\tmov_l_rr(nsrc,src);\n");
1772     comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n"
1773     "\tmov_w_rr(src,scratchie);\n");
1774     comprintf("\tcmov_l_rr(offs,PC_P,%d);\n",
1775     cond_codes_x86[curi->cc]);
1776     comprintf("\tcmov_l_rr(src,nsrc,%d);\n",
1777     cond_codes_x86[curi->cc]);
1778     /* OK, now for cc=true, we have src==nsrc and offs==PC_P,
1779     so whether we move them around doesn't matter. However,
1780     if cc=false, we have offs==jump_pc, and src==nsrc-1 */
1781    
1782     comprintf("\t start_needflags();\n");
1783     comprintf("\ttest_w_rr(nsrc,nsrc);\n");
1784     comprintf("\t end_needflags();\n");
1785     comprintf("\tcmov_l_rr(PC_P,offs,5);\n");
1786     break;
1787     default: abort();
1788     }
1789     genastore ("src", curi->smode, "srcreg", curi->size, "src");
1790     gen_update_next_handler();
1791     break;
1792    
1793     case i_Scc:
1794     /* failure; /* NEW: from "Ipswitch Town" release */
1795     genamode (curi->smode, "srcreg", curi->size, "src", 2, 0);
1796     start_brace ();
1797     comprintf ("\tint val = scratchie++;\n");
1798    
1799     /* We set val to 0 if we really should use 255, and to 1 for real 0 */
1800     switch(curi->cc) {
1801     case 0: /* Unconditional set */
1802     comprintf("\tmov_l_ri(val,0);\n");
1803     break;
1804     case 1:
1805     /* Unconditional not-set */
1806     comprintf("\tmov_l_ri(val,1);\n");
1807     break;
1808     case 8: failure; break; /* Work out details! FIXME */
1809     case 9: failure; break; /* Not critical, though! */
1810    
1811     case 2:
1812     case 3:
1813     case 4:
1814     case 5:
1815     case 6:
1816     case 7:
1817     case 10:
1818     case 11:
1819     case 12:
1820     case 13:
1821     case 14:
1822     case 15:
1823     comprintf("\tmake_flags_live();\n"); /* Load the flags */
1824     /* All condition codes can be inverted by changing the LSB */
1825     comprintf("\tsetcc(val,%d);\n",
1826     cond_codes_x86[curi->cc]^1); break;
1827     default: abort();
1828     }
1829     comprintf("\tsub_b_ri(val,1);\n");
1830     genastore ("val", curi->smode, "srcreg", curi->size, "src");
1831     break;
1832     case i_DIVU:
1833     isjump;
1834     failure;
1835     break;
1836     case i_DIVS:
1837     isjump;
1838     failure;
1839     break;
1840     case i_MULU:
1841     /* failure; /* NEW: from "Ipswitch Town" release */
1842     comprintf("\tdont_care_flags();\n");
1843     genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1844     genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
1845     /* To do 16x16 unsigned multiplication, we actually use
1846     32x32 signed, and zero-extend the registers first.
1847     That solves the problem of MUL needing dedicated registers
1848     on the x86 */
1849     comprintf("\tzero_extend_16_rr(scratchie,src);\n"
1850     "\tzero_extend_16_rr(dst,dst);\n"
1851     "\timul_32_32(dst,scratchie);\n");
1852     genflags (flag_logical, sz_long, "dst", "", "");
1853     genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1854     break;
1855     case i_MULS:
1856     /* failure; /* NEW: from "Ipswitch Town" release */
1857     comprintf("\tdont_care_flags();\n");
1858     genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
1859     genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0);
1860     comprintf("\tsign_extend_16_rr(scratchie,src);\n"
1861     "\tsign_extend_16_rr(dst,dst);\n"
1862     "\timul_32_32(dst,scratchie);\n");
1863     genflags (flag_logical, sz_long, "dst", "", "");
1864     genastore ("dst", curi->dmode, "dstreg", sz_long, "dst");
1865     break;
1866     case i_CHK:
1867     isjump;
1868     failure;
1869     break;
1870    
1871     case i_CHK2:
1872     isjump;
1873     failure;
1874     break;
1875    
1876     case i_ASR:
1877     mayfail;
1878     if (curi->smode==Dreg) {
1879     comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
1880     " FAIL(1);\n"
1881     " return;\n"
1882     "} \n");
1883     start_brace();
1884     }
1885     comprintf("\tdont_care_flags();\n");
1886    
1887     genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
1888     genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
1889     if (curi->smode!=immi) {
1890     /* failure; /* UNTESTED: NEW: from "Ipswitch Town" release */
1891     if (!noflags) {
1892     uses_cmov;
1893     start_brace();
1894     comprintf("\tint highmask;\n"
1895     "\tint width;\n"
1896     "\tint cdata=scratchie++;\n"
1897     "\tint tmpcnt=scratchie++;\n"
1898     "\tint highshift=scratchie++;\n");
1899     comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
1900     "\tand_l_ri(tmpcnt,63);\n"
1901     "\tmov_l_ri(cdata,0);\n"
1902     "\tcmov_l_rr(cdata,data,5);\n");
1903     /* cdata is now either data (for shift count!=0) or
1904     0 (for shift count==0) */
1905     switch(curi->size) {
1906     case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
1907     "\thighmask=0x38;\n"
1908     "\twidth=8;\n");
1909     break;
1910     case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
1911     "\thighmask=0x30;\n"
1912     "\twidth=16;\n");
1913     break;
1914     case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
1915     "\thighmask=0x20;\n"
1916     "\twidth=32;\n");
1917     break;
1918     default: abort();
1919     }
1920     comprintf("test_l_ri(cnt,highmask);\n"
1921     "mov_l_ri(highshift,0);\n"
1922     "mov_l_ri(scratchie,width/2);\n"
1923     "cmov_l_rr(highshift,scratchie,5);\n");
1924     /* The x86 masks out bits, so we now make sure that things
1925     really get shifted as much as planned */
1926     switch(curi->size) {
1927     case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
1928     case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
1929     case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
1930     default: abort();
1931     }
1932     /* And again */
1933     switch(curi->size) {
1934     case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
1935     case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
1936     case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
1937     default: abort();
1938     }
1939    
1940     /* Result of shift is now in data. Now we need to determine
1941     the carry by shifting cdata one less */
1942     comprintf("\tsub_l_ri(tmpcnt,1);\n");
1943     switch(curi->size) {
1944     case sz_byte: comprintf("\tshra_b_rr(cdata,tmpcnt);\n");break;
1945     case sz_word: comprintf("\tshra_w_rr(cdata,tmpcnt);\n");break;
1946     case sz_long: comprintf("\tshra_l_rr(cdata,tmpcnt);\n");break;
1947     default: abort();
1948     }
1949     /* If the shift count was higher than the width, we need
1950     to pick up the sign from data */
1951     comprintf("test_l_ri(tmpcnt,highmask);\n"
1952     "cmov_l_rr(cdata,data,5);\n");
1953     /* And create the flags */
1954     comprintf("\tstart_needflags();\n");
1955     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
1956     switch(curi->size) {
1957     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
1958     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
1959     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
1960     }
1961     comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
1962     comprintf("\t live_flags();\n");
1963     comprintf("\t end_needflags();\n");
1964     comprintf("\t duplicate_carry();\n");
1965     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
1966     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
1967     }
1968     else {
1969     uses_cmov;
1970     start_brace();
1971     comprintf("\tint highmask;\n"
1972     "\tint width;\n"
1973     "\tint highshift=scratchie++;\n");
1974     switch(curi->size) {
1975     case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n"
1976     "\thighmask=0x38;\n"
1977     "\twidth=8;\n");
1978     break;
1979     case sz_word: comprintf("\tshra_w_rr(data,cnt);\n"
1980     "\thighmask=0x30;\n"
1981     "\twidth=16;\n");
1982     break;
1983     case sz_long: comprintf("\tshra_l_rr(data,cnt);\n"
1984     "\thighmask=0x20;\n"
1985     "\twidth=32;\n");
1986     break;
1987     default: abort();
1988     }
1989     comprintf("test_l_ri(cnt,highmask);\n"
1990     "mov_l_ri(highshift,0);\n"
1991     "mov_l_ri(scratchie,width/2);\n"
1992     "cmov_l_rr(highshift,scratchie,5);\n");
1993     /* The x86 masks out bits, so we now make sure that things
1994     really get shifted as much as planned */
1995     switch(curi->size) {
1996     case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
1997     case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
1998     case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
1999     default: abort();
2000     }
2001     /* And again */
2002     switch(curi->size) {
2003     case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break;
2004     case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break;
2005     case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break;
2006     default: abort();
2007     }
2008     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2009     }
2010     }
2011     else {
2012     start_brace();
2013     comprintf("\tint tmp=scratchie++;\n"
2014     "\tint bp;\n"
2015     "\tmov_l_rr(tmp,data);\n");
2016     switch(curi->size) {
2017     case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n"
2018     "\tbp=srcreg-1;\n"); break;
2019     case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n"
2020     "\tbp=srcreg-1;\n"); break;
2021     case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n"
2022     "\tbp=srcreg-1;\n"); break;
2023     default: abort();
2024     }
2025    
2026     if (!noflags) {
2027     comprintf("\tstart_needflags();\n");
2028     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2029     switch(curi->size) {
2030     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2031     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2032     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2033     }
2034     comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2035     comprintf("\t live_flags();\n");
2036     comprintf("\t end_needflags();\n");
2037     comprintf("\t duplicate_carry();\n");
2038     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2039     }
2040     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2041     }
2042     break;
2043    
2044     case i_ASL:
2045     /* failure; /* NEW: from "Ipswitch Town" release */
2046     mayfail;
2047     if (curi->smode==Dreg) {
2048     comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2049     " FAIL(1);\n"
2050     " return;\n"
2051     "} \n");
2052     start_brace();
2053     }
2054     comprintf("\tdont_care_flags();\n");
2055     /* Except for the handling of the V flag, this is identical to
2056     LSL. The handling of V is, uhm, unpleasant, so if it's needed,
2057     let the normal emulation handle it. Shoulders of giants kinda
2058     thing ;-) */
2059     comprintf("if (needed_flags & FLAG_V) {\n"
2060     " FAIL(1);\n"
2061     " return;\n"
2062     "} \n");
2063    
2064     genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2065     genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2066     if (curi->smode!=immi) {
2067     if (!noflags) {
2068     uses_cmov;
2069     start_brace();
2070     comprintf("\tint highmask;\n"
2071     "\tint cdata=scratchie++;\n"
2072     "\tint tmpcnt=scratchie++;\n");
2073     comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
2074     "\tand_l_ri(tmpcnt,63);\n"
2075     "\tmov_l_ri(cdata,0);\n"
2076     "\tcmov_l_rr(cdata,data,5);\n");
2077     /* cdata is now either data (for shift count!=0) or
2078     0 (for shift count==0) */
2079     switch(curi->size) {
2080     case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2081     "\thighmask=0x38;\n");
2082     break;
2083     case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2084     "\thighmask=0x30;\n");
2085     break;
2086     case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2087     "\thighmask=0x20;\n");
2088     break;
2089     default: abort();
2090     }
2091     comprintf("test_l_ri(cnt,highmask);\n"
2092     "mov_l_ri(scratchie,0);\n"
2093     "cmov_l_rr(scratchie,data,4);\n");
2094     switch(curi->size) {
2095     case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2096     case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2097     case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2098     default: abort();
2099     }
2100     /* Result of shift is now in data. Now we need to determine
2101     the carry by shifting cdata one less */
2102     comprintf("\tsub_l_ri(tmpcnt,1);\n");
2103     switch(curi->size) {
2104     case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break;
2105     case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break;
2106     case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break;
2107     default: abort();
2108     }
2109     comprintf("test_l_ri(tmpcnt,highmask);\n"
2110     "mov_l_ri(scratchie,0);\n"
2111     "cmov_l_rr(cdata,scratchie,5);\n");
2112     /* And create the flags */
2113     comprintf("\tstart_needflags();\n");
2114    
2115     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2116     switch(curi->size) {
2117     case sz_byte: comprintf("\t test_b_rr(data,data);\n");
2118     comprintf("\t bt_l_ri(cdata,7);\n"); break;
2119     case sz_word: comprintf("\t test_w_rr(data,data);\n");
2120     comprintf("\t bt_l_ri(cdata,15);\n"); break;
2121     case sz_long: comprintf("\t test_l_rr(data,data);\n");
2122     comprintf("\t bt_l_ri(cdata,31);\n"); break;
2123     }
2124     comprintf("\t live_flags();\n");
2125     comprintf("\t end_needflags();\n");
2126     comprintf("\t duplicate_carry();\n");
2127     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2128     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2129     }
2130     else {
2131     uses_cmov;
2132     start_brace();
2133     comprintf("\tint highmask;\n");
2134     switch(curi->size) {
2135     case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2136     "\thighmask=0x38;\n");
2137     break;
2138     case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2139     "\thighmask=0x30;\n");
2140     break;
2141     case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2142     "\thighmask=0x20;\n");
2143     break;
2144     default: abort();
2145     }
2146     comprintf("test_l_ri(cnt,highmask);\n"
2147     "mov_l_ri(scratchie,0);\n"
2148     "cmov_l_rr(scratchie,data,4);\n");
2149     switch(curi->size) {
2150     case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2151     case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2152     case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2153     default: abort();
2154     }
2155     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2156     }
2157     }
2158     else {
2159     start_brace();
2160     comprintf("\tint tmp=scratchie++;\n"
2161     "\tint bp;\n"
2162     "\tmov_l_rr(tmp,data);\n");
2163     switch(curi->size) {
2164     case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"
2165     "\tbp=8-srcreg;\n"); break;
2166     case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"
2167     "\tbp=16-srcreg;\n"); break;
2168     case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"
2169     "\tbp=32-srcreg;\n"); break;
2170     default: abort();
2171     }
2172    
2173     if (!noflags) {
2174     comprintf("\tstart_needflags();\n");
2175     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2176     switch(curi->size) {
2177     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2178     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2179     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2180     }
2181     comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2182     comprintf("\t live_flags();\n");
2183     comprintf("\t end_needflags();\n");
2184     comprintf("\t duplicate_carry();\n");
2185     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2186     }
2187     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2188     }
2189     break;
2190    
2191     case i_LSR:
2192     /* failure; /* NEW: from "Ipswitch Town" release */
2193     mayfail;
2194     if (curi->smode==Dreg) {
2195     comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2196     " FAIL(1);\n"
2197     " return;\n"
2198     "} \n");
2199     start_brace();
2200     }
2201     comprintf("\tdont_care_flags();\n");
2202    
2203     genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2204     genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2205     if (curi->smode!=immi) {
2206     if (!noflags) {
2207     uses_cmov;
2208     start_brace();
2209     comprintf("\tint highmask;\n"
2210     "\tint cdata=scratchie++;\n"
2211     "\tint tmpcnt=scratchie++;\n");
2212     comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
2213     "\tand_l_ri(tmpcnt,63);\n"
2214     "\tmov_l_ri(cdata,0);\n"
2215     "\tcmov_l_rr(cdata,data,5);\n");
2216     /* cdata is now either data (for shift count!=0) or
2217     0 (for shift count==0) */
2218     switch(curi->size) {
2219     case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
2220     "\thighmask=0x38;\n");
2221     break;
2222     case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
2223     "\thighmask=0x30;\n");
2224     break;
2225     case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
2226     "\thighmask=0x20;\n");
2227     break;
2228     default: abort();
2229     }
2230     comprintf("test_l_ri(cnt,highmask);\n"
2231     "mov_l_ri(scratchie,0);\n"
2232     "cmov_l_rr(scratchie,data,4);\n");
2233     switch(curi->size) {
2234     case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2235     case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2236     case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2237     default: abort();
2238     }
2239     /* Result of shift is now in data. Now we need to determine
2240     the carry by shifting cdata one less */
2241     comprintf("\tsub_l_ri(tmpcnt,1);\n");
2242     switch(curi->size) {
2243     case sz_byte: comprintf("\tshrl_b_rr(cdata,tmpcnt);\n");break;
2244     case sz_word: comprintf("\tshrl_w_rr(cdata,tmpcnt);\n");break;
2245     case sz_long: comprintf("\tshrl_l_rr(cdata,tmpcnt);\n");break;
2246     default: abort();
2247     }
2248     comprintf("test_l_ri(tmpcnt,highmask);\n"
2249     "mov_l_ri(scratchie,0);\n"
2250     "cmov_l_rr(cdata,scratchie,5);\n");
2251     /* And create the flags */
2252     comprintf("\tstart_needflags();\n");
2253     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2254     switch(curi->size) {
2255     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2256     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2257     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2258     }
2259     comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */
2260     comprintf("\t live_flags();\n");
2261     comprintf("\t end_needflags();\n");
2262     comprintf("\t duplicate_carry();\n");
2263     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2264     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2265     }
2266     else {
2267     uses_cmov;
2268     start_brace();
2269     comprintf("\tint highmask;\n");
2270     switch(curi->size) {
2271     case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n"
2272     "\thighmask=0x38;\n");
2273     break;
2274     case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n"
2275     "\thighmask=0x30;\n");
2276     break;
2277     case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n"
2278     "\thighmask=0x20;\n");
2279     break;
2280     default: abort();
2281     }
2282     comprintf("test_l_ri(cnt,highmask);\n"
2283     "mov_l_ri(scratchie,0);\n"
2284     "cmov_l_rr(scratchie,data,4);\n");
2285     switch(curi->size) {
2286     case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2287     case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2288     case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2289     default: abort();
2290     }
2291     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2292     }
2293     }
2294     else {
2295     start_brace();
2296     comprintf("\tint tmp=scratchie++;\n"
2297     "\tint bp;\n"
2298     "\tmov_l_rr(tmp,data);\n");
2299     switch(curi->size) {
2300     case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n"
2301     "\tbp=srcreg-1;\n"); break;
2302     case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n"
2303     "\tbp=srcreg-1;\n"); break;
2304     case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n"
2305     "\tbp=srcreg-1;\n"); break;
2306     default: abort();
2307     }
2308    
2309     if (!noflags) {
2310     comprintf("\tstart_needflags();\n");
2311     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2312     switch(curi->size) {
2313     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2314     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2315     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2316     }
2317     comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2318     comprintf("\t live_flags();\n");
2319     comprintf("\t end_needflags();\n");
2320     comprintf("\t duplicate_carry();\n");
2321     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2322     }
2323     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2324     }
2325     break;
2326    
2327     case i_LSL:
2328     mayfail;
2329     if (curi->smode==Dreg) {
2330     comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2331     " FAIL(1);\n"
2332     " return;\n"
2333     "} \n");
2334     start_brace();
2335     }
2336     comprintf("\tdont_care_flags();\n");
2337    
2338     genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2339     genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2340     if (curi->smode!=immi) {
2341     /* failure; /* UNTESTED: NEW: from "Ipswitch Town" release */
2342     if (!noflags) {
2343     uses_cmov;
2344     start_brace();
2345     comprintf("\tint highmask;\n"
2346     "\tint cdata=scratchie++;\n"
2347     "\tint tmpcnt=scratchie++;\n");
2348     comprintf("\tmov_l_rr(tmpcnt,cnt);\n"
2349     "\tand_l_ri(tmpcnt,63);\n"
2350     "\tmov_l_ri(cdata,0);\n"
2351     "\tcmov_l_rr(cdata,data,5);\n");
2352     /* cdata is now either data (for shift count!=0) or
2353     0 (for shift count==0) */
2354     switch(curi->size) {
2355     case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2356     "\thighmask=0x38;\n");
2357     break;
2358     case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2359     "\thighmask=0x30;\n");
2360     break;
2361     case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2362     "\thighmask=0x20;\n");
2363     break;
2364     default: abort();
2365     }
2366     comprintf("test_l_ri(cnt,highmask);\n"
2367     "mov_l_ri(scratchie,0);\n"
2368     "cmov_l_rr(scratchie,data,4);\n");
2369     switch(curi->size) {
2370     case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2371     case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2372     case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2373     default: abort();
2374     }
2375     /* Result of shift is now in data. Now we need to determine
2376     the carry by shifting cdata one less */
2377     comprintf("\tsub_l_ri(tmpcnt,1);\n");
2378     switch(curi->size) {
2379     case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break;
2380     case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break;
2381     case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break;
2382     default: abort();
2383     }
2384     comprintf("test_l_ri(tmpcnt,highmask);\n"
2385     "mov_l_ri(scratchie,0);\n"
2386     "cmov_l_rr(cdata,scratchie,5);\n");
2387     /* And create the flags */
2388     comprintf("\tstart_needflags();\n");
2389     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2390     switch(curi->size) {
2391     case sz_byte: comprintf("\t test_b_rr(data,data);\n");
2392     comprintf("\t bt_l_ri(cdata,7);\n"); break;
2393     case sz_word: comprintf("\t test_w_rr(data,data);\n");
2394     comprintf("\t bt_l_ri(cdata,15);\n"); break;
2395     case sz_long: comprintf("\t test_l_rr(data,data);\n");
2396     comprintf("\t bt_l_ri(cdata,31);\n"); break;
2397     }
2398     comprintf("\t live_flags();\n");
2399     comprintf("\t end_needflags();\n");
2400     comprintf("\t duplicate_carry();\n");
2401     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2402     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2403     }
2404     else {
2405     uses_cmov;
2406     start_brace();
2407     comprintf("\tint highmask;\n");
2408     switch(curi->size) {
2409     case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n"
2410     "\thighmask=0x38;\n");
2411     break;
2412     case sz_word: comprintf("\tshll_w_rr(data,cnt);\n"
2413     "\thighmask=0x30;\n");
2414     break;
2415     case sz_long: comprintf("\tshll_l_rr(data,cnt);\n"
2416     "\thighmask=0x20;\n");
2417     break;
2418     default: abort();
2419     }
2420     comprintf("test_l_ri(cnt,highmask);\n"
2421     "mov_l_ri(scratchie,0);\n"
2422     "cmov_l_rr(scratchie,data,4);\n");
2423     switch(curi->size) {
2424     case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break;
2425     case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break;
2426     case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break;
2427     default: abort();
2428     }
2429     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2430     }
2431     }
2432     else {
2433     start_brace();
2434     comprintf("\tint tmp=scratchie++;\n"
2435     "\tint bp;\n"
2436     "\tmov_l_rr(tmp,data);\n");
2437     switch(curi->size) {
2438     case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"
2439     "\tbp=8-srcreg;\n"); break;
2440     case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"
2441     "\tbp=16-srcreg;\n"); break;
2442     case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"
2443     "\tbp=32-srcreg;\n"); break;
2444     default: abort();
2445     }
2446    
2447     if (!noflags) {
2448     comprintf("\tstart_needflags();\n");
2449     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2450     switch(curi->size) {
2451     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2452     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2453     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2454     }
2455     comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */
2456     comprintf("\t live_flags();\n");
2457     comprintf("\t end_needflags();\n");
2458     comprintf("\t duplicate_carry();\n");
2459     comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n");
2460     }
2461     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2462     }
2463     break;
2464    
2465     case i_ROL:
2466     mayfail;
2467     if (curi->smode==Dreg) {
2468     comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2469     " FAIL(1);\n"
2470     " return;\n"
2471     "} \n");
2472     start_brace();
2473     }
2474     comprintf("\tdont_care_flags();\n");
2475     genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2476     genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2477     start_brace ();
2478    
2479     switch(curi->size) {
2480     case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break;
2481     case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break;
2482     case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break;
2483     }
2484    
2485     if (!noflags) {
2486     comprintf("\tstart_needflags();\n");
2487     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2488     switch(curi->size) {
2489     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2490     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2491     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2492     }
2493     comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */
2494     comprintf("\t live_flags();\n");
2495     comprintf("\t end_needflags();\n");
2496     }
2497     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2498     break;
2499    
2500     case i_ROR:
2501     mayfail;
2502     if (curi->smode==Dreg) {
2503     comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
2504     " FAIL(1);\n"
2505     " return;\n"
2506     "} \n");
2507     start_brace();
2508     }
2509     comprintf("\tdont_care_flags();\n");
2510     genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
2511     genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
2512     start_brace ();
2513    
2514     switch(curi->size) {
2515     case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break;
2516     case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break;
2517     case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break;
2518     }
2519    
2520     if (!noflags) {
2521     comprintf("\tstart_needflags();\n");
2522     comprintf("\tif (needed_flags & FLAG_ZNV)\n");
2523     switch(curi->size) {
2524     case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
2525     case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
2526     case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
2527     }
2528     switch(curi->size) {
2529     case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break;
2530     case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break;
2531     case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break;
2532     }
2533     comprintf("\t live_flags();\n");
2534     comprintf("\t end_needflags();\n");
2535     }
2536     genastore ("data", curi->dmode, "dstreg", curi->size, "data");
2537     break;
2538    
2539     case i_ROXL:
2540     failure;
2541     break;
2542     case i_ROXR:
2543     failure;
2544     break;
2545     case i_ASRW:
2546     failure;
2547     break;
2548     case i_ASLW:
2549     failure;
2550     break;
2551     case i_LSRW:
2552     failure;
2553     break;
2554     case i_LSLW:
2555     failure;
2556     break;
2557     case i_ROLW:
2558     failure;
2559     break;
2560     case i_RORW:
2561     failure;
2562     break;
2563     case i_ROXLW:
2564     failure;
2565     break;
2566     case i_ROXRW:
2567     failure;
2568     break;
2569     case i_MOVEC2:
2570     isjump;
2571     failure;
2572     break;
2573     case i_MOVE2C:
2574     isjump;
2575     failure;
2576     break;
2577     case i_CAS:
2578     failure;
2579     break;
2580     case i_CAS2:
2581     failure;
2582     break;
2583     case i_MOVES: /* ignore DFC and SFC because we have no MMU */
2584     isjump;
2585     failure;
2586     break;
2587     case i_BKPT: /* only needed for hardware emulators */
2588     isjump;
2589     failure;
2590     break;
2591     case i_CALLM: /* not present in 68030 */
2592     isjump;
2593     failure;
2594     break;
2595     case i_RTM: /* not present in 68030 */
2596     isjump;
2597     failure;
2598     break;
2599     case i_TRAPcc:
2600     isjump;
2601     failure;
2602     break;
2603     case i_DIVL:
2604     isjump;
2605     failure;
2606     break;
2607     case i_MULL:
2608     /* failure; /* NEW: from "Ipswitch Town" release */
2609     if (!noflags) {
2610     failure;
2611     break;
2612     }
2613     comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2614     comprintf("\tint r2=(extra>>12)&7;\n"
2615     "\tint tmp=scratchie++;\n");
2616    
2617     genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0);
2618     /* The two operands are in dst and r2 */
2619     comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */
2620     "\tint r3=(extra&7);\n"
2621     "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */
2622     comprintf("\tif (extra&0x0800) { \n" /* signed */
2623     "\t\timul_64_32(r2,r3);\n"
2624     "\t} else { \n"
2625     "\t\tmul_64_32(r2,r3);\n"
2626     "\t} \n");
2627     /* The result is in r2/tmp, with r2 holding the lower 32 bits */
2628     comprintf("\t} else {\n"); /* Only want 32 bit result */
2629     /* operands in dst and r2, result foes into r2 */
2630     /* shouldn't matter whether it's signed or unsigned?!? */
2631     comprintf("\timul_32_32(r2,dst);\n"
2632     "\t}\n");
2633     break;
2634    
2635     case i_BFTST:
2636     case i_BFEXTU:
2637     case i_BFCHG:
2638     case i_BFEXTS:
2639     case i_BFCLR:
2640     case i_BFFFO:
2641     case i_BFSET:
2642     case i_BFINS:
2643     failure;
2644     break;
2645     case i_PACK:
2646     failure;
2647     break;
2648     case i_UNPK:
2649     failure;
2650     break;
2651     case i_TAS:
2652     failure;
2653     break;
2654     case i_FPP:
2655     uses_fpu;
2656     #ifdef USE_JIT_FPU
2657     mayfail;
2658     comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2659     swap_opcode();
2660     comprintf("\tcomp_fpp_opp(opcode,extra);\n");
2661     #else
2662     failure;
2663     #endif
2664     break;
2665     case i_FBcc:
2666     uses_fpu;
2667     #ifdef USE_JIT_FPU
2668     isjump;
2669     uses_cmov;
2670     mayfail;
2671     swap_opcode();
2672     comprintf("\tcomp_fbcc_opp(opcode);\n");
2673     #else
2674     isjump;
2675     failure;
2676     #endif
2677     break;
2678     case i_FDBcc:
2679     uses_fpu;
2680     isjump;
2681     failure;
2682     break;
2683     case i_FScc:
2684     uses_fpu;
2685     #ifdef USE_JIT_FPU
2686     mayfail;
2687     uses_cmov;
2688     comprintf("\tuae_u16 extra=%s;\n",gen_nextiword());
2689     swap_opcode();
2690     comprintf("\tcomp_fscc_opp(opcode,extra);\n");
2691     #else
2692     failure;
2693     #endif
2694     break;
2695     case i_FTRAPcc:
2696     uses_fpu;
2697     isjump;
2698     failure;
2699     break;
2700     case i_FSAVE:
2701     uses_fpu;
2702     failure;
2703     break;
2704     case i_FRESTORE:
2705     uses_fpu;
2706     failure;
2707     break;
2708    
2709     case i_CINVL:
2710     case i_CINVP:
2711     case i_CINVA:
2712     isjump; /* Not really, but it's probably a good idea to stop
2713     translating at this point */
2714     failure;
2715     comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */
2716     break;
2717     case i_CPUSHL:
2718     case i_CPUSHP:
2719     case i_CPUSHA:
2720     isjump; /* Not really, but it's probably a good idea to stop
2721     translating at this point */
2722     failure;
2723     break;
2724     case i_MOVE16:
2725     genmov16(opcode, curi);
2726     break;
2727    
2728     case i_EMULOP_RETURN:
2729     isjump;
2730     failure;
2731     break;
2732    
2733     case i_EMULOP:
2734     failure;
2735     break;
2736    
2737     case i_MMUOP:
2738     isjump;
2739     failure;
2740     break;
2741     default:
2742     abort ();
2743     break;
2744     }
2745     comprintf("%s",endstr);
2746     finish_braces ();
2747     sync_m68k_pc ();
2748     if (global_mayfail)
2749     comprintf("\tif (failure) m68k_pc_offset=m68k_pc_offset_thisinst;\n");
2750     return global_failure;
2751     }
2752    
2753     static void
2754     generate_includes (FILE * f)
2755     {
2756     fprintf (f, "#include \"sysdeps.h\"\n");
2757     fprintf (f, "#include \"m68k.h\"\n");
2758     fprintf (f, "#include \"memory.h\"\n");
2759     fprintf (f, "#include \"readcpu.h\"\n");
2760     fprintf (f, "#include \"newcpu.h\"\n");
2761     fprintf (f, "#include \"comptbl.h\"\n");
2762     }
2763    
2764     static int postfix;
2765    
2766     static void
2767     generate_one_opcode (int rp, int noflags)
2768     {
2769     int i;
2770     uae_u16 smsk, dmsk;
2771     long int opcode = opcode_map[rp];
2772     int aborted=0;
2773     int have_srcreg=0;
2774     int have_dstreg=0;
2775    
2776     if (table68k[opcode].mnemo == i_ILLG
2777     || table68k[opcode].clev > cpu_level)
2778     return;
2779    
2780     for (i = 0; lookuptab[i].name[0]; i++)
2781     {
2782     if (table68k[opcode].mnemo == lookuptab[i].mnemo)
2783     break;
2784     }
2785    
2786     if (table68k[opcode].handler != -1)
2787     return;
2788    
2789     switch (table68k[opcode].stype)
2790     {
2791     case 0:
2792     smsk = 7;
2793     break;
2794     case 1:
2795     smsk = 255;
2796     break;
2797     case 2:
2798     smsk = 15;
2799     break;
2800     case 3:
2801     smsk = 7;
2802     break;
2803     case 4:
2804     smsk = 7;
2805     break;
2806     case 5:
2807     smsk = 63;
2808     break;
2809     case 6:
2810     smsk = 255;
2811     break;
2812     case 7:
2813     smsk = 3;
2814     break;
2815     default:
2816     abort ();
2817     }
2818     dmsk = 7;
2819    
2820     next_cpu_level = -1;
2821     if (table68k[opcode].suse
2822     && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
2823     && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
2824     && table68k[opcode].smode != absw && table68k[opcode].smode != absl
2825     && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
2826     {
2827     have_srcreg=1;
2828     if (table68k[opcode].spos == -1)
2829     {
2830     if (((int) table68k[opcode].sreg) >= 128)
2831     comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
2832     else
2833     comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg);
2834     }
2835     else
2836     {
2837     char source[100];
2838     int pos = table68k[opcode].spos;
2839    
2840     comprintf ("#ifdef HAVE_GET_WORD_UNSWAPPED\n");
2841    
2842     if (pos < 8 && (smsk >> (8 - pos)) != 0)
2843     sprintf (source, "(((opcode >> %d) | (opcode << %d)) & %d)",
2844     pos ^ 8, 8 - pos, dmsk);
2845     else if (pos != 8)
2846     sprintf (source, "((opcode >> %d) & %d)", pos ^ 8, smsk);
2847     else
2848     sprintf (source, "(opcode & %d)", smsk);
2849    
2850     if (table68k[opcode].stype == 3)
2851     comprintf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
2852     else if (table68k[opcode].stype == 1)
2853     comprintf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
2854     else
2855     comprintf ("\tuae_u32 srcreg = %s;\n", source);
2856    
2857     comprintf ("#else\n");
2858    
2859     if (pos)
2860     sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
2861     else
2862     sprintf (source, "(opcode & %d)", smsk);
2863    
2864     if (table68k[opcode].stype == 3)
2865     comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source);
2866     else if (table68k[opcode].stype == 1)
2867     comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
2868     else
2869     comprintf ("\tuae_s32 srcreg = %s;\n", source);
2870    
2871     comprintf ("#endif\n");
2872     }
2873     }
2874     if (table68k[opcode].duse
2875     /* Yes, the dmode can be imm, in case of LINK or DBcc */
2876     && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
2877     && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
2878     && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
2879     {
2880     have_dstreg=1;
2881     if (table68k[opcode].dpos == -1)
2882     {
2883     if (((int) table68k[opcode].dreg) >= 128)
2884     comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
2885     else
2886     comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg);
2887     }
2888     else
2889     {
2890     int pos = table68k[opcode].dpos;
2891    
2892     comprintf ("#ifdef HAVE_GET_WORD_UNSWAPPED\n");
2893    
2894     if (pos < 8 && (dmsk >> (8 - pos)) != 0)
2895     comprintf ("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n",
2896     pos ^ 8, 8 - pos, dmsk);
2897     else if (pos != 8)
2898     comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
2899     pos ^ 8, dmsk);
2900     else
2901     comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
2902    
2903     comprintf ("#else\n");
2904    
2905     if (pos)
2906     comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
2907     pos, dmsk);
2908     else
2909     comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
2910    
2911     comprintf ("#endif\n");
2912     }
2913     }
2914    
2915     if (have_srcreg && have_dstreg &&
2916     (table68k[opcode].dmode==Areg ||
2917     table68k[opcode].dmode==Aind ||
2918     table68k[opcode].dmode==Aipi ||
2919     table68k[opcode].dmode==Apdi ||
2920     table68k[opcode].dmode==Ad16 ||
2921     table68k[opcode].dmode==Ad8r) &&
2922     (table68k[opcode].smode==Areg ||
2923     table68k[opcode].smode==Aind ||
2924     table68k[opcode].smode==Aipi ||
2925     table68k[opcode].smode==Apdi ||
2926     table68k[opcode].smode==Ad16 ||
2927     table68k[opcode].smode==Ad8r)
2928     ) {
2929     comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n");
2930     }
2931     else {
2932     comprintf("\tuae_u32 dodgy=0;\n");
2933     }
2934     comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n");
2935     comprintf("\tm68k_pc_offset+=2;\n");
2936    
2937     aborted=gen_opcode (opcode);
2938     {
2939     int flags=0;
2940     if (global_isjump) flags|=1;
2941     if (long_opcode) flags|=2;
2942     if (global_cmov) flags|=4;
2943     if (global_isaddx) flags|=8;
2944     if (global_iscjump) flags|=16;
2945     if (global_fpu) flags|=32;
2946    
2947     comprintf ("}\n");
2948    
2949     if (aborted) {
2950     fprintf (stblfile, "{ NULL, 0x%08x, %ld }, /* %s */\n", flags, opcode, lookuptab[i].name);
2951     com_discard();
2952     }
2953     else {
2954     if (noflags) {
2955     fprintf (stblfile, "{ op_%lx_%d_comp_nf, 0x%08x, %ld }, /* %s */\n", opcode, postfix, flags, opcode, lookuptab[i].name);
2956     fprintf (headerfile, "extern compop_func op_%lx_%d_comp_nf;\n", opcode, postfix);
2957     printf ("void REGPARAM2 op_%lx_%d_comp_nf(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
2958     }
2959     else {
2960     fprintf (stblfile, "{ op_%lx_%d_comp_ff, 0x%08x, %ld }, /* %s */\n", opcode, postfix, flags, opcode, lookuptab[i].name);
2961     fprintf (headerfile, "extern compop_func op_%lx_%d_comp_ff;\n", opcode, postfix);
2962     printf ("void REGPARAM2 op_%lx_%d_comp_ff(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
2963     }
2964     com_flush();
2965     }
2966     }
2967     opcode_next_clev[rp] = next_cpu_level;
2968     opcode_last_postfix[rp] = postfix;
2969     }
2970    
2971     static void
2972     generate_func (int noflags)
2973     {
2974     int i, j, rp;
2975    
2976     using_prefetch = 0;
2977     using_exception_3 = 0;
2978     for (i = 0; i < 1; i++) /* We only do one level! */
2979     {
2980     cpu_level = 4 - i;
2981     postfix = i;
2982    
2983     if (noflags)
2984     fprintf (stblfile, "struct comptbl op_smalltbl_%d_comp_nf[] = {\n", postfix);
2985     else
2986     fprintf (stblfile, "struct comptbl op_smalltbl_%d_comp_ff[] = {\n", postfix);
2987    
2988    
2989     /* sam: this is for people with low memory (eg. me :)) */
2990     !printf ("\n"
2991     "#if !defined(PART_1) && !defined(PART_2) && "
2992     "!defined(PART_3) && !defined(PART_4) && "
2993     "!defined(PART_5) && !defined(PART_6) && "
2994     "!defined(PART_7) && !defined(PART_8)"
2995     "\n"
2996     "#define PART_1 1\n"
2997     "#define PART_2 1\n"
2998     "#define PART_3 1\n"
2999     "#define PART_4 1\n"
3000     "#define PART_5 1\n"
3001     "#define PART_6 1\n"
3002     "#define PART_7 1\n"
3003     "#define PART_8 1\n"
3004     "#endif\n\n");
3005    
3006     rp = 0;
3007     for (j = 1; j <= 8; ++j)
3008     {
3009     int k = (j * nr_cpuop_funcs) / 8;
3010     printf ("#ifdef PART_%d\n", j);
3011     for (; rp < k; rp++)
3012     generate_one_opcode (rp,noflags);
3013     printf ("#endif\n\n");
3014     }
3015    
3016     fprintf (stblfile, "{ 0, 0,65536 }};\n");
3017     }
3018    
3019     }
3020    
3021     int
3022     main (int argc, char **argv)
3023     {
3024     read_table68k ();
3025     do_merges ();
3026    
3027     opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3028     opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3029     opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3030     counts = (unsigned long *) malloc (65536 * sizeof (unsigned long));
3031     read_counts ();
3032    
3033     /* It would be a lot nicer to put all in one file (we'd also get rid of
3034     * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
3035     * I don't dare to touch the 68k version. */
3036    
3037     headerfile = fopen ("comptbl.h", "wb");
3038     stblfile = fopen ("compstbl.cpp", "wb");
3039     freopen ("compemu.cpp", "wb", stdout);
3040    
3041     generate_includes (stdout);
3042     generate_includes (stblfile);
3043    
3044     printf("#include \"compiler/compemu.h\"\n");
3045    
3046     noflags=0;
3047     generate_func (noflags);
3048    
3049     free(opcode_map);
3050     free(opcode_last_postfix);
3051     free(opcode_next_clev);
3052     free(counts);
3053    
3054     opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3055     opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3056     opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs);
3057     counts = (unsigned long *) malloc (65536 * sizeof (unsigned long));
3058     read_counts ();
3059     noflags=1;
3060     generate_func (noflags);
3061    
3062     free(opcode_map);
3063     free(opcode_last_postfix);
3064     free(opcode_next_clev);
3065     free(counts);
3066    
3067     free (table68k);
3068     fclose (stblfile);
3069     fclose (headerfile);
3070     return 0;
3071     }