ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/readcpu.cpp
Revision: 1.3
Committed: 2001-03-19T13:11:40Z (23 years, 8 months ago) by gbeauche
Branch: MAIN
CVS Tags: snapshot-29052001, release-0_9-1
Changes since 1.2: +12 -0 lines
Log Message:
Additions:
- MOVE16 (Ay)+,(xxx).L
- MOVE16 (xxx).L,(Ay)+
- MOVE16 (Ay),(xxx).L
- MOVE16 (xxx).L,(Ay)

Fixes:
- MOVE16 (Ax)+,(Ay)+ where x == y: address register shall be incremented
  only once
- CINV, CPUSH: 'p' field matches correctly the instruction 'cache field'

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