130 |
|
{ i_FBcc, "FBcc" }, |
131 |
|
{ i_FSAVE, "FSAVE" }, |
132 |
|
{ i_FRESTORE, "FRESTORE" }, |
133 |
+ |
|
134 |
+ |
{ i_CINVL, "CINVL" }, |
135 |
+ |
{ i_CINVP, "CINVP" }, |
136 |
+ |
{ i_CINVA, "CINVA" }, |
137 |
+ |
{ i_CPUSHL, "CPUSHL" }, |
138 |
+ |
{ i_CPUSHP, "CPUSHP" }, |
139 |
+ |
{ i_CPUSHA, "CPUSHA" }, |
140 |
+ |
{ i_MOVE16, "MOVE16" }, |
141 |
+ |
|
142 |
+ |
{ i_EMULOP_RETURN, "EMULOP_RETURN" }, |
143 |
+ |
{ i_EMULOP, "EMULOP" }, |
144 |
+ |
|
145 |
|
{ i_MMUOP, "MMUOP" }, |
146 |
|
{ i_ILLG, "" }, |
147 |
|
}; |
198 |
|
int variants; |
199 |
|
struct instr_def id; |
200 |
|
const char *opcstr; |
201 |
< |
int i; |
201 |
> |
int i, n; |
202 |
|
|
203 |
|
int flaglive = 0, flagdead = 0; |
204 |
+ |
int cflow = 0; |
205 |
|
|
206 |
|
id = defs68k[insn]; |
207 |
|
|
208 |
+ |
// Control flow information |
209 |
+ |
cflow = id.cflow; |
210 |
+ |
|
211 |
+ |
// Mask of flags set/used |
212 |
+ |
unsigned char flags_set(0), flags_used(0); |
213 |
+ |
|
214 |
+ |
for (i = 0, n = 4; i < 5; i++, n--) { |
215 |
+ |
switch (id.flaginfo[i].flagset) { |
216 |
+ |
case fa_unset: case fa_isjmp: break; |
217 |
+ |
default: flags_set |= (1 << n); |
218 |
+ |
} |
219 |
+ |
|
220 |
+ |
switch (id.flaginfo[i].flaguse) { |
221 |
+ |
case fu_unused: case fu_isjmp: break; |
222 |
+ |
default: flags_used |= (1 << n); |
223 |
+ |
} |
224 |
+ |
} |
225 |
+ |
|
226 |
|
for (i = 0; i < 5; i++) { |
227 |
|
switch (id.flaginfo[i].flagset){ |
228 |
|
case fa_unset: break; |
198 |
– |
case fa_isjmp: break; |
229 |
|
case fa_zero: flagdead |= 1 << i; break; |
230 |
|
case fa_one: flagdead |= 1 << i; break; |
231 |
|
case fa_dontcare: flagdead |= 1 << i; break; |
238 |
|
for (i = 0; i < 5; i++) { |
239 |
|
switch (id.flaginfo[i].flaguse) { |
240 |
|
case fu_unused: break; |
211 |
– |
case fu_isjmp: flaglive |= 1 << i; break; |
212 |
– |
case fu_maybecc: flaglive |= 1 << i; break; |
241 |
|
case fu_unknown: flaglive = -1; goto out2; |
242 |
|
case fu_used: flaglive |= 1 << i; break; |
243 |
|
} |
255 |
|
int pos = 0; |
256 |
|
int mnp = 0; |
257 |
|
int bitno = 0; |
258 |
< |
char mnemonic[10]; |
258 |
> |
char mnemonic[64]; |
259 |
|
|
260 |
|
wordsizes sz = sz_long; |
261 |
|
int srcgather = 0, dstgather = 0; |
292 |
|
continue; |
293 |
|
if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) |
294 |
|
continue; |
295 |
+ |
if (bitcnt[bitE] && (bitval[bitE] == 0x00)) |
296 |
+ |
continue; |
297 |
|
|
298 |
|
/* bitI and bitC get copied to biti and bitc */ |
299 |
|
if (bitcnt[bitI]) { |
332 |
|
} |
333 |
|
} |
334 |
|
mnp++; |
335 |
+ |
if ((unsigned)mnp >= sizeof(mnemonic) - 1) { |
336 |
+ |
mnemonic[sizeof(mnemonic) - 1] = 0; |
337 |
+ |
fprintf(stderr, "Instruction %s overflow\n", mnemonic); |
338 |
+ |
abort(); |
339 |
+ |
} |
340 |
|
} |
341 |
|
pos++; |
342 |
|
} |
374 |
|
case 'P': srcmode = Aipi; pos++; break; |
375 |
|
} |
376 |
|
break; |
377 |
+ |
case 'L': |
378 |
+ |
srcmode = absl; |
379 |
+ |
break; |
380 |
|
case '#': |
381 |
|
switch (opcstr[pos++]) { |
382 |
|
case 'z': srcmode = imm; break; |
422 |
|
srcpos = bitpos[bitK]; |
423 |
|
} |
424 |
|
break; |
425 |
+ |
case 'E': srcmode = immi; srcreg = bitval[bitE]; |
426 |
+ |
if (CPU_EMU_SIZE < 5) { // gb-- what is CPU_EMU_SIZE used for ?? |
427 |
+ |
/* 1..255 */ |
428 |
+ |
srcgather = 1; |
429 |
+ |
srctype = 6; |
430 |
+ |
srcpos = bitpos[bitE]; |
431 |
+ |
} |
432 |
+ |
break; |
433 |
+ |
case 'p': srcmode = immi; srcreg = bitval[bitp]; |
434 |
+ |
if (CPU_EMU_SIZE < 5) { |
435 |
+ |
/* 0..3 */ |
436 |
+ |
srcgather = 1; |
437 |
+ |
srctype = 7; |
438 |
+ |
srcpos = bitpos[bitp]; |
439 |
+ |
} |
440 |
+ |
break; |
441 |
|
default: abort(); |
442 |
|
} |
443 |
|
break; |
562 |
|
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; |
563 |
|
default: abort(); |
564 |
|
} |
565 |
+ |
if (dstpos < 0 || dstpos >= 32) |
566 |
+ |
abort(); |
567 |
|
break; |
568 |
|
case 'A': |
569 |
|
destmode = Areg; |
570 |
|
switch (opcstr[pos++]) { |
571 |
|
case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; |
572 |
|
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; |
573 |
+ |
case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; |
574 |
|
default: abort(); |
575 |
|
} |
576 |
+ |
if (dstpos < 0 || dstpos >= 32) |
577 |
+ |
abort(); |
578 |
|
switch (opcstr[pos]) { |
579 |
|
case 'p': destmode = Apdi; pos++; break; |
580 |
|
case 'P': destmode = Aipi; pos++; break; |
581 |
|
} |
582 |
|
break; |
583 |
+ |
case 'L': |
584 |
+ |
destmode = absl; |
585 |
+ |
break; |
586 |
|
case '#': |
587 |
|
switch (opcstr[pos++]) { |
588 |
|
case 'z': destmode = imm; break; |
753 |
|
table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; |
754 |
|
} |
755 |
|
#endif |
756 |
+ |
|
757 |
+ |
#if 1 |
758 |
+ |
/* gb-- flagdead and flaglive would not have correct information */ |
759 |
+ |
table68k[opc].flagdead = flags_set; |
760 |
+ |
table68k[opc].flaglive = flags_used; |
761 |
+ |
#else |
762 |
|
table68k[opc].flagdead = flagdead; |
763 |
|
table68k[opc].flaglive = flaglive; |
764 |
+ |
#endif |
765 |
+ |
table68k[opc].cflow = cflow; |
766 |
|
nomatch: |
767 |
|
/* FOO! */; |
768 |
|
} |
781 |
|
for (i = 0; i < n_defs68k; i++) { |
782 |
|
build_insn (i); |
783 |
|
} |
784 |
+ |
|
785 |
+ |
/* Extra fixes in table68k for control flow information and flag usage */ |
786 |
+ |
for (i = 0; i < 65536; i++) { |
787 |
+ |
instrmnem mnemo = (instrmnem)(table68k[i].mnemo); |
788 |
+ |
|
789 |
+ |
#define IS_CONST_JUMP(opc) \ |
790 |
+ |
( ((table68k[opc].mnemo == i_Bcc) && (table68k[opc].cc < 2)) \ |
791 |
+ |
|| (table68k[opc].mnemo == i_BSR) \ |
792 |
+ |
) |
793 |
+ |
|
794 |
+ |
// Precise const jumps as such. The JIT compiler will take |
795 |
+ |
// care to actually enable that optimization or not |
796 |
+ |
if (IS_CONST_JUMP(i)) |
797 |
+ |
table68k[i].cflow |= fl_const_jump; |
798 |
+ |
|
799 |
+ |
// Fix flags used information for Scc, Bcc, TRAPcc, DBcc instructions |
800 |
+ |
int flags_used = table68k[i].flaglive; |
801 |
+ |
if ( (mnemo == i_Scc) |
802 |
+ |
|| (mnemo == i_Bcc) |
803 |
+ |
|| (mnemo == i_DBcc) |
804 |
+ |
|| (mnemo == i_TRAPcc) |
805 |
+ |
) { |
806 |
+ |
switch (table68k[i].cc) { |
807 |
+ |
// CC mask: XNZVC |
808 |
+ |
// 8421 |
809 |
+ |
case 0: flags_used = 0x00; break; /* T */ |
810 |
+ |
case 1: flags_used = 0x00; break; /* F */ |
811 |
+ |
case 2: flags_used = 0x05; break; /* HI */ |
812 |
+ |
case 3: flags_used = 0x05; break; /* LS */ |
813 |
+ |
case 4: flags_used = 0x01; break; /* CC */ |
814 |
+ |
case 5: flags_used = 0x01; break; /* CS */ |
815 |
+ |
case 6: flags_used = 0x04; break; /* NE */ |
816 |
+ |
case 7: flags_used = 0x04; break; /* EQ */ |
817 |
+ |
case 8: flags_used = 0x02; break; /* VC */ |
818 |
+ |
case 9: flags_used = 0x02; break; /* VS */ |
819 |
+ |
case 10:flags_used = 0x08; break; /* PL */ |
820 |
+ |
case 11:flags_used = 0x08; break; /* MI */ |
821 |
+ |
case 12:flags_used = 0x0A; break; /* GE */ |
822 |
+ |
case 13:flags_used = 0x0A; break; /* LT */ |
823 |
+ |
case 14:flags_used = 0x0E; break; /* GT */ |
824 |
+ |
case 15:flags_used = 0x0E; break; /* LE */ |
825 |
+ |
} |
826 |
+ |
} |
827 |
+ |
|
828 |
+ |
/* Unconditional jumps don't evaluate condition codes, so they |
829 |
+ |
don't actually use any flags themselves */ |
830 |
+ |
if (IS_CONST_JUMP(i)) |
831 |
+ |
flags_used = 0; |
832 |
+ |
|
833 |
+ |
table68k[i].flaglive = flags_used; |
834 |
+ |
} |
835 |
|
} |
836 |
|
|
837 |
|
static int mismatch; |
859 |
|
smsk = 7; sbitdst = 8; break; |
860 |
|
case 5: |
861 |
|
smsk = 63; sbitdst = 64; break; |
862 |
+ |
case 6: |
863 |
+ |
smsk = 255; sbitdst = 256; break; |
864 |
+ |
case 7: |
865 |
+ |
smsk = 3; sbitdst = 4; break; |
866 |
|
default: |
867 |
|
smsk = 0; sbitdst = 0; |
868 |
|
abort(); |