]> Shamusworld >> Repos - virtualjaguar/blob - src/m68000/readcpu.c
4fcb100926c2dc1073f24c9835c7249f213661f8
[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
157 struct instr * table68k;
158
159
160 STATIC_INLINE amodes mode_from_str(const char * str)
161 {
162         if (strncmp (str, "Dreg", 4) == 0) return Dreg;
163         if (strncmp (str, "Areg", 4) == 0) return Areg;
164         if (strncmp (str, "Aind", 4) == 0) return Aind;
165         if (strncmp (str, "Apdi", 4) == 0) return Apdi;
166         if (strncmp (str, "Aipi", 4) == 0) return Aipi;
167         if (strncmp (str, "Ad16", 4) == 0) return Ad16;
168         if (strncmp (str, "Ad8r", 4) == 0) return Ad8r;
169         if (strncmp (str, "absw", 4) == 0) return absw;
170         if (strncmp (str, "absl", 4) == 0) return absl;
171         if (strncmp (str, "PC16", 4) == 0) return PC16;
172         if (strncmp (str, "PC8r", 4) == 0) return PC8r;
173         if (strncmp (str, "Immd", 4) == 0) return imm;
174
175         abort();
176         return 0;
177 }
178
179
180 STATIC_INLINE amodes mode_from_mr(int mode, int reg)
181 {
182         switch (mode)
183         {
184                 case 0: return Dreg;
185                 case 1: return Areg;
186                 case 2: return Aind;
187                 case 3: return Aipi;
188                 case 4: return Apdi;
189                 case 5: return Ad16;
190                 case 6: return Ad8r;
191                 case 7:
192                 switch (reg)
193                 {
194                         case 0: return absw;
195                         case 1: return absl;
196                         case 2: return PC16;
197                         case 3: return PC8r;
198                         case 4: return imm;
199                         case 5:
200                         case 6:
201                         case 7: return am_illg;
202                 }
203         }
204
205         abort();
206         return 0;
207 }
208
209
210 static void build_insn(int insn)
211 {
212         int find = -1;
213         int variants;
214         int isjmp = 0;
215         struct instr_def id;
216         const char * opcstr;
217         int j;
218
219         int flaglive = 0, flagdead = 0;
220         id = defs68k[insn];
221
222         /* Note: We treat anything with unknown flags as a jump. That
223            is overkill, but "the programmer" was lazy quite often, and
224            *this* programmer can't be bothered to work out what can and
225            can't trap. Usually, this will be overwritten with the gencomp
226            based information, anyway. */
227
228         for(j=0; j<5; j++)
229         {
230                 switch (id.flaginfo[j].flagset)
231                 {
232                 case fa_unset: break;
233                 case fa_isjmp: isjmp = 1; break;
234                 case fa_isbranch: isjmp = 1; break;
235                 case fa_zero: flagdead |= 1 << j; break;
236                 case fa_one: flagdead |= 1 << j; break;
237                 case fa_dontcare: flagdead |= 1 << j; break;
238                 case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
239                 case fa_set: flagdead |= 1 << j; break;
240                 }
241     }
242
243 out1:
244         for(j=0; j<5; j++)
245         {
246                 switch (id.flaginfo[j].flaguse)
247                 {
248                 case fu_unused: break;
249                 case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
250                 case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
251                 case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
252                 case fu_used: flaglive |= 1 << j; break;
253                 }
254         }
255
256         opcstr = id.opcstr;
257
258         for(variants=0; variants<(1 << id.n_variable); variants++)
259         {
260                 int bitcnt[lastbit];
261                 int bitval[lastbit];
262                 int bitpos[lastbit];
263                 int i;
264                 uint16_t opc = id.bits;
265                 uint16_t msk, vmsk;
266                 int pos = 0;
267                 int mnp = 0;
268                 int bitno = 0;
269                 char mnemonic[10];
270
271                 wordsizes sz = sz_long;
272                 int srcgather = 0, dstgather = 0;
273                 int usesrc = 0, usedst = 0;
274                 int srctype = 0;
275                 int srcpos = -1, dstpos = -1;
276
277                 amodes srcmode = am_unknown, destmode = am_unknown;
278                 int srcreg = -1, destreg = -1;
279
280                 for(i=0; i<lastbit; i++)
281                         bitcnt[i] = bitval[i] = 0;
282
283                 vmsk = 1 << id.n_variable;
284
285                 for(i=0, msk=0x8000; i<16; i++, msk >>= 1)
286                 {
287                         if (!(msk & id.mask))
288                         {
289                                 int currbit = id.bitpos[bitno++];
290                                 int bit_set;
291                                 vmsk >>= 1;
292                                 bit_set = (variants & vmsk ? 1 : 0);
293
294                                 if (bit_set)
295                                         opc |= msk;
296
297                                 bitpos[currbit] = 15 - i;
298                                 bitcnt[currbit]++;
299                                 bitval[currbit] <<= 1;
300                                 bitval[currbit] |= bit_set;
301                         }
302                 }
303
304                 if (bitval[bitj] == 0)
305                         bitval[bitj] = 8;
306
307                 /* first check whether this one does not match after all */
308                 if (bitval[bitz] == 3 || bitval[bitC] == 1)
309                         continue;
310
311                 if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
312                         continue;
313
314                 /* bitI and bitC get copied to biti and bitc */
315                 if (bitcnt[bitI])
316                 {
317                         bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
318                 }
319
320                 if (bitcnt[bitC])
321                         bitval[bitc] = bitval[bitC];
322
323                 pos = 0;
324                 while (opcstr[pos] && !isspace((unsigned)opcstr[pos]))
325                 {
326                         if (opcstr[pos] == '.')
327                         {
328                                 pos++;
329
330                                 switch (opcstr[pos])
331                                 {
332                                 case 'B': sz = sz_byte; break;
333                                 case 'W': sz = sz_word; break;
334                                 case 'L': sz = sz_long; break;
335                                 case 'z':
336                                         switch (bitval[bitz])
337                                         {
338                                         case 0: sz = sz_byte; break;
339                                         case 1: sz = sz_word; break;
340                                         case 2: sz = sz_long; break;
341                                         default: abort();
342                                         }
343                                         break;
344                                 default: abort();
345                                 }
346                         }
347                         else
348                         {
349                                 mnemonic[mnp] = opcstr[pos];
350
351                                 if (mnemonic[mnp] == 'f')
352                                 {
353                                         find = -1;
354                                         switch (bitval[bitf])
355                                         {
356                                         case 0: mnemonic[mnp] = 'R'; break;
357                                         case 1: mnemonic[mnp] = 'L'; break;
358                                         default: abort();
359                                         }
360                                 }
361
362                                 mnp++;
363                         }
364
365                         pos++;
366                 }
367
368                 mnemonic[mnp] = 0;
369
370                 /* now, we have read the mnemonic and the size */
371                 while (opcstr[pos] && isspace((unsigned)opcstr[pos]))
372                         pos++;
373
374                 /* A goto a day keeps the D******a away. */
375                 if (opcstr[pos] == 0)
376                         goto endofline;
377
378                 /* parse the source address */
379                 usesrc = 1;
380                 switch (opcstr[pos++])
381                 {
382                 case 'D':
383                         srcmode = Dreg;
384
385                         switch (opcstr[pos++])
386                         {
387                         case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
388                         case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
389                         default: abort();
390                         }
391
392                         break;
393                 case 'A':
394                         srcmode = Areg;
395
396                         switch (opcstr[pos++])
397                         {
398                         case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
399                         case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
400                         default: abort();
401                         }
402
403                         switch (opcstr[pos])
404                         {
405                         case 'p': srcmode = Apdi; pos++; break;
406                         case 'P': srcmode = Aipi; pos++; break;
407                         }
408                         break;
409
410                 case 'L':
411                         srcmode = absl;
412                         break;
413                 case '#':
414                         switch (opcstr[pos++])
415                         {
416                         case 'z': srcmode = imm; break;
417                         case '0': srcmode = imm0; break;
418                         case '1': srcmode = imm1; break;
419                         case '2': srcmode = imm2; break;
420                         case 'i':
421                                 srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
422
423                                 if (CPU_EMU_SIZE < 4)
424                                 {
425                                         /* Used for branch instructions */
426                                         srctype = 1;
427                                         srcgather = 1;
428                                         srcpos = bitpos[biti];
429                                 }
430
431                                 break;
432                         case 'j':
433                                 srcmode = immi; srcreg = bitval[bitj];
434
435                                 if (CPU_EMU_SIZE < 3)
436                                 {
437                                         /* 1..8 for ADDQ/SUBQ and rotshi insns */
438                                         srcgather = 1;
439                                         srctype = 3;
440                                         srcpos = bitpos[bitj];
441                                 }
442
443                                 break;
444                         case 'J':
445                                 srcmode = immi; srcreg = bitval[bitJ];
446
447                                 if (CPU_EMU_SIZE < 5)
448                                 {
449                                         /* 0..15 */
450                                         srcgather = 1;
451                                         srctype = 2;
452                                         srcpos = bitpos[bitJ];
453                                 }
454
455                                 break;
456                         case 'k':
457                                 srcmode = immi; srcreg = bitval[bitk];
458
459                                 if (CPU_EMU_SIZE < 3)
460                                 {
461                                         srcgather = 1;
462                                         srctype = 4;
463                                         srcpos = bitpos[bitk];
464                                 }
465
466                                 break;
467                         case 'K':
468                                 srcmode = immi; srcreg = bitval[bitK];
469
470                                 if (CPU_EMU_SIZE < 5)
471                                 {
472                                         /* 0..15 */
473                                         srcgather = 1;
474                                         srctype = 5;
475                                         srcpos = bitpos[bitK];
476                                 }
477
478                                 break;
479                         case 'p':
480                                 srcmode = immi; srcreg = bitval[bitK];
481
482                                 if (CPU_EMU_SIZE < 5)
483                                 {
484                                         /* 0..3 */
485                                         srcgather = 1;
486                                         srctype = 7;
487                                         srcpos = bitpos[bitp];
488                                 }
489
490                                 break;
491                         default: abort();
492                         }
493
494                         break;
495                 case 'd':
496                         srcreg = bitval[bitD];
497                         srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
498
499                         if (srcmode == am_illg)
500                                 continue;
501
502                         if (CPU_EMU_SIZE < 2
503                                 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
504                                 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
505                                 || srcmode == Apdi))
506                         {
507                                 srcgather = 1;
508                                 srcpos = bitpos[bitD];
509                         }
510
511                         if (opcstr[pos] == '[')
512                         {
513                                 pos++;
514
515                                 if (opcstr[pos] == '!')
516                                 {
517                                         /* exclusion */
518                                         do
519                                         {
520                                                 pos++;
521
522                                                 if (mode_from_str(opcstr + pos) == srcmode)
523                                                         goto nomatch;
524
525                                                 pos += 4;
526                                         }
527                                         while (opcstr[pos] == ',');
528
529                                         pos++;
530                                 }
531                                 else
532                                 {
533                                         if (opcstr[pos + 4] == '-')
534                                         {
535                                                 /* replacement */
536                                                 if (mode_from_str(opcstr + pos) == srcmode)
537                                                         srcmode = mode_from_str(opcstr + pos + 5);
538                                                 else
539                                                         goto nomatch;
540
541                                                 pos += 10;
542                                         }
543                                         else
544                                         {
545                                                 /* normal */
546                                                 while(mode_from_str(opcstr + pos) != srcmode)
547                                                 {
548                                                         pos += 4;
549
550                                                         if (opcstr[pos] == ']')
551                                                                 goto nomatch;
552
553                                                         pos++;
554                                                 }
555
556                                                 while(opcstr[pos] != ']')
557                                                         pos++;
558
559                                                 pos++;
560                                                 break;
561                                         }
562                                 }
563                         }
564
565                         /* Some addressing modes are invalid as destination */
566                         if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
567                                 goto nomatch;
568
569                         break;
570                 case 's':
571                         srcreg = bitval[bitS];
572                         srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
573
574                         if (srcmode == am_illg)
575                                 continue;
576
577                         if (CPU_EMU_SIZE < 2
578                                 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
579                                 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
580                                 || srcmode == Apdi))
581                         {
582                                 srcgather = 1;
583                                 srcpos = bitpos[bitS];
584                         }
585
586                         if (opcstr[pos] == '[')
587                         {
588                                 pos++;
589
590                                 if (opcstr[pos] == '!')
591                                 {
592                                         /* exclusion */
593                                         do
594                                         {
595                                                 pos++;
596
597                                                 if (mode_from_str(opcstr + pos) == srcmode)
598                                                         goto nomatch;
599
600                                                 pos += 4;
601                                         }
602                                         while (opcstr[pos] == ',');
603
604                                         pos++;
605                                 }
606                                 else
607                                 {
608                                         if (opcstr[pos + 4] == '-')
609                                         {
610                                                 /* replacement */
611                                                 if (mode_from_str(opcstr + pos) == srcmode)
612                                                         srcmode = mode_from_str(opcstr + pos + 5);
613                                                 else
614                                                         goto nomatch;
615
616                                                 pos += 10;
617                                         }
618                                         else
619                                         {
620                                                 /* normal */
621                                                 while(mode_from_str(opcstr+pos) != srcmode)
622                                                 {
623                                                         pos += 4;
624
625                                                         if (opcstr[pos] == ']')
626                                                                 goto nomatch;
627
628                                                         pos++;
629                                                 }
630
631                                                 while(opcstr[pos] != ']')
632                                                         pos++;
633
634                                                 pos++;
635                                         }
636                                 }
637                         }
638                         break;
639                 default: abort();
640                 }
641
642                 /* safety check - might have changed */
643                 if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
644                         && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
645                         && srcmode != Apdi && srcmode != immi)
646                 {
647                         srcgather = 0;
648                 }
649
650 //              if (srcmode == Areg && sz == sz_byte)
651                 if (srcmode == Areg && sz == sz_byte && strcmp(mnemonic, "MOVE") != 0 ) // [NP] move.b is valid on 68000
652                         goto nomatch;
653
654                 if (opcstr[pos] != ',')
655                         goto endofline;
656
657                 pos++;
658
659                 /* parse the destination address */
660                 usedst = 1;
661
662                 switch (opcstr[pos++])
663                 {
664                 case 'D':
665                         destmode = Dreg;
666
667                         switch (opcstr[pos++])
668                         {
669                         case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
670                         case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
671                         default: abort();
672                         }
673
674                         if (dstpos < 0 || dstpos >= 32)
675                                 abort();
676
677                         break;
678                 case 'A':
679                         destmode = Areg;
680
681                         switch (opcstr[pos++])
682                         {
683                         case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
684                         case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
685                         case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
686                         default: abort();
687                         }
688
689                         if (dstpos < 0 || dstpos >= 32)
690                                 abort();
691
692                         switch (opcstr[pos])
693                         {
694                         case 'p': destmode = Apdi; pos++; break;
695                         case 'P': destmode = Aipi; pos++; break;
696                         }
697
698                         break;
699                 case 'L':
700                         destmode = absl;
701                         break;
702                 case '#':
703                         switch (opcstr[pos++])
704                         {
705                         case 'z': destmode = imm; break;
706                         case '0': destmode = imm0; break;
707                         case '1': destmode = imm1; break;
708                         case '2': destmode = imm2; break;
709                         case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
710                         case 'j': destmode = immi; destreg = bitval[bitj]; break;
711                         case 'J': destmode = immi; destreg = bitval[bitJ]; break;
712                         case 'k': destmode = immi; destreg = bitval[bitk]; break;
713                         case 'K': destmode = immi; destreg = bitval[bitK]; break;
714                         default: abort();
715                         }
716                         break;
717                 case 'd':
718                         destreg = bitval[bitD];
719                         destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
720
721                         if (destmode == am_illg)
722                                 continue;
723
724                         if (CPU_EMU_SIZE < 1
725                                 && (destmode == Areg || destmode == Dreg || destmode == Aind
726                                 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
727                                 || destmode == Apdi))
728                         {
729                                 dstgather = 1;
730                                 dstpos = bitpos[bitD];
731                         }
732
733                         if (opcstr[pos] == '[')
734                         {
735                                 pos++;
736
737                                 if (opcstr[pos] == '!')
738                                 {
739                                         /* exclusion */
740                                         do
741                                         {
742                                                 pos++;
743
744                                                 if (mode_from_str(opcstr + pos) == destmode)
745                                                         goto nomatch;
746
747                                                 pos += 4;
748                                         }
749                                         while (opcstr[pos] == ',');
750
751                                         pos++;
752                                 }
753                                 else
754                                 {
755                                         if (opcstr[pos+4] == '-')
756                                         {
757                                                 /* replacement */
758                                                 if (mode_from_str(opcstr + pos) == destmode)
759                                                         destmode = mode_from_str(opcstr + pos + 5);
760                                                 else
761                                                         goto nomatch;
762
763                                                 pos += 10;
764                                         }
765                                         else
766                                         {
767                                                 /* normal */
768                                                 while(mode_from_str(opcstr + pos) != destmode)
769                                                 {
770                                                         pos += 4;
771
772                                                         if (opcstr[pos] == ']')
773                                                                 goto nomatch;
774
775                                                         pos++;
776                                                 }
777
778                                                 while(opcstr[pos] != ']')
779                                                         pos++;
780
781                                                 pos++;
782                                                 break;
783                                         }
784                                 }
785                         }
786
787                         /* Some addressing modes are invalid as destination */
788                         if (destmode == imm || destmode == PC16 || destmode == PC8r)
789                                 goto nomatch;
790
791                         break;
792                 case 's':
793                         destreg = bitval[bitS];
794                         destmode = mode_from_mr(bitval[bits], bitval[bitS]);
795
796                         if (destmode == am_illg)
797                         continue;
798                         if (CPU_EMU_SIZE < 1
799                                 && (destmode == Areg || destmode == Dreg || destmode == Aind
800                                 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
801                                 || destmode == Apdi))
802                         {
803                                 dstgather = 1;
804                                 dstpos = bitpos[bitS];
805                         }
806
807                         if (opcstr[pos] == '[')
808                         {
809                                 pos++;
810
811                                 if (opcstr[pos] == '!')
812                                 {
813                                         /* exclusion */
814                                         do
815                                         {
816                                                 pos++;
817
818                                                 if (mode_from_str(opcstr + pos) == destmode)
819                                                         goto nomatch;
820
821                                                 pos += 4;
822                                         }
823                                         while (opcstr[pos] == ',');
824
825                                         pos++;
826                                 }
827                                 else
828                                 {
829                                         if (opcstr[pos+4] == '-')
830                                         {
831                                                 /* replacement */
832                                                 if (mode_from_str(opcstr + pos) == destmode)
833                                                         destmode = mode_from_str(opcstr + pos + 5);
834                                                 else
835                                                         goto nomatch;
836
837                                                 pos += 10;
838                                         }
839                                         else
840                                         {
841                                                 /* normal */
842                                                 while (mode_from_str(opcstr + pos) != destmode)
843                                                 {
844                                                         pos += 4;
845
846                                                         if (opcstr[pos] == ']')
847                                                                 goto nomatch;
848
849                                                         pos++;
850                                                 }
851
852                                                 while (opcstr[pos] != ']')
853                                                         pos++;
854
855                                                 pos++;
856                                         }
857                                 }
858                         }
859                         break;
860                 default: abort();
861                 }
862
863                 /* safety check - might have changed */
864                 if (destmode != Areg && destmode != Dreg && destmode != Aind
865                         && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
866                         && destmode != Apdi)
867                 {
868                         dstgather = 0;
869                 }
870
871                 if (destmode == Areg && sz == sz_byte)
872                         goto nomatch;
873 #if 0
874                 if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
875                         dstgather = 0;
876                 }
877 #endif
878 endofline:
879                 /* now, we have a match */
880                 if (table68k[opc].mnemo != i_ILLG)
881                         fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
882
883                 if (find == -1)
884                 {
885                         for(find=0; ; find++)
886                         {
887                                 if (strcmp(mnemonic, lookuptab[find].name) == 0)
888                                 {
889                                         table68k[opc].mnemo = lookuptab[find].mnemo;
890                                         break;
891                                 }
892
893                                 if (strlen(lookuptab[find].name) == 0)
894                                         abort();
895                         }
896                 }
897                 else
898                 {
899                         table68k[opc].mnemo = lookuptab[find].mnemo;
900                 }
901
902                 table68k[opc].cc = bitval[bitc];
903
904                 if (table68k[opc].mnemo == i_BTST
905                         || table68k[opc].mnemo == i_BSET
906                         || table68k[opc].mnemo == i_BCLR
907                         || table68k[opc].mnemo == i_BCHG)
908                 {
909                         sz = (destmode == Dreg ? sz_long : sz_byte);
910                 }
911
912                 table68k[opc].size = sz;
913                 table68k[opc].sreg = srcreg;
914                 table68k[opc].dreg = destreg;
915                 table68k[opc].smode = srcmode;
916                 table68k[opc].dmode = destmode;
917                 table68k[opc].spos = (srcgather ? srcpos : -1);
918                 table68k[opc].dpos = (dstgather ? dstpos : -1);
919                 table68k[opc].suse = usesrc;
920                 table68k[opc].duse = usedst;
921                 table68k[opc].stype = srctype;
922                 table68k[opc].plev = id.plevel;
923                 table68k[opc].clev = id.cpulevel;
924 #if 0
925                 for (i = 0; i < 5; i++) {
926                         table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
927                         table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
928                 }
929 #endif
930                 table68k[opc].flagdead = flagdead;
931                 table68k[opc].flaglive = flaglive;
932                 table68k[opc].isjmp = isjmp;
933
934 nomatch:
935         /* FOO! */;
936     }
937 }
938
939
940 void read_table68k(void)
941 {
942         int i;
943         table68k = (struct instr *)malloc(65536 * sizeof(struct instr));
944
945         for(i=0; i<65536; i++)
946         {
947                 table68k[i].mnemo = i_ILLG;
948                 table68k[i].handler = -1;
949         }
950
951         for(i=0; i<n_defs68k; i++)
952                 build_insn(i);
953 }
954
955
956 static int mismatch;
957
958
959 static void handle_merges (long int opcode)
960 {
961         uint16_t smsk;
962         uint16_t dmsk;
963         int sbitdst, dstend;
964         int srcreg, dstreg;
965
966 //0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W  s,d[!Areg]
967 //31C3 ->
968 //0011 0001 1100 0011 : DDD = 0, ddd = 7, sss = 0, SSS = 3
969
970         if (table68k[opcode].spos == -1)
971         {
972                 sbitdst = 1;
973                 smsk = 0;
974         }
975         else
976         {
977                 switch (table68k[opcode].stype)
978                 {
979                 case 0:
980                         smsk = 7; sbitdst = 8; break;
981                 case 1:
982                         smsk = 255; sbitdst = 256; break;
983                 case 2:
984                         smsk = 15; sbitdst = 16; break;
985                 case 3:
986                         smsk = 7; sbitdst = 8; break;
987                 case 4:
988                         smsk = 7; sbitdst = 8; break;
989                 case 5:
990                         smsk = 63; sbitdst = 64; break;
991                 case 7:
992                         smsk = 3; sbitdst = 4; break;
993                 default:
994                         smsk = 0; sbitdst = 0;
995                         abort();
996                         break;
997                 }
998
999                 smsk <<= table68k[opcode].spos;
1000         }
1001
1002         if (table68k[opcode].dpos == -1)
1003         {
1004                 dmsk = 0;
1005                 dstend = 1;
1006         }
1007         else
1008         {
1009                 dmsk = 7 << table68k[opcode].dpos;
1010                 dstend = 8;
1011         }
1012
1013         for(srcreg=0; srcreg<sbitdst; srcreg++)
1014         {
1015                 for(dstreg=0; dstreg<dstend; dstreg++)
1016                 {
1017                         uint16_t code = opcode;
1018
1019                         code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
1020                         code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
1021
1022                         /* Check whether this is in fact the same instruction.
1023                         * The instructions should never differ, except for the
1024                         * Bcc.(BW) case. */
1025                         if (table68k[code].mnemo != table68k[opcode].mnemo
1026                                 || table68k[code].size != table68k[opcode].size
1027                                 || table68k[code].suse != table68k[opcode].suse
1028                                 || table68k[code].duse != table68k[opcode].duse)
1029                         {
1030                                 mismatch++;
1031                                 continue;
1032                         }
1033
1034                         if (table68k[opcode].suse
1035                                 && (table68k[opcode].spos != table68k[code].spos
1036                                 || table68k[opcode].smode != table68k[code].smode
1037                                 || table68k[opcode].stype != table68k[code].stype))
1038                         {
1039                                 mismatch++;
1040                                 continue;
1041                         }
1042
1043                         if (table68k[opcode].duse
1044                                 && (table68k[opcode].dpos != table68k[code].dpos
1045                                 || table68k[opcode].dmode != table68k[code].dmode))
1046                         {
1047                                 mismatch++;
1048                                 continue;
1049                         }
1050
1051                         if (code != opcode)
1052                         {
1053                                 table68k[code].handler = opcode;
1054
1055 #if 0
1056 if (opcode == 0x31C3 || code == 0x31C3)
1057 {
1058         printf("Relocate... ($%04X->$%04X)\n", (uint16_t)opcode, code);
1059         printf(" handler: %08X\n", table68k[code].handler);
1060         printf("    dreg: %i\n", table68k[code].dreg);
1061         printf("    sreg: %i\n", table68k[code].sreg);
1062         printf("    dpos: %i\n", table68k[code].dpos);
1063         printf("    spos: %i\n", table68k[code].spos);
1064         printf("   sduse: %i\n", table68k[code].sduse);
1065         printf("flagdead: %i\n", table68k[code].flagdead);
1066         printf("flaglive: %i\n", table68k[code].flaglive);
1067 }
1068 #endif
1069 /*
1070     long int handler;
1071     unsigned char dreg;
1072     unsigned char sreg;
1073     signed char dpos;
1074     signed char spos;
1075     unsigned char sduse;
1076     int flagdead:8, flaglive:8;
1077     unsigned int mnemo:8;
1078     unsigned int cc:4;
1079     unsigned int plev:2;
1080     unsigned int size:2;
1081     unsigned int smode:5;
1082     unsigned int stype:3;
1083     unsigned int dmode:5;
1084     unsigned int suse:1;
1085     unsigned int duse:1;
1086     unsigned int unused1:1;
1087     unsigned int clev:3;
1088     unsigned int isjmp:1;
1089     unsigned int unused2:4;
1090 */
1091                         }
1092                 }
1093         }
1094 }
1095
1096
1097 // What this really does is expand the # of handlers, which is why the
1098 // opcode has to be passed into the opcode handler...
1099 // E.g., $F620 maps into $F621-F627 as well; this code does this expansion.
1100 void do_merges(void)
1101 {
1102         long int opcode;
1103         int nr = 0;
1104         mismatch = 0;
1105
1106         for(opcode=0; opcode<65536; opcode++)
1107         {
1108                 if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
1109                         continue;
1110
1111                 nr++;
1112                 handle_merges(opcode);
1113         }
1114
1115         nr_cpuop_funcs = nr;
1116 }
1117
1118
1119 int get_no_mismatches(void)
1120 {
1121         return mismatch;
1122 }
1123