ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/readcpu.cpp
Revision: 1.4
Committed: 2001-08-19T16:21:01Z (22 years, 10 months ago) by gbeauche
Branch: MAIN
CVS Tags: snapshot-15012002
Changes since 1.3: +12 -3 lines
Log Message:
- merge 680x0 emulation core with uae 0.8.17

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