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 (25 years, 1 month ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

# Content
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 }