ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/readcpu.cpp
Revision: 1.2
Committed: 1999-10-28T15:33:24Z (24 years, 8 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-13072000, snapshot-22121999, snapshot-17022001, release-0_8-1, snapshot-02111999
Changes since 1.1: +9 -0 lines
Log Message:
- added some 68040 instructions: CINV, CPUSH, MOVE16 (Ax)+,(Ay)+, MOVEC regs,
  and FPU state frames; enough to boot MacOS
- CPU type can be selected in GTK prefs editor

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     case '#':
352     switch (opcstr[pos++]) {
353     case 'z': srcmode = imm; break;
354     case '0': srcmode = imm0; break;
355     case '1': srcmode = imm1; break;
356     case '2': srcmode = imm2; break;
357     case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti];
358     if (CPU_EMU_SIZE < 4) {
359     /* Used for branch instructions */
360     srctype = 1;
361     srcgather = 1;
362     srcpos = bitpos[biti];
363     }
364     break;
365     case 'j': srcmode = immi; srcreg = bitval[bitj];
366     if (CPU_EMU_SIZE < 3) {
367     /* 1..8 for ADDQ/SUBQ and rotshi insns */
368     srcgather = 1;
369     srctype = 3;
370     srcpos = bitpos[bitj];
371     }
372     break;
373     case 'J': srcmode = immi; srcreg = bitval[bitJ];
374     if (CPU_EMU_SIZE < 5) {
375     /* 0..15 */
376     srcgather = 1;
377     srctype = 2;
378     srcpos = bitpos[bitJ];
379     }
380     break;
381     case 'k': srcmode = immi; srcreg = bitval[bitk];
382     if (CPU_EMU_SIZE < 3) {
383     srcgather = 1;
384     srctype = 4;
385     srcpos = bitpos[bitk];
386     }
387     break;
388     case 'K': srcmode = immi; srcreg = bitval[bitK];
389     if (CPU_EMU_SIZE < 5) {
390     /* 0..15 */
391     srcgather = 1;
392     srctype = 5;
393     srcpos = bitpos[bitK];
394     }
395     break;
396     default: abort();
397     }
398     break;
399     case 'd':
400     srcreg = bitval[bitD];
401     srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
402     if (srcmode == am_illg)
403     continue;
404     if (CPU_EMU_SIZE < 2 &&
405     (srcmode == Areg || srcmode == Dreg || srcmode == Aind
406     || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
407     || srcmode == Apdi))
408     {
409     srcgather = 1; srcpos = bitpos[bitD];
410     }
411     if (opcstr[pos] == '[') {
412     pos++;
413     if (opcstr[pos] == '!') {
414     /* exclusion */
415     do {
416     pos++;
417     if (mode_from_str(opcstr+pos) == srcmode)
418     goto nomatch;
419     pos += 4;
420     } while (opcstr[pos] == ',');
421     pos++;
422     } else {
423     if (opcstr[pos+4] == '-') {
424     /* replacement */
425     if (mode_from_str(opcstr+pos) == srcmode)
426     srcmode = mode_from_str(opcstr+pos+5);
427     else
428     goto nomatch;
429     pos += 10;
430     } else {
431     /* normal */
432     while(mode_from_str(opcstr+pos) != srcmode) {
433     pos += 4;
434     if (opcstr[pos] == ']')
435     goto nomatch;
436     pos++;
437     }
438     while(opcstr[pos] != ']') pos++;
439     pos++;
440     break;
441     }
442     }
443     }
444     /* Some addressing modes are invalid as destination */
445     if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
446     goto nomatch;
447     break;
448     case 's':
449     srcreg = bitval[bitS];
450     srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
451    
452     if (srcmode == am_illg)
453     continue;
454     if (CPU_EMU_SIZE < 2 &&
455     (srcmode == Areg || srcmode == Dreg || srcmode == Aind
456     || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
457     || srcmode == Apdi))
458     {
459     srcgather = 1; srcpos = bitpos[bitS];
460     }
461     if (opcstr[pos] == '[') {
462     pos++;
463     if (opcstr[pos] == '!') {
464     /* exclusion */
465     do {
466     pos++;
467     if (mode_from_str(opcstr+pos) == srcmode)
468     goto nomatch;
469     pos += 4;
470     } while (opcstr[pos] == ',');
471     pos++;
472     } else {
473     if (opcstr[pos+4] == '-') {
474     /* replacement */
475     if (mode_from_str(opcstr+pos) == srcmode)
476     srcmode = mode_from_str(opcstr+pos+5);
477     else
478     goto nomatch;
479     pos += 10;
480     } else {
481     /* normal */
482     while(mode_from_str(opcstr+pos) != srcmode) {
483     pos += 4;
484     if (opcstr[pos] == ']')
485     goto nomatch;
486     pos++;
487     }
488     while(opcstr[pos] != ']') pos++;
489     pos++;
490     }
491     }
492     }
493     break;
494     default: abort();
495     }
496     /* safety check - might have changed */
497     if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
498     && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
499     && srcmode != Apdi && srcmode != immi)
500     {
501     srcgather = 0;
502     }
503     if (srcmode == Areg && sz == sz_byte)
504     goto nomatch;
505    
506     if (opcstr[pos] != ',')
507     goto endofline;
508     pos++;
509    
510     /* parse the destination address */
511     usedst = 1;
512     switch (opcstr[pos++]) {
513     case 'D':
514     destmode = Dreg;
515     switch (opcstr[pos++]) {
516     case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
517     case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
518     default: abort();
519     }
520     break;
521     case 'A':
522     destmode = Areg;
523     switch (opcstr[pos++]) {
524     case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
525     case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
526     default: abort();
527     }
528     switch (opcstr[pos]) {
529     case 'p': destmode = Apdi; pos++; break;
530     case 'P': destmode = Aipi; pos++; break;
531     }
532     break;
533     case '#':
534     switch (opcstr[pos++]) {
535     case 'z': destmode = imm; break;
536     case '0': destmode = imm0; break;
537     case '1': destmode = imm1; break;
538     case '2': destmode = imm2; break;
539     case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break;
540     case 'j': destmode = immi; destreg = bitval[bitj]; break;
541     case 'J': destmode = immi; destreg = bitval[bitJ]; break;
542     case 'k': destmode = immi; destreg = bitval[bitk]; break;
543     case 'K': destmode = immi; destreg = bitval[bitK]; break;
544     default: abort();
545     }
546     break;
547     case 'd':
548     destreg = bitval[bitD];
549     destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
550     if (destmode == am_illg)
551     continue;
552     if (CPU_EMU_SIZE < 1 &&
553     (destmode == Areg || destmode == Dreg || destmode == Aind
554     || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
555     || destmode == Apdi))
556     {
557     dstgather = 1; dstpos = bitpos[bitD];
558     }
559    
560     if (opcstr[pos] == '[') {
561     pos++;
562     if (opcstr[pos] == '!') {
563     /* exclusion */
564     do {
565     pos++;
566     if (mode_from_str(opcstr+pos) == destmode)
567     goto nomatch;
568     pos += 4;
569     } while (opcstr[pos] == ',');
570     pos++;
571     } else {
572     if (opcstr[pos+4] == '-') {
573     /* replacement */
574     if (mode_from_str(opcstr+pos) == destmode)
575     destmode = mode_from_str(opcstr+pos+5);
576     else
577     goto nomatch;
578     pos += 10;
579     } else {
580     /* normal */
581     while(mode_from_str(opcstr+pos) != destmode) {
582     pos += 4;
583     if (opcstr[pos] == ']')
584     goto nomatch;
585     pos++;
586     }
587     while(opcstr[pos] != ']') pos++;
588     pos++;
589     break;
590     }
591     }
592     }
593     /* Some addressing modes are invalid as destination */
594     if (destmode == imm || destmode == PC16 || destmode == PC8r)
595     goto nomatch;
596     break;
597     case 's':
598     destreg = bitval[bitS];
599     destmode = mode_from_mr(bitval[bits],bitval[bitS]);
600    
601     if (destmode == am_illg)
602     continue;
603     if (CPU_EMU_SIZE < 1 &&
604     (destmode == Areg || destmode == Dreg || destmode == Aind
605     || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
606     || destmode == Apdi))
607     {
608     dstgather = 1; dstpos = bitpos[bitS];
609     }
610    
611     if (opcstr[pos] == '[') {
612     pos++;
613     if (opcstr[pos] == '!') {
614     /* exclusion */
615     do {
616     pos++;
617     if (mode_from_str(opcstr+pos) == destmode)
618     goto nomatch;
619     pos += 4;
620     } while (opcstr[pos] == ',');
621     pos++;
622     } else {
623     if (opcstr[pos+4] == '-') {
624     /* replacement */
625     if (mode_from_str(opcstr+pos) == destmode)
626     destmode = mode_from_str(opcstr+pos+5);
627     else
628     goto nomatch;
629     pos += 10;
630     } else {
631     /* normal */
632     while(mode_from_str(opcstr+pos) != destmode) {
633     pos += 4;
634     if (opcstr[pos] == ']')
635     goto nomatch;
636     pos++;
637     }
638     while(opcstr[pos] != ']') pos++;
639     pos++;
640     }
641     }
642     }
643     break;
644     default: abort();
645     }
646     /* safety check - might have changed */
647     if (destmode != Areg && destmode != Dreg && destmode != Aind
648     && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
649     && destmode != Apdi)
650     {
651     dstgather = 0;
652     }
653    
654     if (destmode == Areg && sz == sz_byte)
655     goto nomatch;
656     #if 0
657     if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
658     dstgather = 0;
659     }
660     #endif
661     endofline:
662     /* now, we have a match */
663     if (table68k[opc].mnemo != i_ILLG)
664     fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
665     if (find == -1) {
666     for (find = 0;; find++) {
667     if (strcmp(mnemonic, lookuptab[find].name) == 0) {
668     table68k[opc].mnemo = lookuptab[find].mnemo;
669     break;
670     }
671     if (strlen(lookuptab[find].name) == 0) abort();
672     }
673     }
674     else {
675     table68k[opc].mnemo = lookuptab[find].mnemo;
676     }
677     table68k[opc].cc = bitval[bitc];
678     if (table68k[opc].mnemo == i_BTST
679     || table68k[opc].mnemo == i_BSET
680     || table68k[opc].mnemo == i_BCLR
681     || table68k[opc].mnemo == i_BCHG)
682     {
683     sz = destmode == Dreg ? sz_long : sz_byte;
684     }
685     table68k[opc].size = sz;
686     table68k[opc].sreg = srcreg;
687     table68k[opc].dreg = destreg;
688     table68k[opc].smode = srcmode;
689     table68k[opc].dmode = destmode;
690     table68k[opc].spos = srcgather ? srcpos : -1;
691     table68k[opc].dpos = dstgather ? dstpos : -1;
692     table68k[opc].suse = usesrc;
693     table68k[opc].duse = usedst;
694     table68k[opc].stype = srctype;
695     table68k[opc].plev = id.plevel;
696     table68k[opc].clev = id.cpulevel;
697     #if 0
698     for (i = 0; i < 5; i++) {
699     table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
700     table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
701     }
702     #endif
703     table68k[opc].flagdead = flagdead;
704     table68k[opc].flaglive = flaglive;
705     nomatch:
706     /* FOO! */;
707     }
708     }
709    
710    
711     void read_table68k (void)
712     {
713     int i;
714    
715     table68k = (struct instr *)malloc (65536 * sizeof (struct instr));
716     for (i = 0; i < 65536; i++) {
717     table68k[i].mnemo = i_ILLG;
718     table68k[i].handler = -1;
719     }
720     for (i = 0; i < n_defs68k; i++) {
721     build_insn (i);
722     }
723     }
724    
725     static int mismatch;
726    
727     static void handle_merges (long int opcode)
728     {
729     uae_u16 smsk;
730     uae_u16 dmsk;
731     int sbitdst, dstend;
732     int srcreg, dstreg;
733    
734     if (table68k[opcode].spos == -1) {
735     sbitdst = 1; smsk = 0;
736     } else {
737     switch (table68k[opcode].stype) {
738     case 0:
739     smsk = 7; sbitdst = 8; break;
740     case 1:
741     smsk = 255; sbitdst = 256; break;
742     case 2:
743     smsk = 15; sbitdst = 16; break;
744     case 3:
745     smsk = 7; sbitdst = 8; break;
746     case 4:
747     smsk = 7; sbitdst = 8; break;
748     case 5:
749     smsk = 63; sbitdst = 64; break;
750     default:
751     smsk = 0; sbitdst = 0;
752     abort();
753     break;
754     }
755     smsk <<= table68k[opcode].spos;
756     }
757     if (table68k[opcode].dpos == -1) {
758     dstend = 1; dmsk = 0;
759     } else {
760     dmsk = 7 << table68k[opcode].dpos;
761     dstend = 8;
762     }
763     for (srcreg=0; srcreg < sbitdst; srcreg++) {
764     for (dstreg=0; dstreg < dstend; dstreg++) {
765     uae_u16 code = opcode;
766    
767     code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
768     code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
769    
770     /* Check whether this is in fact the same instruction.
771     * The instructions should never differ, except for the
772     * Bcc.(BW) case. */
773     if (table68k[code].mnemo != table68k[opcode].mnemo
774     || table68k[code].size != table68k[opcode].size
775     || table68k[code].suse != table68k[opcode].suse
776     || table68k[code].duse != table68k[opcode].duse)
777     {
778     mismatch++; continue;
779     }
780     if (table68k[opcode].suse
781     && (table68k[opcode].spos != table68k[code].spos
782     || table68k[opcode].smode != table68k[code].smode
783     || table68k[opcode].stype != table68k[code].stype))
784     {
785     mismatch++; continue;
786     }
787     if (table68k[opcode].duse
788     && (table68k[opcode].dpos != table68k[code].dpos
789     || table68k[opcode].dmode != table68k[code].dmode))
790     {
791     mismatch++; continue;
792     }
793    
794     if (code != opcode)
795     table68k[code].handler = opcode;
796     }
797     }
798     }
799    
800     void do_merges (void)
801     {
802     long int opcode;
803     int nr = 0;
804     mismatch = 0;
805     for (opcode = 0; opcode < 65536; opcode++) {
806     if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
807     continue;
808     nr++;
809     handle_merges (opcode);
810     }
811     nr_cpuop_funcs = nr;
812     }
813    
814     int get_no_mismatches (void)
815     {
816     return mismatch;
817     }