ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/readcpu.cpp
Revision: 1.11
Committed: 2012-03-30T01:25:46Z (12 years, 8 months ago) by asvitkine
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +14 -0 lines
Log Message:
Add GPLv2 notices to files from UAE Amiga Emulator, as retrieved from the
COPYING file of uae-0.8.29, retrieved from http://www.amigaemulator.org/
via uae-0.8.29.tar.bz2 (MD5 = 54abbabb5e8580b679c52de019141d61).

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