ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/readcpu.cpp
Revision: 1.1
Committed: 1999-10-03T14:16:26Z (24 years, 9 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

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     { i_MMUOP, "MMUOP" },
134     { i_ILLG, "" },
135     };
136    
137     struct instr *table68k;
138    
139     static __inline__ amodes mode_from_str (const char *str)
140     {
141     if (strncmp (str, "Dreg", 4) == 0) return Dreg;
142     if (strncmp (str, "Areg", 4) == 0) return Areg;
143     if (strncmp (str, "Aind", 4) == 0) return Aind;
144     if (strncmp (str, "Apdi", 4) == 0) return Apdi;
145     if (strncmp (str, "Aipi", 4) == 0) return Aipi;
146     if (strncmp (str, "Ad16", 4) == 0) return Ad16;
147     if (strncmp (str, "Ad8r", 4) == 0) return Ad8r;
148     if (strncmp (str, "absw", 4) == 0) return absw;
149     if (strncmp (str, "absl", 4) == 0) return absl;
150     if (strncmp (str, "PC16", 4) == 0) return PC16;
151     if (strncmp (str, "PC8r", 4) == 0) return PC8r;
152     if (strncmp (str, "Immd", 4) == 0) return imm;
153     abort ();
154     return (amodes)0;
155     }
156    
157     static __inline__ amodes mode_from_mr (int mode, int reg)
158     {
159     switch (mode) {
160     case 0: return Dreg;
161     case 1: return Areg;
162     case 2: return Aind;
163     case 3: return Aipi;
164     case 4: return Apdi;
165     case 5: return Ad16;
166     case 6: return Ad8r;
167     case 7:
168     switch (reg) {
169     case 0: return absw;
170     case 1: return absl;
171     case 2: return PC16;
172     case 3: return PC8r;
173     case 4: return imm;
174     case 5:
175     case 6:
176     case 7: return am_illg;
177     }
178     }
179     abort ();
180     return (amodes)0;
181     }
182    
183     static void build_insn (int insn)
184     {
185     int find = -1;
186     int variants;
187     struct instr_def id;
188     const char *opcstr;
189     int i;
190    
191     int flaglive = 0, flagdead = 0;
192    
193     id = defs68k[insn];
194    
195     for (i = 0; i < 5; i++) {
196     switch (id.flaginfo[i].flagset){
197     case fa_unset: break;
198     case fa_isjmp: break;
199     case fa_zero: flagdead |= 1 << i; break;
200     case fa_one: flagdead |= 1 << i; break;
201     case fa_dontcare: flagdead |= 1 << i; break;
202     case fa_unknown: flagdead = -1; goto out1;
203     case fa_set: flagdead |= 1 << i; break;
204     }
205     }
206    
207     out1:
208     for (i = 0; i < 5; i++) {
209     switch (id.flaginfo[i].flaguse) {
210     case fu_unused: break;
211     case fu_isjmp: flaglive |= 1 << i; break;
212     case fu_maybecc: flaglive |= 1 << i; break;
213     case fu_unknown: flaglive = -1; goto out2;
214     case fu_used: flaglive |= 1 << i; break;
215     }
216     }
217     out2:
218    
219     opcstr = id.opcstr;
220     for (variants = 0; variants < (1 << id.n_variable); variants++) {
221     int bitcnt[lastbit];
222     int bitval[lastbit];
223     int bitpos[lastbit];
224     int i;
225     uae_u16 opc = id.bits;
226     uae_u16 msk, vmsk;
227     int pos = 0;
228     int mnp = 0;
229     int bitno = 0;
230     char mnemonic[10];
231    
232     wordsizes sz = sz_long;
233     int srcgather = 0, dstgather = 0;
234     int usesrc = 0, usedst = 0;
235     int srctype = 0;
236     int srcpos = -1, dstpos = -1;
237    
238     amodes srcmode = am_unknown, destmode = am_unknown;
239     int srcreg = -1, destreg = -1;
240    
241     for (i = 0; i < lastbit; i++)
242     bitcnt[i] = bitval[i] = 0;
243    
244     vmsk = 1 << id.n_variable;
245    
246     for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) {
247     if (!(msk & id.mask)) {
248     int currbit = id.bitpos[bitno++];
249     int bit_set;
250     vmsk >>= 1;
251     bit_set = variants & vmsk ? 1 : 0;
252     if (bit_set)
253     opc |= msk;
254     bitpos[currbit] = 15 - i;
255     bitcnt[currbit]++;
256     bitval[currbit] <<= 1;
257     bitval[currbit] |= bit_set;
258     }
259     }
260    
261     if (bitval[bitj] == 0) bitval[bitj] = 8;
262     /* first check whether this one does not match after all */
263     if (bitval[bitz] == 3 || bitval[bitC] == 1)
264     continue;
265     if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
266     continue;
267    
268     /* bitI and bitC get copied to biti and bitc */
269     if (bitcnt[bitI]) {
270     bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
271     }
272     if (bitcnt[bitC])
273     bitval[bitc] = bitval[bitC];
274    
275     pos = 0;
276     while (opcstr[pos] && !isspace(opcstr[pos])) {
277     if (opcstr[pos] == '.') {
278     pos++;
279     switch (opcstr[pos]) {
280    
281     case 'B': sz = sz_byte; break;
282     case 'W': sz = sz_word; break;
283     case 'L': sz = sz_long; break;
284     case 'z':
285     switch (bitval[bitz]) {
286     case 0: sz = sz_byte; break;
287     case 1: sz = sz_word; break;
288     case 2: sz = sz_long; break;
289     default: abort();
290     }
291     break;
292     default: abort();
293     }
294     } else {
295     mnemonic[mnp] = opcstr[pos];
296     if (mnemonic[mnp] == 'f') {
297     find = -1;
298     switch (bitval[bitf]) {
299     case 0: mnemonic[mnp] = 'R'; break;
300     case 1: mnemonic[mnp] = 'L'; break;
301     default: abort();
302     }
303     }
304     mnp++;
305     }
306     pos++;
307     }
308     mnemonic[mnp] = 0;
309    
310     /* now, we have read the mnemonic and the size */
311     while (opcstr[pos] && isspace(opcstr[pos]))
312     pos++;
313    
314     /* A goto a day keeps the D******a away. */
315     if (opcstr[pos] == 0)
316     goto endofline;
317    
318     /* parse the source address */
319     usesrc = 1;
320     switch (opcstr[pos++]) {
321     case 'D':
322     srcmode = Dreg;
323     switch (opcstr[pos++]) {
324     case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
325     case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
326     default: abort();
327     }
328    
329     break;
330     case 'A':
331     srcmode = Areg;
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     switch (opcstr[pos]) {
338     case 'p': srcmode = Apdi; pos++; break;
339     case 'P': srcmode = Aipi; pos++; break;
340     }
341     break;
342     case '#':
343     switch (opcstr[pos++]) {
344     case 'z': srcmode = imm; break;
345     case '0': srcmode = imm0; break;
346     case '1': srcmode = imm1; break;
347     case '2': srcmode = imm2; break;
348     case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti];
349     if (CPU_EMU_SIZE < 4) {
350     /* Used for branch instructions */
351     srctype = 1;
352     srcgather = 1;
353     srcpos = bitpos[biti];
354     }
355     break;
356     case 'j': srcmode = immi; srcreg = bitval[bitj];
357     if (CPU_EMU_SIZE < 3) {
358     /* 1..8 for ADDQ/SUBQ and rotshi insns */
359     srcgather = 1;
360     srctype = 3;
361     srcpos = bitpos[bitj];
362     }
363     break;
364     case 'J': srcmode = immi; srcreg = bitval[bitJ];
365     if (CPU_EMU_SIZE < 5) {
366     /* 0..15 */
367     srcgather = 1;
368     srctype = 2;
369     srcpos = bitpos[bitJ];
370     }
371     break;
372     case 'k': srcmode = immi; srcreg = bitval[bitk];
373     if (CPU_EMU_SIZE < 3) {
374     srcgather = 1;
375     srctype = 4;
376     srcpos = bitpos[bitk];
377     }
378     break;
379     case 'K': srcmode = immi; srcreg = bitval[bitK];
380     if (CPU_EMU_SIZE < 5) {
381     /* 0..15 */
382     srcgather = 1;
383     srctype = 5;
384     srcpos = bitpos[bitK];
385     }
386     break;
387     default: abort();
388     }
389     break;
390     case 'd':
391     srcreg = bitval[bitD];
392     srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
393     if (srcmode == am_illg)
394     continue;
395     if (CPU_EMU_SIZE < 2 &&
396     (srcmode == Areg || srcmode == Dreg || srcmode == Aind
397     || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
398     || srcmode == Apdi))
399     {
400     srcgather = 1; srcpos = bitpos[bitD];
401     }
402     if (opcstr[pos] == '[') {
403     pos++;
404     if (opcstr[pos] == '!') {
405     /* exclusion */
406     do {
407     pos++;
408     if (mode_from_str(opcstr+pos) == srcmode)
409     goto nomatch;
410     pos += 4;
411     } while (opcstr[pos] == ',');
412     pos++;
413     } else {
414     if (opcstr[pos+4] == '-') {
415     /* replacement */
416     if (mode_from_str(opcstr+pos) == srcmode)
417     srcmode = mode_from_str(opcstr+pos+5);
418     else
419     goto nomatch;
420     pos += 10;
421     } else {
422     /* normal */
423     while(mode_from_str(opcstr+pos) != srcmode) {
424     pos += 4;
425     if (opcstr[pos] == ']')
426     goto nomatch;
427     pos++;
428     }
429     while(opcstr[pos] != ']') pos++;
430     pos++;
431     break;
432     }
433     }
434     }
435     /* Some addressing modes are invalid as destination */
436     if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
437     goto nomatch;
438     break;
439     case 's':
440     srcreg = bitval[bitS];
441     srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
442    
443     if (srcmode == am_illg)
444     continue;
445     if (CPU_EMU_SIZE < 2 &&
446     (srcmode == Areg || srcmode == Dreg || srcmode == Aind
447     || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
448     || srcmode == Apdi))
449     {
450     srcgather = 1; srcpos = bitpos[bitS];
451     }
452     if (opcstr[pos] == '[') {
453     pos++;
454     if (opcstr[pos] == '!') {
455     /* exclusion */
456     do {
457     pos++;
458     if (mode_from_str(opcstr+pos) == srcmode)
459     goto nomatch;
460     pos += 4;
461     } while (opcstr[pos] == ',');
462     pos++;
463     } else {
464     if (opcstr[pos+4] == '-') {
465     /* replacement */
466     if (mode_from_str(opcstr+pos) == srcmode)
467     srcmode = mode_from_str(opcstr+pos+5);
468     else
469     goto nomatch;
470     pos += 10;
471     } else {
472     /* normal */
473     while(mode_from_str(opcstr+pos) != srcmode) {
474     pos += 4;
475     if (opcstr[pos] == ']')
476     goto nomatch;
477     pos++;
478     }
479     while(opcstr[pos] != ']') pos++;
480     pos++;
481     }
482     }
483     }
484     break;
485     default: abort();
486     }
487     /* safety check - might have changed */
488     if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
489     && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
490     && srcmode != Apdi && srcmode != immi)
491     {
492     srcgather = 0;
493     }
494     if (srcmode == Areg && sz == sz_byte)
495     goto nomatch;
496    
497     if (opcstr[pos] != ',')
498     goto endofline;
499     pos++;
500    
501     /* parse the destination address */
502     usedst = 1;
503     switch (opcstr[pos++]) {
504     case 'D':
505     destmode = Dreg;
506     switch (opcstr[pos++]) {
507     case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
508     case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
509     default: abort();
510     }
511     break;
512     case 'A':
513     destmode = Areg;
514     switch (opcstr[pos++]) {
515     case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
516     case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
517     default: abort();
518     }
519     switch (opcstr[pos]) {
520     case 'p': destmode = Apdi; pos++; break;
521     case 'P': destmode = Aipi; pos++; break;
522     }
523     break;
524     case '#':
525     switch (opcstr[pos++]) {
526     case 'z': destmode = imm; break;
527     case '0': destmode = imm0; break;
528     case '1': destmode = imm1; break;
529     case '2': destmode = imm2; break;
530     case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break;
531     case 'j': destmode = immi; destreg = bitval[bitj]; break;
532     case 'J': destmode = immi; destreg = bitval[bitJ]; break;
533     case 'k': destmode = immi; destreg = bitval[bitk]; break;
534     case 'K': destmode = immi; destreg = bitval[bitK]; break;
535     default: abort();
536     }
537     break;
538     case 'd':
539     destreg = bitval[bitD];
540     destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
541     if (destmode == am_illg)
542     continue;
543     if (CPU_EMU_SIZE < 1 &&
544     (destmode == Areg || destmode == Dreg || destmode == Aind
545     || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
546     || destmode == Apdi))
547     {
548     dstgather = 1; dstpos = bitpos[bitD];
549     }
550    
551     if (opcstr[pos] == '[') {
552     pos++;
553     if (opcstr[pos] == '!') {
554     /* exclusion */
555     do {
556     pos++;
557     if (mode_from_str(opcstr+pos) == destmode)
558     goto nomatch;
559     pos += 4;
560     } while (opcstr[pos] == ',');
561     pos++;
562     } else {
563     if (opcstr[pos+4] == '-') {
564     /* replacement */
565     if (mode_from_str(opcstr+pos) == destmode)
566     destmode = mode_from_str(opcstr+pos+5);
567     else
568     goto nomatch;
569     pos += 10;
570     } else {
571     /* normal */
572     while(mode_from_str(opcstr+pos) != destmode) {
573     pos += 4;
574     if (opcstr[pos] == ']')
575     goto nomatch;
576     pos++;
577     }
578     while(opcstr[pos] != ']') pos++;
579     pos++;
580     break;
581     }
582     }
583     }
584     /* Some addressing modes are invalid as destination */
585     if (destmode == imm || destmode == PC16 || destmode == PC8r)
586     goto nomatch;
587     break;
588     case 's':
589     destreg = bitval[bitS];
590     destmode = mode_from_mr(bitval[bits],bitval[bitS]);
591    
592     if (destmode == am_illg)
593     continue;
594     if (CPU_EMU_SIZE < 1 &&
595     (destmode == Areg || destmode == Dreg || destmode == Aind
596     || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
597     || destmode == Apdi))
598     {
599     dstgather = 1; dstpos = bitpos[bitS];
600     }
601    
602     if (opcstr[pos] == '[') {
603     pos++;
604     if (opcstr[pos] == '!') {
605     /* exclusion */
606     do {
607     pos++;
608     if (mode_from_str(opcstr+pos) == destmode)
609     goto nomatch;
610     pos += 4;
611     } while (opcstr[pos] == ',');
612     pos++;
613     } else {
614     if (opcstr[pos+4] == '-') {
615     /* replacement */
616     if (mode_from_str(opcstr+pos) == destmode)
617     destmode = mode_from_str(opcstr+pos+5);
618     else
619     goto nomatch;
620     pos += 10;
621     } else {
622     /* normal */
623     while(mode_from_str(opcstr+pos) != destmode) {
624     pos += 4;
625     if (opcstr[pos] == ']')
626     goto nomatch;
627     pos++;
628     }
629     while(opcstr[pos] != ']') pos++;
630     pos++;
631     }
632     }
633     }
634     break;
635     default: abort();
636     }
637     /* safety check - might have changed */
638     if (destmode != Areg && destmode != Dreg && destmode != Aind
639     && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
640     && destmode != Apdi)
641     {
642     dstgather = 0;
643     }
644    
645     if (destmode == Areg && sz == sz_byte)
646     goto nomatch;
647     #if 0
648     if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
649     dstgather = 0;
650     }
651     #endif
652     endofline:
653     /* now, we have a match */
654     if (table68k[opc].mnemo != i_ILLG)
655     fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
656     if (find == -1) {
657     for (find = 0;; find++) {
658     if (strcmp(mnemonic, lookuptab[find].name) == 0) {
659     table68k[opc].mnemo = lookuptab[find].mnemo;
660     break;
661     }
662     if (strlen(lookuptab[find].name) == 0) abort();
663     }
664     }
665     else {
666     table68k[opc].mnemo = lookuptab[find].mnemo;
667     }
668     table68k[opc].cc = bitval[bitc];
669     if (table68k[opc].mnemo == i_BTST
670     || table68k[opc].mnemo == i_BSET
671     || table68k[opc].mnemo == i_BCLR
672     || table68k[opc].mnemo == i_BCHG)
673     {
674     sz = destmode == Dreg ? sz_long : sz_byte;
675     }
676     table68k[opc].size = sz;
677     table68k[opc].sreg = srcreg;
678     table68k[opc].dreg = destreg;
679     table68k[opc].smode = srcmode;
680     table68k[opc].dmode = destmode;
681     table68k[opc].spos = srcgather ? srcpos : -1;
682     table68k[opc].dpos = dstgather ? dstpos : -1;
683     table68k[opc].suse = usesrc;
684     table68k[opc].duse = usedst;
685     table68k[opc].stype = srctype;
686     table68k[opc].plev = id.plevel;
687     table68k[opc].clev = id.cpulevel;
688     #if 0
689     for (i = 0; i < 5; i++) {
690     table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
691     table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
692     }
693     #endif
694     table68k[opc].flagdead = flagdead;
695     table68k[opc].flaglive = flaglive;
696     nomatch:
697     /* FOO! */;
698     }
699     }
700    
701    
702     void read_table68k (void)
703     {
704     int i;
705    
706     table68k = (struct instr *)malloc (65536 * sizeof (struct instr));
707     for (i = 0; i < 65536; i++) {
708     table68k[i].mnemo = i_ILLG;
709     table68k[i].handler = -1;
710     }
711     for (i = 0; i < n_defs68k; i++) {
712     build_insn (i);
713     }
714     }
715    
716     static int mismatch;
717    
718     static void handle_merges (long int opcode)
719     {
720     uae_u16 smsk;
721     uae_u16 dmsk;
722     int sbitdst, dstend;
723     int srcreg, dstreg;
724    
725     if (table68k[opcode].spos == -1) {
726     sbitdst = 1; smsk = 0;
727     } else {
728     switch (table68k[opcode].stype) {
729     case 0:
730     smsk = 7; sbitdst = 8; break;
731     case 1:
732     smsk = 255; sbitdst = 256; break;
733     case 2:
734     smsk = 15; sbitdst = 16; break;
735     case 3:
736     smsk = 7; sbitdst = 8; break;
737     case 4:
738     smsk = 7; sbitdst = 8; break;
739     case 5:
740     smsk = 63; sbitdst = 64; break;
741     default:
742     smsk = 0; sbitdst = 0;
743     abort();
744     break;
745     }
746     smsk <<= table68k[opcode].spos;
747     }
748     if (table68k[opcode].dpos == -1) {
749     dstend = 1; dmsk = 0;
750     } else {
751     dmsk = 7 << table68k[opcode].dpos;
752     dstend = 8;
753     }
754     for (srcreg=0; srcreg < sbitdst; srcreg++) {
755     for (dstreg=0; dstreg < dstend; dstreg++) {
756     uae_u16 code = opcode;
757    
758     code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
759     code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
760    
761     /* Check whether this is in fact the same instruction.
762     * The instructions should never differ, except for the
763     * Bcc.(BW) case. */
764     if (table68k[code].mnemo != table68k[opcode].mnemo
765     || table68k[code].size != table68k[opcode].size
766     || table68k[code].suse != table68k[opcode].suse
767     || table68k[code].duse != table68k[opcode].duse)
768     {
769     mismatch++; continue;
770     }
771     if (table68k[opcode].suse
772     && (table68k[opcode].spos != table68k[code].spos
773     || table68k[opcode].smode != table68k[code].smode
774     || table68k[opcode].stype != table68k[code].stype))
775     {
776     mismatch++; continue;
777     }
778     if (table68k[opcode].duse
779     && (table68k[opcode].dpos != table68k[code].dpos
780     || table68k[opcode].dmode != table68k[code].dmode))
781     {
782     mismatch++; continue;
783     }
784    
785     if (code != opcode)
786     table68k[code].handler = opcode;
787     }
788     }
789     }
790    
791     void do_merges (void)
792     {
793     long int opcode;
794     int nr = 0;
795     mismatch = 0;
796     for (opcode = 0; opcode < 65536; opcode++) {
797     if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
798     continue;
799     nr++;
800     handle_merges (opcode);
801     }
802     nr_cpuop_funcs = nr;
803     }
804    
805     int get_no_mismatches (void)
806     {
807     return mismatch;
808     }