ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/compiler/gencomp.c
Revision: 1.11
Committed: 2007-06-29T16:32:05Z (17 years, 5 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
Changes since 1.10: +9 -13 lines
Log Message:
More human readable instruction names (from e-uae).

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