ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/readcpu.cpp
Revision: 1.3
Committed: 2001-03-19T13:11:40Z (23 years, 3 months ago) by gbeauche
Branch: MAIN
CVS Tags: snapshot-29052001, release-0_9-1
Changes since 1.2: +12 -0 lines
Log Message:
Additions:
- MOVE16 (Ay)+,(xxx).L
- MOVE16 (xxx).L,(Ay)+
- MOVE16 (Ay),(xxx).L
- MOVE16 (xxx).L,(Ay)

Fixes:
- MOVE16 (Ax)+,(Ay)+ where x == y: address register shall be incremented
  only once
- CINV, CPUSH: 'p' field matches correctly the instruction 'cache field'

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 'l': srcmode = absl; break;
343 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
344 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
345 default: abort();
346 }
347 switch (opcstr[pos]) {
348 case 'p': srcmode = Apdi; pos++; break;
349 case 'P': srcmode = Aipi; pos++; break;
350 }
351 break;
352 case '#':
353 switch (opcstr[pos++]) {
354 case 'z': srcmode = imm; break;
355 case '0': srcmode = imm0; break;
356 case '1': srcmode = imm1; break;
357 case '2': srcmode = imm2; break;
358 case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti];
359 if (CPU_EMU_SIZE < 4) {
360 /* Used for branch instructions */
361 srctype = 1;
362 srcgather = 1;
363 srcpos = bitpos[biti];
364 }
365 break;
366 case 'j': srcmode = immi; srcreg = bitval[bitj];
367 if (CPU_EMU_SIZE < 3) {
368 /* 1..8 for ADDQ/SUBQ and rotshi insns */
369 srcgather = 1;
370 srctype = 3;
371 srcpos = bitpos[bitj];
372 }
373 break;
374 case 'J': srcmode = immi; srcreg = bitval[bitJ];
375 if (CPU_EMU_SIZE < 5) {
376 /* 0..15 */
377 srcgather = 1;
378 srctype = 2;
379 srcpos = bitpos[bitJ];
380 }
381 break;
382 case 'k': srcmode = immi; srcreg = bitval[bitk];
383 if (CPU_EMU_SIZE < 3) {
384 srcgather = 1;
385 srctype = 4;
386 srcpos = bitpos[bitk];
387 }
388 break;
389 case 'K': srcmode = immi; srcreg = bitval[bitK];
390 if (CPU_EMU_SIZE < 5) {
391 /* 0..15 */
392 srcgather = 1;
393 srctype = 5;
394 srcpos = bitpos[bitK];
395 }
396 break;
397 case 'p': srcmode = immi; srcreg = bitval[bitp];
398 if (CPU_EMU_SIZE < 5) { // gb-- what is CPU_EMU_SIZE used for ??
399 /* 0..3 */
400 srcgather = 1;
401 srctype = 7;
402 srcpos = bitpos[bitp];
403 }
404 break;
405 default: abort();
406 }
407 break;
408 case 'd':
409 srcreg = bitval[bitD];
410 srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
411 if (srcmode == am_illg)
412 continue;
413 if (CPU_EMU_SIZE < 2 &&
414 (srcmode == Areg || srcmode == Dreg || srcmode == Aind
415 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
416 || srcmode == Apdi))
417 {
418 srcgather = 1; srcpos = bitpos[bitD];
419 }
420 if (opcstr[pos] == '[') {
421 pos++;
422 if (opcstr[pos] == '!') {
423 /* exclusion */
424 do {
425 pos++;
426 if (mode_from_str(opcstr+pos) == srcmode)
427 goto nomatch;
428 pos += 4;
429 } while (opcstr[pos] == ',');
430 pos++;
431 } else {
432 if (opcstr[pos+4] == '-') {
433 /* replacement */
434 if (mode_from_str(opcstr+pos) == srcmode)
435 srcmode = mode_from_str(opcstr+pos+5);
436 else
437 goto nomatch;
438 pos += 10;
439 } else {
440 /* normal */
441 while(mode_from_str(opcstr+pos) != srcmode) {
442 pos += 4;
443 if (opcstr[pos] == ']')
444 goto nomatch;
445 pos++;
446 }
447 while(opcstr[pos] != ']') pos++;
448 pos++;
449 break;
450 }
451 }
452 }
453 /* Some addressing modes are invalid as destination */
454 if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
455 goto nomatch;
456 break;
457 case 's':
458 srcreg = bitval[bitS];
459 srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
460
461 if (srcmode == am_illg)
462 continue;
463 if (CPU_EMU_SIZE < 2 &&
464 (srcmode == Areg || srcmode == Dreg || srcmode == Aind
465 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
466 || srcmode == Apdi))
467 {
468 srcgather = 1; srcpos = bitpos[bitS];
469 }
470 if (opcstr[pos] == '[') {
471 pos++;
472 if (opcstr[pos] == '!') {
473 /* exclusion */
474 do {
475 pos++;
476 if (mode_from_str(opcstr+pos) == srcmode)
477 goto nomatch;
478 pos += 4;
479 } while (opcstr[pos] == ',');
480 pos++;
481 } else {
482 if (opcstr[pos+4] == '-') {
483 /* replacement */
484 if (mode_from_str(opcstr+pos) == srcmode)
485 srcmode = mode_from_str(opcstr+pos+5);
486 else
487 goto nomatch;
488 pos += 10;
489 } else {
490 /* normal */
491 while(mode_from_str(opcstr+pos) != srcmode) {
492 pos += 4;
493 if (opcstr[pos] == ']')
494 goto nomatch;
495 pos++;
496 }
497 while(opcstr[pos] != ']') pos++;
498 pos++;
499 }
500 }
501 }
502 break;
503 default: abort();
504 }
505 /* safety check - might have changed */
506 if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
507 && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
508 && srcmode != Apdi && srcmode != immi)
509 {
510 srcgather = 0;
511 }
512 if (srcmode == Areg && sz == sz_byte)
513 goto nomatch;
514
515 if (opcstr[pos] != ',')
516 goto endofline;
517 pos++;
518
519 /* parse the destination address */
520 usedst = 1;
521 switch (opcstr[pos++]) {
522 case 'D':
523 destmode = Dreg;
524 switch (opcstr[pos++]) {
525 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
526 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
527 default: abort();
528 }
529 break;
530 case 'A':
531 destmode = Areg;
532 switch (opcstr[pos++]) {
533 case 'l': destmode = absl; break;
534 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
535 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
536 default: abort();
537 }
538 switch (opcstr[pos]) {
539 case 'p': destmode = Apdi; pos++; break;
540 case 'P': destmode = Aipi; pos++; break;
541 }
542 break;
543 case '#':
544 switch (opcstr[pos++]) {
545 case 'z': destmode = imm; break;
546 case '0': destmode = imm0; break;
547 case '1': destmode = imm1; break;
548 case '2': destmode = imm2; break;
549 case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break;
550 case 'j': destmode = immi; destreg = bitval[bitj]; break;
551 case 'J': destmode = immi; destreg = bitval[bitJ]; break;
552 case 'k': destmode = immi; destreg = bitval[bitk]; break;
553 case 'K': destmode = immi; destreg = bitval[bitK]; break;
554 default: abort();
555 }
556 break;
557 case 'd':
558 destreg = bitval[bitD];
559 destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
560 if (destmode == am_illg)
561 continue;
562 if (CPU_EMU_SIZE < 1 &&
563 (destmode == Areg || destmode == Dreg || destmode == Aind
564 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
565 || destmode == Apdi))
566 {
567 dstgather = 1; dstpos = bitpos[bitD];
568 }
569
570 if (opcstr[pos] == '[') {
571 pos++;
572 if (opcstr[pos] == '!') {
573 /* exclusion */
574 do {
575 pos++;
576 if (mode_from_str(opcstr+pos) == destmode)
577 goto nomatch;
578 pos += 4;
579 } while (opcstr[pos] == ',');
580 pos++;
581 } else {
582 if (opcstr[pos+4] == '-') {
583 /* replacement */
584 if (mode_from_str(opcstr+pos) == destmode)
585 destmode = mode_from_str(opcstr+pos+5);
586 else
587 goto nomatch;
588 pos += 10;
589 } else {
590 /* normal */
591 while(mode_from_str(opcstr+pos) != destmode) {
592 pos += 4;
593 if (opcstr[pos] == ']')
594 goto nomatch;
595 pos++;
596 }
597 while(opcstr[pos] != ']') pos++;
598 pos++;
599 break;
600 }
601 }
602 }
603 /* Some addressing modes are invalid as destination */
604 if (destmode == imm || destmode == PC16 || destmode == PC8r)
605 goto nomatch;
606 break;
607 case 's':
608 destreg = bitval[bitS];
609 destmode = mode_from_mr(bitval[bits],bitval[bitS]);
610
611 if (destmode == am_illg)
612 continue;
613 if (CPU_EMU_SIZE < 1 &&
614 (destmode == Areg || destmode == Dreg || destmode == Aind
615 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
616 || destmode == Apdi))
617 {
618 dstgather = 1; dstpos = bitpos[bitS];
619 }
620
621 if (opcstr[pos] == '[') {
622 pos++;
623 if (opcstr[pos] == '!') {
624 /* exclusion */
625 do {
626 pos++;
627 if (mode_from_str(opcstr+pos) == destmode)
628 goto nomatch;
629 pos += 4;
630 } while (opcstr[pos] == ',');
631 pos++;
632 } else {
633 if (opcstr[pos+4] == '-') {
634 /* replacement */
635 if (mode_from_str(opcstr+pos) == destmode)
636 destmode = mode_from_str(opcstr+pos+5);
637 else
638 goto nomatch;
639 pos += 10;
640 } else {
641 /* normal */
642 while(mode_from_str(opcstr+pos) != destmode) {
643 pos += 4;
644 if (opcstr[pos] == ']')
645 goto nomatch;
646 pos++;
647 }
648 while(opcstr[pos] != ']') pos++;
649 pos++;
650 }
651 }
652 }
653 break;
654 default: abort();
655 }
656 /* safety check - might have changed */
657 if (destmode != Areg && destmode != Dreg && destmode != Aind
658 && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
659 && destmode != Apdi)
660 {
661 dstgather = 0;
662 }
663
664 if (destmode == Areg && sz == sz_byte)
665 goto nomatch;
666 #if 0
667 if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
668 dstgather = 0;
669 }
670 #endif
671 endofline:
672 /* now, we have a match */
673 if (table68k[opc].mnemo != i_ILLG)
674 fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
675 if (find == -1) {
676 for (find = 0;; find++) {
677 if (strcmp(mnemonic, lookuptab[find].name) == 0) {
678 table68k[opc].mnemo = lookuptab[find].mnemo;
679 break;
680 }
681 if (strlen(lookuptab[find].name) == 0) abort();
682 }
683 }
684 else {
685 table68k[opc].mnemo = lookuptab[find].mnemo;
686 }
687 table68k[opc].cc = bitval[bitc];
688 if (table68k[opc].mnemo == i_BTST
689 || table68k[opc].mnemo == i_BSET
690 || table68k[opc].mnemo == i_BCLR
691 || table68k[opc].mnemo == i_BCHG)
692 {
693 sz = destmode == Dreg ? sz_long : sz_byte;
694 }
695 table68k[opc].size = sz;
696 table68k[opc].sreg = srcreg;
697 table68k[opc].dreg = destreg;
698 table68k[opc].smode = srcmode;
699 table68k[opc].dmode = destmode;
700 table68k[opc].spos = srcgather ? srcpos : -1;
701 table68k[opc].dpos = dstgather ? dstpos : -1;
702 table68k[opc].suse = usesrc;
703 table68k[opc].duse = usedst;
704 table68k[opc].stype = srctype;
705 table68k[opc].plev = id.plevel;
706 table68k[opc].clev = id.cpulevel;
707 #if 0
708 for (i = 0; i < 5; i++) {
709 table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
710 table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
711 }
712 #endif
713 table68k[opc].flagdead = flagdead;
714 table68k[opc].flaglive = flaglive;
715 nomatch:
716 /* FOO! */;
717 }
718 }
719
720
721 void read_table68k (void)
722 {
723 int i;
724
725 table68k = (struct instr *)malloc (65536 * sizeof (struct instr));
726 for (i = 0; i < 65536; i++) {
727 table68k[i].mnemo = i_ILLG;
728 table68k[i].handler = -1;
729 }
730 for (i = 0; i < n_defs68k; i++) {
731 build_insn (i);
732 }
733 }
734
735 static int mismatch;
736
737 static void handle_merges (long int opcode)
738 {
739 uae_u16 smsk;
740 uae_u16 dmsk;
741 int sbitdst, dstend;
742 int srcreg, dstreg;
743
744 if (table68k[opcode].spos == -1) {
745 sbitdst = 1; smsk = 0;
746 } else {
747 switch (table68k[opcode].stype) {
748 case 0:
749 smsk = 7; sbitdst = 8; break;
750 case 1:
751 smsk = 255; sbitdst = 256; break;
752 case 2:
753 smsk = 15; sbitdst = 16; break;
754 case 3:
755 smsk = 7; sbitdst = 8; break;
756 case 4:
757 smsk = 7; sbitdst = 8; break;
758 case 5:
759 smsk = 63; sbitdst = 64; break;
760 case 7:
761 smsk = 3; sbitdst = 4; break;
762 default:
763 smsk = 0; sbitdst = 0;
764 abort();
765 break;
766 }
767 smsk <<= table68k[opcode].spos;
768 }
769 if (table68k[opcode].dpos == -1) {
770 dstend = 1; dmsk = 0;
771 } else {
772 dmsk = 7 << table68k[opcode].dpos;
773 dstend = 8;
774 }
775 for (srcreg=0; srcreg < sbitdst; srcreg++) {
776 for (dstreg=0; dstreg < dstend; dstreg++) {
777 uae_u16 code = opcode;
778
779 code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
780 code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
781
782 /* Check whether this is in fact the same instruction.
783 * The instructions should never differ, except for the
784 * Bcc.(BW) case. */
785 if (table68k[code].mnemo != table68k[opcode].mnemo
786 || table68k[code].size != table68k[opcode].size
787 || table68k[code].suse != table68k[opcode].suse
788 || table68k[code].duse != table68k[opcode].duse)
789 {
790 mismatch++; continue;
791 }
792 if (table68k[opcode].suse
793 && (table68k[opcode].spos != table68k[code].spos
794 || table68k[opcode].smode != table68k[code].smode
795 || table68k[opcode].stype != table68k[code].stype))
796 {
797 mismatch++; continue;
798 }
799 if (table68k[opcode].duse
800 && (table68k[opcode].dpos != table68k[code].dpos
801 || table68k[opcode].dmode != table68k[code].dmode))
802 {
803 mismatch++; continue;
804 }
805
806 if (code != opcode)
807 table68k[code].handler = opcode;
808 }
809 }
810 }
811
812 void do_merges (void)
813 {
814 long int opcode;
815 int nr = 0;
816 mismatch = 0;
817 for (opcode = 0; opcode < 65536; opcode++) {
818 if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
819 continue;
820 nr++;
821 handle_merges (opcode);
822 }
823 nr_cpuop_funcs = nr;
824 }
825
826 int get_no_mismatches (void)
827 {
828 return mismatch;
829 }