]> Shamusworld >> Repos - virtualjaguar/blob - src/m68000/readcpu.c
3287e03b91d047fa68f158664455f6ded9759be2
[virtualjaguar] / src / m68000 / readcpu.c
1 /*
2  * UAE - The Un*x Amiga Emulator - CPU core
3  *
4  * Read 68000 CPU specs from file "table68k"
5  *
6  * Copyright 1995,1996 Bernd Schmidt
7  *
8  * Adaptation to Hatari by Thomas Huth
9  * Adaptation to Virtual Jaguar by James Hammons
10  *
11  * This file is distributed under the GNU Public License, version 3 or at
12  * your option any later version. Read the file GPLv3 for details.
13  */
14
15
16 /* 2008/04/26   [NP]    Handle sz_byte for Areg as a valid srcmode if current instruction is a MOVE     */
17 /*                      (e.g. move.b a1,(a0) ($1089)) (fix Blood Money on Superior 65)                  */
18
19
20 //const char ReadCpu_fileid[] = "Hatari readcpu.c : " __DATE__ " " __TIME__;
21
22 #include <ctype.h>
23 #include <string.h>
24
25 #include "readcpu.h"
26
27 int nr_cpuop_funcs;
28
29 const struct mnemolookup lookuptab[] = {
30         { i_ILLG, "ILLEGAL" },
31         { i_OR, "OR" },
32         { i_CHK, "CHK" },
33         { i_CHK2, "CHK2" },
34         { i_AND, "AND" },
35         { i_EOR, "EOR" },
36         { i_ORSR, "ORSR" },
37         { i_ANDSR, "ANDSR" },
38         { i_EORSR, "EORSR" },
39         { i_SUB, "SUB" },
40         { i_SUBA, "SUBA" },
41         { i_SUBX, "SUBX" },
42         { i_SBCD, "SBCD" },
43         { i_ADD, "ADD" },
44         { i_ADDA, "ADDA" },
45         { i_ADDX, "ADDX" },
46         { i_ABCD, "ABCD" },
47         { i_NEG, "NEG" },
48         { i_NEGX, "NEGX" },
49         { i_NBCD, "NBCD" },
50         { i_CLR, "CLR" },
51         { i_NOT, "NOT" },
52         { i_TST, "TST" },
53         { i_BTST, "BTST" },
54         { i_BCHG, "BCHG" },
55         { i_BCLR, "BCLR" },
56         { i_BSET, "BSET" },
57         { i_CMP, "CMP" },
58         { i_CMPM, "CMPM" },
59         { i_CMPA, "CMPA" },
60         { i_MVPRM, "MVPRM" },
61         { i_MVPMR, "MVPMR" },
62         { i_MOVE, "MOVE" },
63         { i_MOVEA, "MOVEA" },
64         { i_MVSR2, "MVSR2" },
65         { i_MV2SR, "MV2SR" },
66         { i_SWAP, "SWAP" },
67         { i_EXG, "EXG" },
68         { i_EXT, "EXT" },
69         { i_MVMEL, "MVMEL" },
70         { i_MVMLE, "MVMLE" },
71         { i_TRAP, "TRAP" },
72         { i_MVR2USP, "MVR2USP" },
73         { i_MVUSP2R, "MVUSP2R" },
74         { i_NOP, "NOP" },
75         { i_RESET, "RESET" },
76         { i_RTE, "RTE" },
77         { i_RTD, "RTD" },
78         { i_LINK, "LINK" },
79         { i_UNLK, "UNLK" },
80         { i_RTS, "RTS" },
81         { i_STOP, "STOP" },
82         { i_TRAPV, "TRAPV" },
83         { i_RTR, "RTR" },
84         { i_JSR, "JSR" },
85         { i_JMP, "JMP" },
86         { i_BSR, "BSR" },
87         { i_Bcc, "Bcc" },
88         { i_LEA, "LEA" },
89         { i_PEA, "PEA" },
90         { i_DBcc, "DBcc" },
91         { i_Scc, "Scc" },
92         { i_DIVU, "DIVU" },
93         { i_DIVS, "DIVS" },
94         { i_MULU, "MULU" },
95         { i_MULS, "MULS" },
96         { i_ASR, "ASR" },
97         { i_ASL, "ASL" },
98         { i_LSR, "LSR" },
99         { i_LSL, "LSL" },
100         { i_ROL, "ROL" },
101         { i_ROR, "ROR" },
102         { i_ROXL, "ROXL" },
103         { i_ROXR, "ROXR" },
104         { i_ASRW, "ASRW" },
105         { i_ASLW, "ASLW" },
106         { i_LSRW, "LSRW" },
107         { i_LSLW, "LSLW" },
108         { i_ROLW, "ROLW" },
109         { i_RORW, "RORW" },
110         { i_ROXLW, "ROXLW" },
111         { i_ROXRW, "ROXRW" },
112
113         { i_MOVE2C, "MOVE2C" },
114         { i_MOVEC2, "MOVEC2" },
115         { i_CAS, "CAS" },
116         { i_CAS2, "CAS2" },
117         { i_MULL, "MULL" },
118         { i_DIVL, "DIVL" },
119         { i_BFTST, "BFTST" },
120         { i_BFEXTU, "BFEXTU" },
121         { i_BFCHG, "BFCHG" },
122         { i_BFEXTS, "BFEXTS" },
123         { i_BFCLR, "BFCLR" },
124         { i_BFFFO, "BFFFO" },
125         { i_BFSET, "BFSET" },
126         { i_BFINS, "BFINS" },
127         { i_PACK, "PACK" },
128         { i_UNPK, "UNPK" },
129         { i_TAS, "TAS" },
130         { i_BKPT, "BKPT" },
131         { i_CALLM, "CALLM" },
132         { i_RTM, "RTM" },
133         { i_TRAPcc, "TRAPcc" },
134         { i_MOVES, "MOVES" },
135         { i_FPP, "FPP" },
136         { i_FDBcc, "FDBcc" },
137         { i_FScc, "FScc" },
138         { i_FTRAPcc, "FTRAPcc" },
139         { i_FBcc, "FBcc" },
140         { i_FBcc, "FBcc" },
141         { i_FSAVE, "FSAVE" },
142         { i_FRESTORE, "FRESTORE" },
143
144         { i_CINVL, "CINVL" },
145         { i_CINVP, "CINVP" },
146         { i_CINVA, "CINVA" },
147         { i_CPUSHL, "CPUSHL" },
148         { i_CPUSHP, "CPUSHP" },
149         { i_CPUSHA, "CPUSHA" },
150         { i_MOVE16, "MOVE16" },
151
152         { i_MMUOP, "MMUOP" },
153         { i_ILLG, "" },
154 };
155
156 struct instr *table68k;
157
158 STATIC_INLINE amodes mode_from_str(const char * str)
159 {
160         if (strncmp (str, "Dreg", 4) == 0) return Dreg;
161         if (strncmp (str, "Areg", 4) == 0) return Areg;
162         if (strncmp (str, "Aind", 4) == 0) return Aind;
163         if (strncmp (str, "Apdi", 4) == 0) return Apdi;
164         if (strncmp (str, "Aipi", 4) == 0) return Aipi;
165         if (strncmp (str, "Ad16", 4) == 0) return Ad16;
166         if (strncmp (str, "Ad8r", 4) == 0) return Ad8r;
167         if (strncmp (str, "absw", 4) == 0) return absw;
168         if (strncmp (str, "absl", 4) == 0) return absl;
169         if (strncmp (str, "PC16", 4) == 0) return PC16;
170         if (strncmp (str, "PC8r", 4) == 0) return PC8r;
171         if (strncmp (str, "Immd", 4) == 0) return imm;
172
173         abort();
174         return 0;
175 }
176
177 STATIC_INLINE amodes mode_from_mr(int mode, int reg)
178 {
179         switch (mode)
180         {
181                 case 0: return Dreg;
182                 case 1: return Areg;
183                 case 2: return Aind;
184                 case 3: return Aipi;
185                 case 4: return Apdi;
186                 case 5: return Ad16;
187                 case 6: return Ad8r;
188                 case 7:
189                 switch (reg)
190                 {
191                         case 0: return absw;
192                         case 1: return absl;
193                         case 2: return PC16;
194                         case 3: return PC8r;
195                         case 4: return imm;
196                         case 5:
197                         case 6:
198                         case 7: return am_illg;
199                 }
200         }
201
202         abort();
203         return 0;
204 }
205
206 static void build_insn(int insn)
207 {
208         int find = -1;
209         int variants;
210         int isjmp = 0;
211         struct instr_def id;
212         const char * opcstr;
213         int j;
214
215         int flaglive = 0, flagdead = 0;
216         id = defs68k[insn];
217
218         /* Note: We treat anything with unknown flags as a jump. That
219            is overkill, but "the programmer" was lazy quite often, and
220            *this* programmer can't be bothered to work out what can and
221            can't trap. Usually, this will be overwritten with the gencomp
222            based information, anyway. */
223
224         for(j=0; j<5; j++)
225         {
226                 switch (id.flaginfo[j].flagset)
227                 {
228                 case fa_unset: break;
229                 case fa_isjmp: isjmp = 1; break;
230                 case fa_isbranch: isjmp = 1; break;
231                 case fa_zero: flagdead |= 1 << j; break;
232                 case fa_one: flagdead |= 1 << j; break;
233                 case fa_dontcare: flagdead |= 1 << j; break;
234                 case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
235                 case fa_set: flagdead |= 1 << j; break;
236                 }
237     }
238
239 out1:
240         for(j=0; j<5; j++)
241         {
242                 switch (id.flaginfo[j].flaguse)
243                 {
244                 case fu_unused: break;
245                 case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
246                 case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
247                 case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
248                 case fu_used: flaglive |= 1 << j; break;
249                 }
250         }
251
252         opcstr = id.opcstr;
253
254         for(variants=0; variants<(1 << id.n_variable); variants++)
255         {
256                 int bitcnt[lastbit];
257                 int bitval[lastbit];
258                 int bitpos[lastbit];
259                 int i;
260                 uint16_t opc = id.bits;
261                 uint16_t msk, vmsk;
262                 int pos = 0;
263                 int mnp = 0;
264                 int bitno = 0;
265                 char mnemonic[10];
266
267                 wordsizes sz = sz_long;
268                 int srcgather = 0, dstgather = 0;
269                 int usesrc = 0, usedst = 0;
270                 int srctype = 0;
271                 int srcpos = -1, dstpos = -1;
272
273                 amodes srcmode = am_unknown, destmode = am_unknown;
274                 int srcreg = -1, destreg = -1;
275
276                 for(i=0; i<lastbit; i++)
277                         bitcnt[i] = bitval[i] = 0;
278
279                 vmsk = 1 << id.n_variable;
280
281                 for(i=0, msk=0x8000; i<16; i++, msk >>= 1)
282                 {
283                         if (!(msk & id.mask))
284                         {
285                                 int currbit = id.bitpos[bitno++];
286                                 int bit_set;
287                                 vmsk >>= 1;
288                                 bit_set = (variants & vmsk ? 1 : 0);
289
290                                 if (bit_set)
291                                         opc |= msk;
292
293                                 bitpos[currbit] = 15 - i;
294                                 bitcnt[currbit]++;
295                                 bitval[currbit] <<= 1;
296                                 bitval[currbit] |= bit_set;
297                         }
298                 }
299
300                 if (bitval[bitj] == 0)
301                         bitval[bitj] = 8;
302
303                 /* first check whether this one does not match after all */
304                 if (bitval[bitz] == 3 || bitval[bitC] == 1)
305                         continue;
306
307                 if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
308                         continue;
309
310                 /* bitI and bitC get copied to biti and bitc */
311                 if (bitcnt[bitI])
312                 {
313                         bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
314                 }
315
316                 if (bitcnt[bitC])
317                         bitval[bitc] = bitval[bitC];
318
319                 pos = 0;
320                 while (opcstr[pos] && !isspace((unsigned)opcstr[pos]))
321                 {
322                         if (opcstr[pos] == '.')
323                         {
324                                 pos++;
325
326                                 switch (opcstr[pos])
327                                 {
328                                 case 'B': sz = sz_byte; break;
329                                 case 'W': sz = sz_word; break;
330                                 case 'L': sz = sz_long; break;
331                                 case 'z':
332                                         switch (bitval[bitz])
333                                         {
334                                         case 0: sz = sz_byte; break;
335                                         case 1: sz = sz_word; break;
336                                         case 2: sz = sz_long; break;
337                                         default: abort();
338                                         }
339                                         break;
340                                 default: abort();
341                                 }
342                         }
343                         else
344                         {
345                                 mnemonic[mnp] = opcstr[pos];
346
347                                 if (mnemonic[mnp] == 'f')
348                                 {
349                                         find = -1;
350                                         switch (bitval[bitf])
351                                         {
352                                         case 0: mnemonic[mnp] = 'R'; break;
353                                         case 1: mnemonic[mnp] = 'L'; break;
354                                         default: abort();
355                                         }
356                                 }
357
358                                 mnp++;
359                         }
360
361                         pos++;
362                 }
363
364                 mnemonic[mnp] = 0;
365
366                 /* now, we have read the mnemonic and the size */
367                 while (opcstr[pos] && isspace((unsigned)opcstr[pos]))
368                         pos++;
369
370                 /* A goto a day keeps the D******a away. */
371                 if (opcstr[pos] == 0)
372                         goto endofline;
373
374                 /* parse the source address */
375                 usesrc = 1;
376                 switch (opcstr[pos++])
377                 {
378                 case 'D':
379                         srcmode = Dreg;
380
381                         switch (opcstr[pos++])
382                         {
383                         case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
384                         case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
385                         default: abort();
386                         }
387
388                         break;
389                 case 'A':
390                         srcmode = Areg;
391
392                         switch (opcstr[pos++])
393                         {
394                         case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
395                         case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
396                         default: abort();
397                         }
398
399                         switch (opcstr[pos])
400                         {
401                         case 'p': srcmode = Apdi; pos++; break;
402                         case 'P': srcmode = Aipi; pos++; break;
403                         }
404                         break;
405
406                 case 'L':
407                         srcmode = absl;
408                         break;
409                 case '#':
410                         switch (opcstr[pos++])
411                         {
412                         case 'z': srcmode = imm; break;
413                         case '0': srcmode = imm0; break;
414                         case '1': srcmode = imm1; break;
415                         case '2': srcmode = imm2; break;
416                         case 'i':
417                                 srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
418
419                                 if (CPU_EMU_SIZE < 4)
420                                 {
421                                         /* Used for branch instructions */
422                                         srctype = 1;
423                                         srcgather = 1;
424                                         srcpos = bitpos[biti];
425                                 }
426
427                                 break;
428                         case 'j':
429                                 srcmode = immi; srcreg = bitval[bitj];
430
431                                 if (CPU_EMU_SIZE < 3)
432                                 {
433                                         /* 1..8 for ADDQ/SUBQ and rotshi insns */
434                                         srcgather = 1;
435                                         srctype = 3;
436                                         srcpos = bitpos[bitj];
437                                 }
438
439                                 break;
440                         case 'J':
441                                 srcmode = immi; srcreg = bitval[bitJ];
442
443                                 if (CPU_EMU_SIZE < 5)
444                                 {
445                                         /* 0..15 */
446                                         srcgather = 1;
447                                         srctype = 2;
448                                         srcpos = bitpos[bitJ];
449                                 }
450
451                                 break;
452                         case 'k':
453                                 srcmode = immi; srcreg = bitval[bitk];
454
455                                 if (CPU_EMU_SIZE < 3)
456                                 {
457                                         srcgather = 1;
458                                         srctype = 4;
459                                         srcpos = bitpos[bitk];
460                                 }
461
462                                 break;
463                         case 'K':
464                                 srcmode = immi; srcreg = bitval[bitK];
465
466                                 if (CPU_EMU_SIZE < 5)
467                                 {
468                                         /* 0..15 */
469                                         srcgather = 1;
470                                         srctype = 5;
471                                         srcpos = bitpos[bitK];
472                                 }
473
474                                 break;
475                         case 'p':
476                                 srcmode = immi; srcreg = bitval[bitK];
477
478                                 if (CPU_EMU_SIZE < 5)
479                                 {
480                                         /* 0..3 */
481                                         srcgather = 1;
482                                         srctype = 7;
483                                         srcpos = bitpos[bitp];
484                                 }
485
486                                 break;
487                         default: abort();
488                         }
489
490                         break;
491                 case 'd':
492                         srcreg = bitval[bitD];
493                         srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
494
495                         if (srcmode == am_illg)
496                                 continue;
497
498                         if (CPU_EMU_SIZE < 2
499                                 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
500                                 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
501                                 || srcmode == Apdi))
502                         {
503                                 srcgather = 1;
504                                 srcpos = bitpos[bitD];
505                         }
506
507                         if (opcstr[pos] == '[')
508                         {
509                                 pos++;
510
511                                 if (opcstr[pos] == '!')
512                                 {
513                                         /* exclusion */
514                                         do
515                                         {
516                                                 pos++;
517
518                                                 if (mode_from_str(opcstr + pos) == srcmode)
519                                                         goto nomatch;
520
521                                                 pos += 4;
522                                         }
523                                         while (opcstr[pos] == ',');
524
525                                         pos++;
526                                 }
527                                 else
528                                 {
529                                         if (opcstr[pos + 4] == '-')
530                                         {
531                                                 /* replacement */
532                                                 if (mode_from_str(opcstr + pos) == srcmode)
533                                                         srcmode = mode_from_str(opcstr + pos + 5);
534                                                 else
535                                                         goto nomatch;
536
537                                                 pos += 10;
538                                         }
539                                         else
540                                         {
541                                                 /* normal */
542                                                 while(mode_from_str(opcstr + pos) != srcmode)
543                                                 {
544                                                         pos += 4;
545
546                                                         if (opcstr[pos] == ']')
547                                                                 goto nomatch;
548
549                                                         pos++;
550                                                 }
551
552                                                 while(opcstr[pos] != ']')
553                                                         pos++;
554
555                                                 pos++;
556                                                 break;
557                                         }
558                                 }
559                         }
560
561                         /* Some addressing modes are invalid as destination */
562                         if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
563                                 goto nomatch;
564
565                         break;
566                 case 's':
567                         srcreg = bitval[bitS];
568                         srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
569
570                         if (srcmode == am_illg)
571                                 continue;
572
573                         if (CPU_EMU_SIZE < 2
574                                 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
575                                 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
576                                 || srcmode == Apdi))
577                         {
578                                 srcgather = 1;
579                                 srcpos = bitpos[bitS];
580                         }
581
582                         if (opcstr[pos] == '[')
583                         {
584                                 pos++;
585
586                                 if (opcstr[pos] == '!')
587                                 {
588                                         /* exclusion */
589                                         do
590                                         {
591                                                 pos++;
592
593                                                 if (mode_from_str(opcstr + pos) == srcmode)
594                                                         goto nomatch;
595
596                                                 pos += 4;
597                                         }
598                                         while (opcstr[pos] == ',');
599
600                                         pos++;
601                                 }
602                                 else
603                                 {
604                                         if (opcstr[pos + 4] == '-')
605                                         {
606                                                 /* replacement */
607                                                 if (mode_from_str(opcstr + pos) == srcmode)
608                                                         srcmode = mode_from_str(opcstr + pos + 5);
609                                                 else
610                                                         goto nomatch;
611
612                                                 pos += 10;
613                                         }
614                                         else
615                                         {
616                                                 /* normal */
617                                                 while(mode_from_str(opcstr+pos) != srcmode)
618                                                 {
619                                                         pos += 4;
620
621                                                         if (opcstr[pos] == ']')
622                                                                 goto nomatch;
623
624                                                         pos++;
625                                                 }
626
627                                                 while(opcstr[pos] != ']')
628                                                         pos++;
629
630                                                 pos++;
631                                         }
632                                 }
633                         }
634                         break;
635                 default: abort();
636                 }
637
638                 /* safety check - might have changed */
639                 if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
640                         && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
641                         && srcmode != Apdi && srcmode != immi)
642                 {
643                         srcgather = 0;
644                 }
645
646 //              if (srcmode == Areg && sz == sz_byte)
647                 if (srcmode == Areg && sz == sz_byte && strcmp(mnemonic, "MOVE") != 0 ) // [NP] move.b is valid on 68000
648                         goto nomatch;
649
650                 if (opcstr[pos] != ',')
651                         goto endofline;
652
653                 pos++;
654
655                 /* parse the destination address */
656                 usedst = 1;
657
658                 switch (opcstr[pos++])
659                 {
660                 case 'D':
661                         destmode = Dreg;
662
663                         switch (opcstr[pos++])
664                         {
665                         case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
666                         case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
667                         default: abort();
668                         }
669
670                         if (dstpos < 0 || dstpos >= 32)
671                                 abort();
672
673                         break;
674                 case 'A':
675                         destmode = Areg;
676
677                         switch (opcstr[pos++])
678                         {
679                         case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
680                         case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
681                         case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
682                         default: abort();
683                         }
684
685                         if (dstpos < 0 || dstpos >= 32)
686                                 abort();
687
688                         switch (opcstr[pos])
689                         {
690                         case 'p': destmode = Apdi; pos++; break;
691                         case 'P': destmode = Aipi; pos++; break;
692                         }
693
694                         break;
695                 case 'L':
696                         destmode = absl;
697                         break;
698                 case '#':
699                         switch (opcstr[pos++])
700                         {
701                         case 'z': destmode = imm; break;
702                         case '0': destmode = imm0; break;
703                         case '1': destmode = imm1; break;
704                         case '2': destmode = imm2; break;
705                         case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
706                         case 'j': destmode = immi; destreg = bitval[bitj]; break;
707                         case 'J': destmode = immi; destreg = bitval[bitJ]; break;
708                         case 'k': destmode = immi; destreg = bitval[bitk]; break;
709                         case 'K': destmode = immi; destreg = bitval[bitK]; break;
710                         default: abort();
711                         }
712                         break;
713                 case 'd':
714                         destreg = bitval[bitD];
715                         destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
716
717                         if (destmode == am_illg)
718                                 continue;
719
720                         if (CPU_EMU_SIZE < 1
721                                 && (destmode == Areg || destmode == Dreg || destmode == Aind
722                                 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
723                                 || destmode == Apdi))
724                         {
725                                 dstgather = 1;
726                                 dstpos = bitpos[bitD];
727                         }
728
729                         if (opcstr[pos] == '[')
730                         {
731                                 pos++;
732
733                                 if (opcstr[pos] == '!')
734                                 {
735                                         /* exclusion */
736                                         do
737                                         {
738                                                 pos++;
739
740                                                 if (mode_from_str(opcstr + pos) == destmode)
741                                                         goto nomatch;
742
743                                                 pos += 4;
744                                         }
745                                         while (opcstr[pos] == ',');
746
747                                         pos++;
748                                 }
749                                 else
750                                 {
751                                         if (opcstr[pos+4] == '-')
752                                         {
753                                                 /* replacement */
754                                                 if (mode_from_str(opcstr + pos) == destmode)
755                                                         destmode = mode_from_str(opcstr + pos + 5);
756                                                 else
757                                                         goto nomatch;
758
759                                                 pos += 10;
760                                         }
761                                         else
762                                         {
763                                                 /* normal */
764                                                 while(mode_from_str(opcstr + pos) != destmode)
765                                                 {
766                                                         pos += 4;
767
768                                                         if (opcstr[pos] == ']')
769                                                                 goto nomatch;
770
771                                                         pos++;
772                                                 }
773
774                                                 while(opcstr[pos] != ']')
775                                                         pos++;
776
777                                                 pos++;
778                                                 break;
779                                         }
780                                 }
781                         }
782
783                         /* Some addressing modes are invalid as destination */
784                         if (destmode == imm || destmode == PC16 || destmode == PC8r)
785                                 goto nomatch;
786
787                         break;
788                 case 's':
789                         destreg = bitval[bitS];
790                         destmode = mode_from_mr(bitval[bits], bitval[bitS]);
791
792                         if (destmode == am_illg)
793                         continue;
794                         if (CPU_EMU_SIZE < 1
795                                 && (destmode == Areg || destmode == Dreg || destmode == Aind
796                                 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
797                                 || destmode == Apdi))
798                         {
799                                 dstgather = 1;
800                                 dstpos = bitpos[bitS];
801                         }
802
803                         if (opcstr[pos] == '[')
804                         {
805                                 pos++;
806
807                                 if (opcstr[pos] == '!')
808                                 {
809                                         /* exclusion */
810                                         do
811                                         {
812                                                 pos++;
813
814                                                 if (mode_from_str(opcstr + pos) == destmode)
815                                                         goto nomatch;
816
817                                                 pos += 4;
818                                         }
819                                         while (opcstr[pos] == ',');
820
821                                         pos++;
822                                 }
823                                 else
824                                 {
825                                         if (opcstr[pos+4] == '-')
826                                         {
827                                                 /* replacement */
828                                                 if (mode_from_str(opcstr + pos) == destmode)
829                                                         destmode = mode_from_str(opcstr + pos + 5);
830                                                 else
831                                                         goto nomatch;
832
833                                                 pos += 10;
834                                         }
835                                         else
836                                         {
837                                                 /* normal */
838                                                 while (mode_from_str(opcstr + pos) != destmode)
839                                                 {
840                                                         pos += 4;
841
842                                                         if (opcstr[pos] == ']')
843                                                                 goto nomatch;
844
845                                                         pos++;
846                                                 }
847
848                                                 while (opcstr[pos] != ']')
849                                                         pos++;
850
851                                                 pos++;
852                                         }
853                                 }
854                         }
855                         break;
856                 default: abort();
857                 }
858
859                 /* safety check - might have changed */
860                 if (destmode != Areg && destmode != Dreg && destmode != Aind
861                         && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
862                         && destmode != Apdi)
863                 {
864                         dstgather = 0;
865                 }
866
867                 if (destmode == Areg && sz == sz_byte)
868                         goto nomatch;
869 #if 0
870                 if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
871                         dstgather = 0;
872                 }
873 #endif
874 endofline:
875                 /* now, we have a match */
876                 if (table68k[opc].mnemo != i_ILLG)
877                         fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
878
879                 if (find == -1)
880                 {
881                         for(find=0; ; find++)
882                         {
883                                 if (strcmp(mnemonic, lookuptab[find].name) == 0)
884                                 {
885                                         table68k[opc].mnemo = lookuptab[find].mnemo;
886                                         break;
887                                 }
888
889                                 if (strlen(lookuptab[find].name) == 0)
890                                         abort();
891                         }
892                 }
893                 else
894                 {
895                         table68k[opc].mnemo = lookuptab[find].mnemo;
896                 }
897
898                 table68k[opc].cc = bitval[bitc];
899
900                 if (table68k[opc].mnemo == i_BTST
901                         || table68k[opc].mnemo == i_BSET
902                         || table68k[opc].mnemo == i_BCLR
903                         || table68k[opc].mnemo == i_BCHG)
904                 {
905                         sz = (destmode == Dreg ? sz_long : sz_byte);
906                 }
907
908                 table68k[opc].size = sz;
909                 table68k[opc].sreg = srcreg;
910                 table68k[opc].dreg = destreg;
911                 table68k[opc].smode = srcmode;
912                 table68k[opc].dmode = destmode;
913                 table68k[opc].spos = (srcgather ? srcpos : -1);
914                 table68k[opc].dpos = (dstgather ? dstpos : -1);
915                 table68k[opc].suse = usesrc;
916                 table68k[opc].duse = usedst;
917                 table68k[opc].stype = srctype;
918                 table68k[opc].plev = id.plevel;
919                 table68k[opc].clev = id.cpulevel;
920 #if 0
921                 for (i = 0; i < 5; i++) {
922                         table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
923                         table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
924                 }
925 #endif
926                 table68k[opc].flagdead = flagdead;
927                 table68k[opc].flaglive = flaglive;
928                 table68k[opc].isjmp = isjmp;
929
930 nomatch:
931         /* FOO! */;
932     }
933 }
934
935
936 void read_table68k(void)
937 {
938         int i;
939         table68k = (struct instr *)malloc(65536 * sizeof(struct instr));
940
941         for(i=0; i<65536; i++)
942         {
943                 table68k[i].mnemo = i_ILLG;
944                 table68k[i].handler = -1;
945         }
946
947         for(i=0; i<n_defs68k; i++)
948                 build_insn(i);
949 }
950
951 static int mismatch;
952
953 static void handle_merges (long int opcode)
954 {
955         uint16_t smsk;
956         uint16_t dmsk;
957         int sbitdst, dstend;
958         int srcreg, dstreg;
959
960 //0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W  s,d[!Areg]
961 //31C3 ->
962 //0011 0001 1100 0011 : DDD = 0, ddd = 7, sss = 0, SSS = 3
963
964         if (table68k[opcode].spos == -1)
965         {
966                 sbitdst = 1;
967                 smsk = 0;
968         }
969         else
970         {
971                 switch (table68k[opcode].stype)
972                 {
973                 case 0:
974                         smsk = 7; sbitdst = 8; break;
975                 case 1:
976                         smsk = 255; sbitdst = 256; break;
977                 case 2:
978                         smsk = 15; sbitdst = 16; break;
979                 case 3:
980                         smsk = 7; sbitdst = 8; break;
981                 case 4:
982                         smsk = 7; sbitdst = 8; break;
983                 case 5:
984                         smsk = 63; sbitdst = 64; break;
985                 case 7:
986                         smsk = 3; sbitdst = 4; break;
987                 default:
988                         smsk = 0; sbitdst = 0;
989                         abort();
990                         break;
991                 }
992
993                 smsk <<= table68k[opcode].spos;
994         }
995
996         if (table68k[opcode].dpos == -1)
997         {
998                 dmsk = 0;
999                 dstend = 1;
1000         }
1001         else
1002         {
1003                 dmsk = 7 << table68k[opcode].dpos;
1004                 dstend = 8;
1005         }
1006
1007         for(srcreg=0; srcreg<sbitdst; srcreg++)
1008         {
1009                 for(dstreg=0; dstreg<dstend; dstreg++)
1010                 {
1011                         uint16_t code = opcode;
1012
1013                         code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
1014                         code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
1015
1016                         /* Check whether this is in fact the same instruction.
1017                         * The instructions should never differ, except for the
1018                         * Bcc.(BW) case. */
1019                         if (table68k[code].mnemo != table68k[opcode].mnemo
1020                                 || table68k[code].size != table68k[opcode].size
1021                                 || table68k[code].suse != table68k[opcode].suse
1022                                 || table68k[code].duse != table68k[opcode].duse)
1023                         {
1024                                 mismatch++;
1025                                 continue;
1026                         }
1027
1028                         if (table68k[opcode].suse
1029                                 && (table68k[opcode].spos != table68k[code].spos
1030                                 || table68k[opcode].smode != table68k[code].smode
1031                                 || table68k[opcode].stype != table68k[code].stype))
1032                         {
1033                                 mismatch++;
1034                                 continue;
1035                         }
1036
1037                         if (table68k[opcode].duse
1038                                 && (table68k[opcode].dpos != table68k[code].dpos
1039                                 || table68k[opcode].dmode != table68k[code].dmode))
1040                         {
1041                                 mismatch++;
1042                                 continue;
1043                         }
1044
1045                         if (code != opcode)
1046                         {
1047                                 table68k[code].handler = opcode;
1048
1049 #if 0
1050 if (opcode == 0x31C3 || code == 0x31C3)
1051 {
1052         printf("Relocate... ($%04X->$%04X)\n", (uint16_t)opcode, code);
1053         printf(" handler: %08X\n", table68k[code].handler);
1054         printf("    dreg: %i\n", table68k[code].dreg);
1055         printf("    sreg: %i\n", table68k[code].sreg);
1056         printf("    dpos: %i\n", table68k[code].dpos);
1057         printf("    spos: %i\n", table68k[code].spos);
1058         printf("   sduse: %i\n", table68k[code].sduse);
1059         printf("flagdead: %i\n", table68k[code].flagdead);
1060         printf("flaglive: %i\n", table68k[code].flaglive);
1061 }
1062 #endif
1063 /*
1064     long int handler;
1065     unsigned char dreg;
1066     unsigned char sreg;
1067     signed char dpos;
1068     signed char spos;
1069     unsigned char sduse;
1070     int flagdead:8, flaglive:8;
1071     unsigned int mnemo:8;
1072     unsigned int cc:4;
1073     unsigned int plev:2;
1074     unsigned int size:2;
1075     unsigned int smode:5;
1076     unsigned int stype:3;
1077     unsigned int dmode:5;
1078     unsigned int suse:1;
1079     unsigned int duse:1;
1080     unsigned int unused1:1;
1081     unsigned int clev:3;
1082     unsigned int isjmp:1;
1083     unsigned int unused2:4;
1084 */
1085                         }
1086                 }
1087         }
1088 }
1089
1090 // What this really does is expand the # of handlers, which is why the
1091 // opcode has to be passed into the opcode handler...
1092 // E.g., $F620 maps into $F621-F627 as well; this code does this expansion.
1093 void do_merges(void)
1094 {
1095         long int opcode;
1096         int nr = 0;
1097         mismatch = 0;
1098
1099         for(opcode=0; opcode<65536; opcode++)
1100         {
1101                 if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
1102                         continue;
1103
1104                 nr++;
1105                 handle_merges(opcode);
1106         }
1107
1108         nr_cpuop_funcs = nr;
1109 }
1110
1111 int get_no_mismatches(void)
1112 {
1113         return mismatch;
1114 }