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

File Contents

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