ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/compiler/gencomp.c
Revision: 1.4
Committed: 2003-03-13T15:57:01Z (21 years, 8 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
Changes since 1.3: +15 -9 lines
Log Message:
Workaround change in flags handling for BSF instruction on Pentium 4.
i.e. currently disable translation of ADDX/SUBX/B<CHG,CLR,SET,TST> instructions
in that case. That is to say, better (much?) slower than inaccurate. :-(

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