ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/readcpu.cpp
Revision: 1.4
Committed: 2001-08-19T16:21:01Z (23 years, 3 months ago) by gbeauche
Branch: MAIN
CVS Tags: snapshot-15012002
Changes since 1.3: +12 -3 lines
Log Message:
- merge 680x0 emulation core with uae 0.8.17

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * UAE - The Un*x Amiga Emulator
3     *
4     * Read 68000 CPU specs from file "table68k"
5     *
6     * Copyright 1995,1996 Bernd Schmidt
7     */
8    
9     #include <stdio.h>
10     #include <stdlib.h>
11     #include <string.h>
12     #include <ctype.h>
13    
14     #include "sysdeps.h"
15     #include "readcpu.h"
16    
17     int nr_cpuop_funcs;
18    
19     struct mnemolookup lookuptab[] = {
20     { i_ILLG, "ILLEGAL" },
21     { i_OR, "OR" },
22     { i_CHK, "CHK" },
23     { i_CHK2, "CHK2" },
24     { i_AND, "AND" },
25     { i_EOR, "EOR" },
26     { i_ORSR, "ORSR" },
27     { i_ANDSR, "ANDSR" },
28     { i_EORSR, "EORSR" },
29     { i_SUB, "SUB" },
30     { i_SUBA, "SUBA" },
31     { i_SUBX, "SUBX" },
32     { i_SBCD, "SBCD" },
33     { i_ADD, "ADD" },
34     { i_ADDA, "ADDA" },
35     { i_ADDX, "ADDX" },
36     { i_ABCD, "ABCD" },
37     { i_NEG, "NEG" },
38     { i_NEGX, "NEGX" },
39     { i_NBCD, "NBCD" },
40     { i_CLR, "CLR" },
41     { i_NOT, "NOT" },
42     { i_TST, "TST" },
43     { i_BTST, "BTST" },
44     { i_BCHG, "BCHG" },
45     { i_BCLR, "BCLR" },
46     { i_BSET, "BSET" },
47     { i_CMP, "CMP" },
48     { i_CMPM, "CMPM" },
49     { i_CMPA, "CMPA" },
50     { i_MVPRM, "MVPRM" },
51     { i_MVPMR, "MVPMR" },
52     { i_MOVE, "MOVE" },
53     { i_MOVEA, "MOVEA" },
54     { i_MVSR2, "MVSR2" },
55     { i_MV2SR, "MV2SR" },
56     { i_SWAP, "SWAP" },
57     { i_EXG, "EXG" },
58     { i_EXT, "EXT" },
59     { i_MVMEL, "MVMEL" },
60     { i_MVMLE, "MVMLE" },
61     { i_TRAP, "TRAP" },
62     { i_MVR2USP, "MVR2USP" },
63     { i_MVUSP2R, "MVUSP2R" },
64     { i_NOP, "NOP" },
65     { i_RESET, "RESET" },
66     { i_RTE, "RTE" },
67     { i_RTD, "RTD" },
68     { i_LINK, "LINK" },
69     { i_UNLK, "UNLK" },
70     { i_RTS, "RTS" },
71     { i_STOP, "STOP" },
72     { i_TRAPV, "TRAPV" },
73     { i_RTR, "RTR" },
74     { i_JSR, "JSR" },
75     { i_JMP, "JMP" },
76     { i_BSR, "BSR" },
77     { i_Bcc, "Bcc" },
78     { i_LEA, "LEA" },
79     { i_PEA, "PEA" },
80     { i_DBcc, "DBcc" },
81     { i_Scc, "Scc" },
82     { i_DIVU, "DIVU" },
83     { i_DIVS, "DIVS" },
84     { i_MULU, "MULU" },
85     { i_MULS, "MULS" },
86     { i_ASR, "ASR" },
87     { i_ASL, "ASL" },
88     { i_LSR, "LSR" },
89     { i_LSL, "LSL" },
90     { i_ROL, "ROL" },
91     { i_ROR, "ROR" },
92     { i_ROXL, "ROXL" },
93     { i_ROXR, "ROXR" },
94     { i_ASRW, "ASRW" },
95     { i_ASLW, "ASLW" },
96     { i_LSRW, "LSRW" },
97     { i_LSLW, "LSLW" },
98     { i_ROLW, "ROLW" },
99     { i_RORW, "RORW" },
100     { i_ROXLW, "ROXLW" },
101     { i_ROXRW, "ROXRW" },
102    
103     { i_MOVE2C, "MOVE2C" },
104     { i_MOVEC2, "MOVEC2" },
105     { i_CAS, "CAS" },
106     { i_CAS2, "CAS2" },
107     { i_MULL, "MULL" },
108     { i_DIVL, "DIVL" },
109     { i_BFTST, "BFTST" },
110     { i_BFEXTU, "BFEXTU" },
111     { i_BFCHG, "BFCHG" },
112     { i_BFEXTS, "BFEXTS" },
113     { i_BFCLR, "BFCLR" },
114     { i_BFFFO, "BFFFO" },
115     { i_BFSET, "BFSET" },
116     { i_BFINS, "BFINS" },
117     { i_PACK, "PACK" },
118     { i_UNPK, "UNPK" },
119     { i_TAS, "TAS" },
120     { i_BKPT, "BKPT" },
121     { i_CALLM, "CALLM" },
122     { i_RTM, "RTM" },
123     { i_TRAPcc, "TRAPcc" },
124     { i_MOVES, "MOVES" },
125     { i_FPP, "FPP" },
126     { i_FDBcc, "FDBcc" },
127     { i_FScc, "FScc" },
128     { i_FTRAPcc, "FTRAPcc" },
129     { i_FBcc, "FBcc" },
130     { i_FBcc, "FBcc" },
131     { i_FSAVE, "FSAVE" },
132     { i_FRESTORE, "FRESTORE" },
133 cebix 1.2
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 cebix 1.1 { i_MMUOP, "MMUOP" },
143     { i_ILLG, "" },
144     };
145    
146     struct instr *table68k;
147    
148     static __inline__ amodes mode_from_str (const char *str)
149     {
150     if (strncmp (str, "Dreg", 4) == 0) return Dreg;
151     if (strncmp (str, "Areg", 4) == 0) return Areg;
152     if (strncmp (str, "Aind", 4) == 0) return Aind;
153     if (strncmp (str, "Apdi", 4) == 0) return Apdi;
154     if (strncmp (str, "Aipi", 4) == 0) return Aipi;
155     if (strncmp (str, "Ad16", 4) == 0) return Ad16;
156     if (strncmp (str, "Ad8r", 4) == 0) return Ad8r;
157     if (strncmp (str, "absw", 4) == 0) return absw;
158     if (strncmp (str, "absl", 4) == 0) return absl;
159     if (strncmp (str, "PC16", 4) == 0) return PC16;
160     if (strncmp (str, "PC8r", 4) == 0) return PC8r;
161     if (strncmp (str, "Immd", 4) == 0) return imm;
162     abort ();
163     return (amodes)0;
164     }
165    
166     static __inline__ amodes mode_from_mr (int mode, int reg)
167     {
168     switch (mode) {
169     case 0: return Dreg;
170     case 1: return Areg;
171     case 2: return Aind;
172     case 3: return Aipi;
173     case 4: return Apdi;
174     case 5: return Ad16;
175     case 6: return Ad8r;
176     case 7:
177     switch (reg) {
178     case 0: return absw;
179     case 1: return absl;
180     case 2: return PC16;
181     case 3: return PC8r;
182     case 4: return imm;
183     case 5:
184     case 6:
185     case 7: return am_illg;
186     }
187     }
188     abort ();
189     return (amodes)0;
190     }
191    
192     static void build_insn (int insn)
193     {
194     int find = -1;
195     int variants;
196     struct instr_def id;
197     const char *opcstr;
198     int i;
199    
200     int flaglive = 0, flagdead = 0;
201    
202     id = defs68k[insn];
203    
204     for (i = 0; i < 5; i++) {
205     switch (id.flaginfo[i].flagset){
206     case fa_unset: break;
207     case fa_isjmp: break;
208     case fa_zero: flagdead |= 1 << i; break;
209     case fa_one: flagdead |= 1 << i; break;
210     case fa_dontcare: flagdead |= 1 << i; break;
211     case fa_unknown: flagdead = -1; goto out1;
212     case fa_set: flagdead |= 1 << i; break;
213     }
214     }
215    
216     out1:
217     for (i = 0; i < 5; i++) {
218     switch (id.flaginfo[i].flaguse) {
219     case fu_unused: break;
220     case fu_isjmp: flaglive |= 1 << i; break;
221     case fu_maybecc: flaglive |= 1 << i; break;
222     case fu_unknown: flaglive = -1; goto out2;
223     case fu_used: flaglive |= 1 << i; break;
224     }
225     }
226     out2:
227    
228     opcstr = id.opcstr;
229     for (variants = 0; variants < (1 << id.n_variable); variants++) {
230     int bitcnt[lastbit];
231     int bitval[lastbit];
232     int bitpos[lastbit];
233     int i;
234     uae_u16 opc = id.bits;
235     uae_u16 msk, vmsk;
236     int pos = 0;
237     int mnp = 0;
238     int bitno = 0;
239     char mnemonic[10];
240    
241     wordsizes sz = sz_long;
242     int srcgather = 0, dstgather = 0;
243     int usesrc = 0, usedst = 0;
244     int srctype = 0;
245     int srcpos = -1, dstpos = -1;
246    
247     amodes srcmode = am_unknown, destmode = am_unknown;
248     int srcreg = -1, destreg = -1;
249    
250     for (i = 0; i < lastbit; i++)
251     bitcnt[i] = bitval[i] = 0;
252    
253     vmsk = 1 << id.n_variable;
254    
255     for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) {
256     if (!(msk & id.mask)) {
257     int currbit = id.bitpos[bitno++];
258     int bit_set;
259     vmsk >>= 1;
260     bit_set = variants & vmsk ? 1 : 0;
261     if (bit_set)
262     opc |= msk;
263     bitpos[currbit] = 15 - i;
264     bitcnt[currbit]++;
265     bitval[currbit] <<= 1;
266     bitval[currbit] |= bit_set;
267     }
268     }
269    
270     if (bitval[bitj] == 0) bitval[bitj] = 8;
271     /* first check whether this one does not match after all */
272     if (bitval[bitz] == 3 || bitval[bitC] == 1)
273     continue;
274     if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
275     continue;
276    
277     /* bitI and bitC get copied to biti and bitc */
278     if (bitcnt[bitI]) {
279     bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
280     }
281     if (bitcnt[bitC])
282     bitval[bitc] = bitval[bitC];
283    
284     pos = 0;
285     while (opcstr[pos] && !isspace(opcstr[pos])) {
286     if (opcstr[pos] == '.') {
287     pos++;
288     switch (opcstr[pos]) {
289    
290     case 'B': sz = sz_byte; break;
291     case 'W': sz = sz_word; break;
292     case 'L': sz = sz_long; break;
293     case 'z':
294     switch (bitval[bitz]) {
295     case 0: sz = sz_byte; break;
296     case 1: sz = sz_word; break;
297     case 2: sz = sz_long; break;
298     default: abort();
299     }
300     break;
301     default: abort();
302     }
303     } else {
304     mnemonic[mnp] = opcstr[pos];
305     if (mnemonic[mnp] == 'f') {
306     find = -1;
307     switch (bitval[bitf]) {
308     case 0: mnemonic[mnp] = 'R'; break;
309     case 1: mnemonic[mnp] = 'L'; break;
310     default: abort();
311     }
312     }
313     mnp++;
314     }
315     pos++;
316     }
317     mnemonic[mnp] = 0;
318    
319     /* now, we have read the mnemonic and the size */
320     while (opcstr[pos] && isspace(opcstr[pos]))
321     pos++;
322    
323     /* A goto a day keeps the D******a away. */
324     if (opcstr[pos] == 0)
325     goto endofline;
326    
327     /* parse the source address */
328     usesrc = 1;
329     switch (opcstr[pos++]) {
330     case 'D':
331     srcmode = Dreg;
332     switch (opcstr[pos++]) {
333     case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
334     case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
335     default: abort();
336     }
337    
338     break;
339     case 'A':
340     srcmode = Areg;
341     switch (opcstr[pos++]) {
342     case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
343     case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
344     default: abort();
345     }
346     switch (opcstr[pos]) {
347     case 'p': srcmode = Apdi; pos++; break;
348     case 'P': srcmode = Aipi; pos++; break;
349     }
350     break;
351 gbeauche 1.4 case 'L':
352     srcmode = absl;
353     break;
354 cebix 1.1 case '#':
355     switch (opcstr[pos++]) {
356     case 'z': srcmode = imm; break;
357     case '0': srcmode = imm0; break;
358     case '1': srcmode = imm1; break;
359     case '2': srcmode = imm2; break;
360     case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti];
361     if (CPU_EMU_SIZE < 4) {
362     /* Used for branch instructions */
363     srctype = 1;
364     srcgather = 1;
365     srcpos = bitpos[biti];
366     }
367     break;
368     case 'j': srcmode = immi; srcreg = bitval[bitj];
369     if (CPU_EMU_SIZE < 3) {
370     /* 1..8 for ADDQ/SUBQ and rotshi insns */
371     srcgather = 1;
372     srctype = 3;
373     srcpos = bitpos[bitj];
374     }
375     break;
376     case 'J': srcmode = immi; srcreg = bitval[bitJ];
377     if (CPU_EMU_SIZE < 5) {
378     /* 0..15 */
379     srcgather = 1;
380     srctype = 2;
381     srcpos = bitpos[bitJ];
382     }
383     break;
384     case 'k': srcmode = immi; srcreg = bitval[bitk];
385     if (CPU_EMU_SIZE < 3) {
386     srcgather = 1;
387     srctype = 4;
388     srcpos = bitpos[bitk];
389     }
390     break;
391     case 'K': srcmode = immi; srcreg = bitval[bitK];
392     if (CPU_EMU_SIZE < 5) {
393     /* 0..15 */
394     srcgather = 1;
395     srctype = 5;
396     srcpos = bitpos[bitK];
397     }
398     break;
399 gbeauche 1.3 case 'p': srcmode = immi; srcreg = bitval[bitp];
400 gbeauche 1.4 if (CPU_EMU_SIZE < 5) {
401 gbeauche 1.3 /* 0..3 */
402     srcgather = 1;
403     srctype = 7;
404     srcpos = bitpos[bitp];
405     }
406     break;
407 cebix 1.1 default: abort();
408     }
409     break;
410     case 'd':
411     srcreg = bitval[bitD];
412     srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
413     if (srcmode == am_illg)
414     continue;
415     if (CPU_EMU_SIZE < 2 &&
416     (srcmode == Areg || srcmode == Dreg || srcmode == Aind
417     || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
418     || srcmode == Apdi))
419     {
420     srcgather = 1; srcpos = bitpos[bitD];
421     }
422     if (opcstr[pos] == '[') {
423     pos++;
424     if (opcstr[pos] == '!') {
425     /* exclusion */
426     do {
427     pos++;
428     if (mode_from_str(opcstr+pos) == srcmode)
429     goto nomatch;
430     pos += 4;
431     } while (opcstr[pos] == ',');
432     pos++;
433     } else {
434     if (opcstr[pos+4] == '-') {
435     /* replacement */
436     if (mode_from_str(opcstr+pos) == srcmode)
437     srcmode = mode_from_str(opcstr+pos+5);
438     else
439     goto nomatch;
440     pos += 10;
441     } else {
442     /* normal */
443     while(mode_from_str(opcstr+pos) != srcmode) {
444     pos += 4;
445     if (opcstr[pos] == ']')
446     goto nomatch;
447     pos++;
448     }
449     while(opcstr[pos] != ']') pos++;
450     pos++;
451     break;
452     }
453     }
454     }
455     /* Some addressing modes are invalid as destination */
456     if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
457     goto nomatch;
458     break;
459     case 's':
460     srcreg = bitval[bitS];
461     srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
462    
463     if (srcmode == am_illg)
464     continue;
465     if (CPU_EMU_SIZE < 2 &&
466     (srcmode == Areg || srcmode == Dreg || srcmode == Aind
467     || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
468     || srcmode == Apdi))
469     {
470     srcgather = 1; srcpos = bitpos[bitS];
471     }
472     if (opcstr[pos] == '[') {
473     pos++;
474     if (opcstr[pos] == '!') {
475     /* exclusion */
476     do {
477     pos++;
478     if (mode_from_str(opcstr+pos) == srcmode)
479     goto nomatch;
480     pos += 4;
481     } while (opcstr[pos] == ',');
482     pos++;
483     } else {
484     if (opcstr[pos+4] == '-') {
485     /* replacement */
486     if (mode_from_str(opcstr+pos) == srcmode)
487     srcmode = mode_from_str(opcstr+pos+5);
488     else
489     goto nomatch;
490     pos += 10;
491     } else {
492     /* normal */
493     while(mode_from_str(opcstr+pos) != srcmode) {
494     pos += 4;
495     if (opcstr[pos] == ']')
496     goto nomatch;
497     pos++;
498     }
499     while(opcstr[pos] != ']') pos++;
500     pos++;
501     }
502     }
503     }
504     break;
505     default: abort();
506     }
507     /* safety check - might have changed */
508     if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
509     && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
510     && srcmode != Apdi && srcmode != immi)
511     {
512     srcgather = 0;
513     }
514     if (srcmode == Areg && sz == sz_byte)
515     goto nomatch;
516    
517     if (opcstr[pos] != ',')
518     goto endofline;
519     pos++;
520    
521     /* parse the destination address */
522     usedst = 1;
523     switch (opcstr[pos++]) {
524     case 'D':
525     destmode = Dreg;
526     switch (opcstr[pos++]) {
527     case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
528     case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
529     default: abort();
530     }
531 gbeauche 1.4 if (dstpos < 0 || dstpos >= 32)
532     abort();
533 cebix 1.1 break;
534     case 'A':
535     destmode = Areg;
536     switch (opcstr[pos++]) {
537     case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
538     case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
539 gbeauche 1.4 case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
540 cebix 1.1 default: abort();
541     }
542 gbeauche 1.4 if (dstpos < 0 || dstpos >= 32)
543     abort();
544 cebix 1.1 switch (opcstr[pos]) {
545     case 'p': destmode = Apdi; pos++; break;
546     case 'P': destmode = Aipi; pos++; break;
547     }
548     break;
549 gbeauche 1.4 case 'L':
550     destmode = absl;
551     break;
552 cebix 1.1 case '#':
553     switch (opcstr[pos++]) {
554     case 'z': destmode = imm; break;
555     case '0': destmode = imm0; break;
556     case '1': destmode = imm1; break;
557     case '2': destmode = imm2; break;
558     case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break;
559     case 'j': destmode = immi; destreg = bitval[bitj]; break;
560     case 'J': destmode = immi; destreg = bitval[bitJ]; break;
561     case 'k': destmode = immi; destreg = bitval[bitk]; break;
562     case 'K': destmode = immi; destreg = bitval[bitK]; break;
563     default: abort();
564     }
565     break;
566     case 'd':
567     destreg = bitval[bitD];
568     destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
569     if (destmode == am_illg)
570     continue;
571     if (CPU_EMU_SIZE < 1 &&
572     (destmode == Areg || destmode == Dreg || destmode == Aind
573     || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
574     || destmode == Apdi))
575     {
576     dstgather = 1; dstpos = bitpos[bitD];
577     }
578    
579     if (opcstr[pos] == '[') {
580     pos++;
581     if (opcstr[pos] == '!') {
582     /* exclusion */
583     do {
584     pos++;
585     if (mode_from_str(opcstr+pos) == destmode)
586     goto nomatch;
587     pos += 4;
588     } while (opcstr[pos] == ',');
589     pos++;
590     } else {
591     if (opcstr[pos+4] == '-') {
592     /* replacement */
593     if (mode_from_str(opcstr+pos) == destmode)
594     destmode = mode_from_str(opcstr+pos+5);
595     else
596     goto nomatch;
597     pos += 10;
598     } else {
599     /* normal */
600     while(mode_from_str(opcstr+pos) != destmode) {
601     pos += 4;
602     if (opcstr[pos] == ']')
603     goto nomatch;
604     pos++;
605     }
606     while(opcstr[pos] != ']') pos++;
607     pos++;
608     break;
609     }
610     }
611     }
612     /* Some addressing modes are invalid as destination */
613     if (destmode == imm || destmode == PC16 || destmode == PC8r)
614     goto nomatch;
615     break;
616     case 's':
617     destreg = bitval[bitS];
618     destmode = mode_from_mr(bitval[bits],bitval[bitS]);
619    
620     if (destmode == am_illg)
621     continue;
622     if (CPU_EMU_SIZE < 1 &&
623     (destmode == Areg || destmode == Dreg || destmode == Aind
624     || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
625     || destmode == Apdi))
626     {
627     dstgather = 1; dstpos = bitpos[bitS];
628     }
629    
630     if (opcstr[pos] == '[') {
631     pos++;
632     if (opcstr[pos] == '!') {
633     /* exclusion */
634     do {
635     pos++;
636     if (mode_from_str(opcstr+pos) == destmode)
637     goto nomatch;
638     pos += 4;
639     } while (opcstr[pos] == ',');
640     pos++;
641     } else {
642     if (opcstr[pos+4] == '-') {
643     /* replacement */
644     if (mode_from_str(opcstr+pos) == destmode)
645     destmode = mode_from_str(opcstr+pos+5);
646     else
647     goto nomatch;
648     pos += 10;
649     } else {
650     /* normal */
651     while(mode_from_str(opcstr+pos) != destmode) {
652     pos += 4;
653     if (opcstr[pos] == ']')
654     goto nomatch;
655     pos++;
656     }
657     while(opcstr[pos] != ']') pos++;
658     pos++;
659     }
660     }
661     }
662     break;
663     default: abort();
664     }
665     /* safety check - might have changed */
666     if (destmode != Areg && destmode != Dreg && destmode != Aind
667     && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
668     && destmode != Apdi)
669     {
670     dstgather = 0;
671     }
672    
673     if (destmode == Areg && sz == sz_byte)
674     goto nomatch;
675     #if 0
676     if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
677     dstgather = 0;
678     }
679     #endif
680     endofline:
681     /* now, we have a match */
682     if (table68k[opc].mnemo != i_ILLG)
683     fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
684     if (find == -1) {
685     for (find = 0;; find++) {
686     if (strcmp(mnemonic, lookuptab[find].name) == 0) {
687     table68k[opc].mnemo = lookuptab[find].mnemo;
688     break;
689     }
690     if (strlen(lookuptab[find].name) == 0) abort();
691     }
692     }
693     else {
694     table68k[opc].mnemo = lookuptab[find].mnemo;
695     }
696     table68k[opc].cc = bitval[bitc];
697     if (table68k[opc].mnemo == i_BTST
698     || table68k[opc].mnemo == i_BSET
699     || table68k[opc].mnemo == i_BCLR
700     || table68k[opc].mnemo == i_BCHG)
701     {
702     sz = destmode == Dreg ? sz_long : sz_byte;
703     }
704     table68k[opc].size = sz;
705     table68k[opc].sreg = srcreg;
706     table68k[opc].dreg = destreg;
707     table68k[opc].smode = srcmode;
708     table68k[opc].dmode = destmode;
709     table68k[opc].spos = srcgather ? srcpos : -1;
710     table68k[opc].dpos = dstgather ? dstpos : -1;
711     table68k[opc].suse = usesrc;
712     table68k[opc].duse = usedst;
713     table68k[opc].stype = srctype;
714     table68k[opc].plev = id.plevel;
715     table68k[opc].clev = id.cpulevel;
716     #if 0
717     for (i = 0; i < 5; i++) {
718     table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
719     table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
720     }
721     #endif
722     table68k[opc].flagdead = flagdead;
723     table68k[opc].flaglive = flaglive;
724     nomatch:
725     /* FOO! */;
726     }
727     }
728    
729    
730     void read_table68k (void)
731     {
732     int i;
733    
734     table68k = (struct instr *)malloc (65536 * sizeof (struct instr));
735     for (i = 0; i < 65536; i++) {
736     table68k[i].mnemo = i_ILLG;
737     table68k[i].handler = -1;
738     }
739     for (i = 0; i < n_defs68k; i++) {
740     build_insn (i);
741     }
742     }
743    
744     static int mismatch;
745    
746     static void handle_merges (long int opcode)
747     {
748     uae_u16 smsk;
749     uae_u16 dmsk;
750     int sbitdst, dstend;
751     int srcreg, dstreg;
752    
753     if (table68k[opcode].spos == -1) {
754     sbitdst = 1; smsk = 0;
755     } else {
756     switch (table68k[opcode].stype) {
757     case 0:
758     smsk = 7; sbitdst = 8; break;
759     case 1:
760     smsk = 255; sbitdst = 256; break;
761     case 2:
762     smsk = 15; sbitdst = 16; break;
763     case 3:
764     smsk = 7; sbitdst = 8; break;
765     case 4:
766     smsk = 7; sbitdst = 8; break;
767     case 5:
768     smsk = 63; sbitdst = 64; break;
769 gbeauche 1.3 case 7:
770     smsk = 3; sbitdst = 4; break;
771 cebix 1.1 default:
772     smsk = 0; sbitdst = 0;
773     abort();
774     break;
775     }
776     smsk <<= table68k[opcode].spos;
777     }
778     if (table68k[opcode].dpos == -1) {
779     dstend = 1; dmsk = 0;
780     } else {
781     dmsk = 7 << table68k[opcode].dpos;
782     dstend = 8;
783     }
784     for (srcreg=0; srcreg < sbitdst; srcreg++) {
785     for (dstreg=0; dstreg < dstend; dstreg++) {
786     uae_u16 code = opcode;
787    
788     code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
789     code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
790    
791     /* Check whether this is in fact the same instruction.
792     * The instructions should never differ, except for the
793     * Bcc.(BW) case. */
794     if (table68k[code].mnemo != table68k[opcode].mnemo
795     || table68k[code].size != table68k[opcode].size
796     || table68k[code].suse != table68k[opcode].suse
797     || table68k[code].duse != table68k[opcode].duse)
798     {
799     mismatch++; continue;
800     }
801     if (table68k[opcode].suse
802     && (table68k[opcode].spos != table68k[code].spos
803     || table68k[opcode].smode != table68k[code].smode
804     || table68k[opcode].stype != table68k[code].stype))
805     {
806     mismatch++; continue;
807     }
808     if (table68k[opcode].duse
809     && (table68k[opcode].dpos != table68k[code].dpos
810     || table68k[opcode].dmode != table68k[code].dmode))
811     {
812     mismatch++; continue;
813     }
814    
815     if (code != opcode)
816     table68k[code].handler = opcode;
817     }
818     }
819     }
820    
821     void do_merges (void)
822     {
823     long int opcode;
824     int nr = 0;
825     mismatch = 0;
826     for (opcode = 0; opcode < 65536; opcode++) {
827     if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
828     continue;
829     nr++;
830     handle_merges (opcode);
831     }
832     nr_cpuop_funcs = nr;
833     }
834    
835     int get_no_mismatches (void)
836     {
837     return mismatch;
838     }