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 "sysconfig.h"
10 #include <stdlib.h>
11 #include "uae_string.h"
12 #include "uae_types.h"
13
14 #define NO_MACHDEP 1
15 #include "sysdeps.h"
16
17 #include "writelog.h"
18 #include <ctype.h>
19
20 #include "readcpu.h"
21
22 #ifndef _T
23 # define _T
24 #endif // _T
25 /*
26 * You can specify numbers from 0 to 5 here. It is possible that higher
27 * numbers will make the CPU emulation slightly faster, but if the setting
28 * is too high, you will run out of memory while compiling.
29 * Best to leave this as it is.
30 */
31 #ifndef CPU_EMU_SIZE
32 # define CPU_EMU_SIZE 0
33 #endif
34
35 int nr_cpuop_funcs;
36
37 struct mnemolookup lookuptab[] = {
38 { i_ILLG, _T("ILLEGAL"), NULL },
39 { i_OR, _T("OR"), NULL },
40 { i_CHK, _T("CHK"), NULL },
41 { i_CHK2, _T("CHK2"), NULL },
42 { i_AND, _T("AND"), NULL },
43 { i_EOR, _T("EOR"), NULL },
44 { i_ORSR, _T("ORSR"), NULL },
45 { i_ANDSR, _T("ANDSR"), NULL },
46 { i_EORSR, _T("EORSR"), NULL },
47 { i_SUB, _T("SUB"), NULL },
48 { i_SUBA, _T("SUBA"), NULL },
49 { i_SUBX, _T("SUBX"), NULL },
50 { i_SBCD, _T("SBCD"), NULL },
51 { i_ADD, _T("ADD"), NULL },
52 { i_ADDA, _T("ADDA"), NULL },
53 { i_ADDX, _T("ADDX"), NULL },
54 { i_ABCD, _T("ABCD"), NULL },
55 { i_NEG, _T("NEG"), NULL },
56 { i_NEGX, _T("NEGX"), NULL },
57 { i_NBCD, _T("NBCD"), NULL },
58 { i_CLR, _T("CLR"), NULL },
59 { i_NOT, _T("NOT"), NULL },
60 { i_TST, _T("TST"), NULL },
61 { i_BTST, _T("BTST"), NULL },
62 { i_BCHG, _T("BCHG"), NULL },
63 { i_BCLR, _T("BCLR"), NULL },
64 { i_BSET, _T("BSET"), NULL },
65 { i_CMP, _T("CMP"), NULL },
66 { i_CMPM, _T("CMPM"), NULL },
67 { i_CMPA, _T("CMPA"), NULL },
68 { i_MVPRM, _T("MVPRM"), NULL },
69 { i_MVPMR, _T("MVPMR"), NULL },
70 { i_MOVE, _T("MOVE"), NULL },
71 { i_MOVEA, _T("MOVEA"), NULL },
72 { i_MVSR2, _T("MVSR2"), NULL },
73 { i_MV2SR, _T("MV2SR"), NULL },
74 { i_SWAP, _T("SWAP"), NULL },
75 { i_EXG, _T("EXG"), NULL },
76 { i_EXT, _T("EXT"), NULL },
77 { i_MVMEL, _T("MVMEL"), _T("MOVEM") },
78 { i_MVMLE, _T("MVMLE"), _T("MOVEM") },
79 { i_TRAP, _T("TRAP"), NULL },
80 { i_MVR2USP, _T("MVR2USP"), NULL },
81 { i_MVUSP2R, _T("MVUSP2R"), NULL },
82 { i_NOP, _T("NOP"), NULL },
83 { i_RESET, _T("RESET"), NULL },
84 { i_RTE, _T("RTE"), NULL },
85 { i_RTD, _T("RTD"), NULL },
86 { i_LINK, _T("LINK"), NULL },
87 { i_UNLK, _T("UNLK"), NULL },
88 { i_RTS, _T("RTS"), NULL },
89 { i_STOP, _T("STOP"), NULL },
90 { i_TRAPV, _T("TRAPV"), NULL },
91 { i_RTR, _T("RTR"), NULL },
92 { i_JSR, _T("JSR"), NULL },
93 { i_JMP, _T("JMP"), NULL },
94 { i_BSR, _T("BSR"), NULL },
95 { i_Bcc, _T("Bcc"), NULL },
96 { i_LEA, _T("LEA"), NULL },
97 { i_PEA, _T("PEA"), NULL },
98 { i_DBcc, _T("DBcc"), NULL },
99 { i_Scc, _T("Scc"), NULL },
100 { i_DIVU, _T("DIVU"), NULL },
101 { i_DIVS, _T("DIVS"), NULL },
102 { i_MULU, _T("MULU"), NULL },
103 { i_MULS, _T("MULS"), NULL },
104 { i_ASR, _T("ASR"), NULL },
105 { i_ASL, _T("ASL"), NULL },
106 { i_LSR, _T("LSR"), NULL },
107 { i_LSL, _T("LSL"), NULL },
108 { i_ROL, _T("ROL"), NULL },
109 { i_ROR, _T("ROR"), NULL },
110 { i_ROXL, _T("ROXL"), NULL },
111 { i_ROXR, _T("ROXR"), NULL },
112 { i_ASRW, _T("ASRW"), NULL },
113 { i_ASLW, _T("ASLW"), NULL },
114 { i_LSRW, _T("LSRW"), NULL },
115 { i_LSLW, _T("LSLW"), NULL },
116 { i_ROLW, _T("ROLW"), NULL },
117 { i_RORW, _T("RORW"), NULL },
118 { i_ROXLW, _T("ROXLW"), NULL },
119 { i_ROXRW, _T("ROXRW"), NULL },
120
121 { i_MOVE2C, _T("MOVE2C"), _T("MOVEC") },
122 { i_MOVEC2, _T("MOVEC2"), _T("MOVEC") },
123 { i_CAS, _T("CAS"), NULL },
124 { i_CAS2, _T("CAS2"), NULL },
125 { i_MULL, _T("MULL"), NULL },
126 { i_DIVL, _T("DIVL"), NULL },
127 { i_BFTST, _T("BFTST"), NULL },
128 { i_BFEXTU, _T("BFEXTU"), NULL },
129 { i_BFCHG, _T("BFCHG"), NULL },
130 { i_BFEXTS, _T("BFEXTS"), NULL },
131 { i_BFCLR, _T("BFCLR"), NULL },
132 { i_BFFFO, _T("BFFFO"), NULL },
133 { i_BFSET, _T("BFSET"), NULL },
134 { i_BFINS, _T("BFINS"), NULL },
135 { i_PACK, _T("PACK"), NULL },
136 { i_UNPK, _T("UNPK"), NULL },
137 { i_TAS, _T("TAS"), NULL },
138 { i_BKPT, _T("BKPT"), NULL },
139 { i_CALLM, _T("CALLM"), NULL },
140 { i_RTM, _T("RTM"), NULL },
141 { i_TRAPcc, _T("TRAPcc"), NULL },
142 { i_MOVES, _T("MOVES"), NULL },
143 { i_FPP, _T("FPP"), NULL },
144 { i_FDBcc, _T("FDBcc"), NULL },
145 { i_FScc, _T("FScc"), NULL },
146 { i_FTRAPcc, _T("FTRAPcc"), NULL },
147 { i_FBcc, _T("FBcc"), NULL },
148 { i_FBcc, _T("FBcc"), NULL },
149 { i_FSAVE, _T("FSAVE"), NULL },
150 { i_FRESTORE, _T("FRESTORE"), NULL },
151
152 { i_CINVL, _T("CINVL"), NULL },
153 { i_CINVP, _T("CINVP"), NULL },
154 { i_CINVA, _T("CINVA"), NULL },
155 { i_CPUSHL, _T("CPUSHL"), NULL },
156 { i_CPUSHP, _T("CPUSHP"), NULL },
157 { i_CPUSHA, _T("CPUSHA"), NULL },
158 { i_MOVE16, _T("MOVE16"), NULL },
159
160 { i_MMUOP030, _T("MMUOP030"), NULL },
161 { i_PFLUSHN, _T("PFLUSHN"), NULL },
162 { i_PFLUSH, _T("PFLUSH"), NULL },
163 { i_PFLUSHAN, _T("PFLUSHAN"), NULL },
164 { i_PFLUSHA, _T("PFLUSHA"), NULL },
165
166 { i_PLPAR, _T("PLPAR"), NULL },
167 { i_PLPAW, _T("PLPAW"), NULL },
168 { i_PTESTR, _T("PTESTR"), NULL },
169 { i_PTESTW, _T("PTESTW"), NULL },
170
171 { i_LPSTOP, _T("LPSTOP"), NULL },
172 { i_ILLG, _T(""), NULL },
173 };
174
175 struct instr *table68k;
176
mode_from_str(const char * str)177 static amodes mode_from_str (const char *str)
178 {
179 if (strncmp (str, _T("Dreg"), 4) == 0) return Dreg;
180 if (strncmp (str, _T("Areg"), 4) == 0) return Areg;
181 if (strncmp (str, _T("Aind"), 4) == 0) return Aind;
182 if (strncmp (str, _T("Apdi"), 4) == 0) return Apdi;
183 if (strncmp (str, _T("Aipi"), 4) == 0) return Aipi;
184 if (strncmp (str, _T("Ad16"), 4) == 0) return Ad16;
185 if (strncmp (str, _T("Ad8r"), 4) == 0) return Ad8r;
186 if (strncmp (str, _T("absw"), 4) == 0) return absw;
187 if (strncmp (str, _T("absl"), 4) == 0) return absl;
188 if (strncmp (str, _T("PC16"), 4) == 0) return PC16;
189 if (strncmp (str, _T("PC8r"), 4) == 0) return PC8r;
190 if (strncmp (str, _T("Immd"), 4) == 0) return imm;
191 abort ();
192 return 0;
193 }
194
mode_from_mr(int mode,int reg)195 STATIC_INLINE amodes mode_from_mr (int mode, int reg)
196 {
197 switch (mode) {
198 case 0: return Dreg;
199 case 1: return Areg;
200 case 2: return Aind;
201 case 3: return Aipi;
202 case 4: return Apdi;
203 case 5: return Ad16;
204 case 6: return Ad8r;
205 case 7:
206 switch (reg) {
207 case 0: return absw;
208 case 1: return absl;
209 case 2: return PC16;
210 case 3: return PC8r;
211 case 4: return imm;
212 case 5:
213 case 6:
214 case 7: return am_illg;
215 }
216 }
217 abort ();
218 return 0;
219 }
220
build_insn(int insn)221 static void build_insn (int insn)
222 {
223 int find = -1;
224 int variants;
225 int isjmp = 0;
226 struct instr_def id;
227 const char *opcstr;
228 int i;
229
230 int flaglive = 0, flagdead = 0;
231
232 id = defs68k[insn];
233
234 /* Note: We treat anything with unknown flags as a jump. That
235 is overkill, but "the programmer" was lazy quite often, and
236 *this* programmer can't be bothered to work out what can and
237 can't trap. Usually, this will be overwritten with the gencomp
238 based information, anyway. */
239
240 for (i = 0; i < 5; i++) {
241 switch (id.flaginfo[i].flagset){
242 case fa_unset: break;
243 case fa_isjmp: isjmp = 1; break;
244 case fa_isbranch: isjmp = 1; break;
245 case fa_zero: flagdead |= 1 << i; break;
246 case fa_one: flagdead |= 1 << i; break;
247 case fa_dontcare: flagdead |= 1 << i; break;
248 case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
249 case fa_set: flagdead |= 1 << i; break;
250 }
251 }
252
253 out1:
254 for (i = 0; i < 5; i++) {
255 switch (id.flaginfo[i].flaguse) {
256 case fu_unused: break;
257 case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break;
258 case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break;
259 case fu_unknown: isjmp = 1; flaglive |= 1 << i; break;
260 case fu_used: flaglive |= 1 << i; break;
261 }
262 }
263
264 opcstr = id.opcstr;
265 for (variants = 0; variants < (1 << id.n_variable); variants++) {
266 int bitcnt[lastbit];
267 int bitval[lastbit];
268 int bitpos[lastbit];
269 int i;
270 uae_u16 opc = id.bits;
271 uae_u16 msk, vmsk;
272 int pos = 0;
273 int mnp = 0;
274 int bitno = 0;
275 char mnemonic[10];
276
277 wordsizes sz = sz_long;
278 int srcgather = 0, dstgather = 0;
279 int usesrc = 0, usedst = 0;
280 int srctype = 0;
281 int srcpos = -1, dstpos = -1;
282
283 amodes srcmode = am_unknown, destmode = am_unknown;
284 int srcreg = -1, destreg = -1;
285
286 for (i = 0; i < lastbit; i++)
287 bitcnt[i] = bitval[i] = 0;
288
289 vmsk = 1 << id.n_variable;
290
291 for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) {
292 if (!(msk & id.mask)) {
293 int currbit = id.bitpos[bitno++];
294 int bit_set;
295 vmsk >>= 1;
296 bit_set = variants & vmsk ? 1 : 0;
297 if (bit_set)
298 opc |= msk;
299 bitpos[currbit] = 15 - i;
300 bitcnt[currbit]++;
301 bitval[currbit] <<= 1;
302 bitval[currbit] |= bit_set;
303 }
304 }
305
306 if (bitval[bitj] == 0) bitval[bitj] = 8;
307 /* first check whether this one does not match after all */
308 if (bitval[bitz] == 3 || bitval[bitC] == 1)
309 continue;
310 if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
311 continue;
312
313 /* bitI and bitC get copied to biti and bitc */
314 if (bitcnt[bitI]) {
315 bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
316 }
317 if (bitcnt[bitC])
318 bitval[bitc] = bitval[bitC];
319
320 pos = 0;
321 while (opcstr[pos] && !isspace(opcstr[pos])) {
322 if (opcstr[pos] == '.') {
323 pos++;
324 switch (opcstr[pos]) {
325
326 case 'B': sz = sz_byte; break;
327 case 'W': sz = sz_word; break;
328 case 'L': sz = sz_long; break;
329 case 'z':
330 switch (bitval[bitz]) {
331 case 0: sz = sz_byte; break;
332 case 1: sz = sz_word; break;
333 case 2: sz = sz_long; break;
334 default: abort();
335 }
336 break;
337 default: abort();
338 }
339 } else {
340 mnemonic[mnp] = opcstr[pos];
341 if (mnemonic[mnp] == 'f') {
342 find = -1;
343 switch (bitval[bitf]) {
344 case 0: mnemonic[mnp] = 'R'; break;
345 case 1: mnemonic[mnp] = 'L'; break;
346 default: abort();
347 }
348 }
349 mnp++;
350 }
351 pos++;
352 }
353 mnemonic[mnp] = 0;
354
355 /* now, we have read the mnemonic and the size */
356 while (opcstr[pos] && isspace(opcstr[pos]))
357 pos++;
358
359 /* A goto a day keeps the D******a away. */
360 if (opcstr[pos] == 0)
361 goto endofline;
362
363 /* parse the source address */
364 usesrc = 1;
365 switch (opcstr[pos++]) {
366 case 'D':
367 srcmode = Dreg;
368 switch (opcstr[pos++]) {
369 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
370 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
371 default: abort();
372 }
373 break;
374 case 'A':
375 srcmode = Areg;
376 switch (opcstr[pos++]) {
377 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
378 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
379 default: abort();
380 }
381 switch (opcstr[pos]) {
382 case 'p': srcmode = Apdi; pos++; break;
383 case 'P': srcmode = Aipi; pos++; break;
384 case 'a': srcmode = Aind; pos++; break;
385 }
386 break;
387 case 'L':
388 srcmode = absl;
389 break;
390 case '#':
391 switch (opcstr[pos++]) {
392 case 'z': srcmode = imm; break;
393 case '0': srcmode = imm0; break;
394 case '1': srcmode = imm1; break;
395 case '2': srcmode = imm2; break;
396 case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti];
397 if (CPU_EMU_SIZE < 4) {
398 /* Used for branch instructions */
399 srctype = 1;
400 srcgather = 1;
401 srcpos = bitpos[biti];
402 }
403 break;
404 case 'j': srcmode = immi; srcreg = bitval[bitj];
405 if (CPU_EMU_SIZE < 3) {
406 /* 1..8 for ADDQ/SUBQ and rotshi insns */
407 srcgather = 1;
408 srctype = 3;
409 srcpos = bitpos[bitj];
410 }
411 break;
412 case 'J': srcmode = immi; srcreg = bitval[bitJ];
413 if (CPU_EMU_SIZE < 5) {
414 /* 0..15 */
415 srcgather = 1;
416 srctype = 2;
417 srcpos = bitpos[bitJ];
418 }
419 break;
420 case 'k': srcmode = immi; srcreg = bitval[bitk];
421 if (CPU_EMU_SIZE < 3) {
422 srcgather = 1;
423 srctype = 4;
424 srcpos = bitpos[bitk];
425 }
426 break;
427 case 'K': srcmode = immi; srcreg = bitval[bitK];
428 if (CPU_EMU_SIZE < 5) {
429 /* 0..15 */
430 srcgather = 1;
431 srctype = 5;
432 srcpos = bitpos[bitK];
433 }
434 break;
435 case 'p': srcmode = immi; srcreg = bitval[bitK];
436 if (CPU_EMU_SIZE < 5) {
437 /* 0..3 */
438 srcgather = 1;
439 srctype = 7;
440 srcpos = bitpos[bitp];
441 }
442 break;
443 default: abort();
444 }
445 break;
446 case 'd':
447 srcreg = bitval[bitD];
448 srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
449 if (srcmode == am_illg)
450 continue;
451 if (CPU_EMU_SIZE < 2 &&
452 (srcmode == Areg || srcmode == Dreg || srcmode == Aind
453 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
454 || srcmode == Apdi))
455 {
456 srcgather = 1; srcpos = bitpos[bitD];
457 }
458 if (opcstr[pos] == '[') {
459 pos++;
460 if (opcstr[pos] == '!') {
461 /* exclusion */
462 do {
463 pos++;
464 if (mode_from_str(opcstr+pos) == srcmode)
465 goto nomatch;
466 pos += 4;
467 } while (opcstr[pos] == ',');
468 pos++;
469 } else {
470 if (opcstr[pos+4] == '-') {
471 /* replacement */
472 if (mode_from_str(opcstr+pos) == srcmode)
473 srcmode = mode_from_str(opcstr+pos+5);
474 else
475 goto nomatch;
476 pos += 10;
477 } else {
478 /* normal */
479 while(mode_from_str(opcstr+pos) != srcmode) {
480 pos += 4;
481 if (opcstr[pos] == ']')
482 goto nomatch;
483 pos++;
484 }
485 while(opcstr[pos] != ']') pos++;
486 pos++;
487 break;
488 }
489 }
490 }
491 /* Some addressing modes are invalid as destination */
492 if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
493 goto nomatch;
494 break;
495 case 's':
496 srcreg = bitval[bitS];
497 srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
498
499 if (srcmode == am_illg)
500 continue;
501 if (CPU_EMU_SIZE < 2 &&
502 (srcmode == Areg || srcmode == Dreg || srcmode == Aind
503 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
504 || srcmode == Apdi))
505 {
506 srcgather = 1; srcpos = bitpos[bitS];
507 }
508 if (opcstr[pos] == '[') {
509 pos++;
510 if (opcstr[pos] == '!') {
511 /* exclusion */
512 do {
513 pos++;
514 if (mode_from_str(opcstr+pos) == srcmode)
515 goto nomatch;
516 pos += 4;
517 } while (opcstr[pos] == ',');
518 pos++;
519 } else {
520 if (opcstr[pos+4] == '-') {
521 /* replacement */
522 if (mode_from_str(opcstr+pos) == srcmode)
523 srcmode = mode_from_str(opcstr+pos+5);
524 else
525 goto nomatch;
526 pos += 10;
527 } else {
528 /* normal */
529 while(mode_from_str(opcstr+pos) != srcmode) {
530 pos += 4;
531 if (opcstr[pos] == ']')
532 goto nomatch;
533 pos++;
534 }
535 while(opcstr[pos] != ']') pos++;
536 pos++;
537 }
538 }
539 }
540 break;
541 default: abort();
542 }
543 /* safety check - might have changed */
544 if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
545 && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
546 && srcmode != Apdi && srcmode != immi)
547 {
548 srcgather = 0;
549 }
550 if (srcmode == Areg && sz == sz_byte)
551 goto nomatch;
552
553 if (opcstr[pos] != ',')
554 goto endofline;
555 pos++;
556
557 /* parse the destination address */
558 usedst = 1;
559 switch (opcstr[pos++]) {
560 case 'D':
561 destmode = Dreg;
562 switch (opcstr[pos++]) {
563 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
564 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
565 default: abort();
566 }
567 if (dstpos < 0 || dstpos >= 32)
568 abort ();
569 break;
570 case 'A':
571 destmode = Areg;
572 switch (opcstr[pos++]) {
573 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
574 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
575 case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
576 default: abort();
577 }
578 if (dstpos < 0 || dstpos >= 32)
579 abort ();
580 switch (opcstr[pos]) {
581 case 'p': destmode = Apdi; pos++; break;
582 case 'P': destmode = Aipi; pos++; break;
583 }
584 break;
585 case 'L':
586 destmode = absl;
587 break;
588 case '#':
589 switch (opcstr[pos++]) {
590 case 'z': destmode = imm; break;
591 case '0': destmode = imm0; break;
592 case '1': destmode = imm1; break;
593 case '2': destmode = imm2; break;
594 case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break;
595 case 'j': destmode = immi; destreg = bitval[bitj]; break;
596 case 'J': destmode = immi; destreg = bitval[bitJ]; break;
597 case 'k': destmode = immi; destreg = bitval[bitk]; break;
598 case 'K': destmode = immi; destreg = bitval[bitK]; break;
599 default: abort();
600 }
601 break;
602 case 'd':
603 destreg = bitval[bitD];
604 destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
605 if (destmode == am_illg)
606 continue;
607 if (CPU_EMU_SIZE < 1 &&
608 (destmode == Areg || destmode == Dreg || destmode == Aind
609 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
610 || destmode == Apdi))
611 {
612 dstgather = 1; dstpos = bitpos[bitD];
613 }
614
615 if (opcstr[pos] == '[') {
616 pos++;
617 if (opcstr[pos] == '!') {
618 /* exclusion */
619 do {
620 pos++;
621 if (mode_from_str(opcstr+pos) == destmode)
622 goto nomatch;
623 pos += 4;
624 } while (opcstr[pos] == ',');
625 pos++;
626 } else {
627 if (opcstr[pos+4] == '-') {
628 /* replacement */
629 if (mode_from_str(opcstr+pos) == destmode)
630 destmode = mode_from_str(opcstr+pos+5);
631 else
632 goto nomatch;
633 pos += 10;
634 } else {
635 /* normal */
636 while(mode_from_str(opcstr+pos) != destmode) {
637 pos += 4;
638 if (opcstr[pos] == ']')
639 goto nomatch;
640 pos++;
641 }
642 while(opcstr[pos] != ']') pos++;
643 pos++;
644 break;
645 }
646 }
647 }
648 /* Some addressing modes are invalid as destination */
649 if (destmode == imm || destmode == PC16 || destmode == PC8r)
650 goto nomatch;
651 break;
652 case 's':
653 destreg = bitval[bitS];
654 destmode = mode_from_mr(bitval[bits],bitval[bitS]);
655
656 if (destmode == am_illg)
657 continue;
658 if (CPU_EMU_SIZE < 1 &&
659 (destmode == Areg || destmode == Dreg || destmode == Aind
660 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
661 || destmode == Apdi))
662 {
663 dstgather = 1; dstpos = bitpos[bitS];
664 }
665
666 if (opcstr[pos] == '[') {
667 pos++;
668 if (opcstr[pos] == '!') {
669 /* exclusion */
670 do {
671 pos++;
672 if (mode_from_str(opcstr+pos) == destmode)
673 goto nomatch;
674 pos += 4;
675 } while (opcstr[pos] == ',');
676 pos++;
677 } else {
678 if (opcstr[pos+4] == '-') {
679 /* replacement */
680 if (mode_from_str(opcstr+pos) == destmode)
681 destmode = mode_from_str(opcstr+pos+5);
682 else
683 goto nomatch;
684 pos += 10;
685 } else {
686 /* normal */
687 while(mode_from_str(opcstr+pos) != destmode) {
688 pos += 4;
689 if (opcstr[pos] == ']')
690 goto nomatch;
691 pos++;
692 }
693 while(opcstr[pos] != ']') pos++;
694 pos++;
695 }
696 }
697 }
698 break;
699 default: abort();
700 }
701 /* safety check - might have changed */
702 if (destmode != Areg && destmode != Dreg && destmode != Aind
703 && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
704 && destmode != Apdi)
705 {
706 dstgather = 0;
707 }
708
709 if (destmode == Areg && sz == sz_byte)
710 goto nomatch;
711 #if 0
712 if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
713 dstgather = 0;
714 }
715 #endif
716 endofline:
717 /* now, we have a match */
718 /* if (table68k[opc].mnemo != i_ILLG)
719 write_log (_T("Double match: %x: %s\n"), opc, opcstr); */
720 if (find == -1) {
721 for (find = 0;; find++) {
722 if (strcmp (mnemonic, lookuptab[find].name) == 0) {
723 table68k[opc].mnemo = lookuptab[find].mnemo;
724 break;
725 }
726 if (strlen (lookuptab[find].name) == 0)
727 abort();
728 }
729 }
730 else {
731 table68k[opc].mnemo = lookuptab[find].mnemo;
732 }
733 table68k[opc].cc = bitval[bitc];
734 if (table68k[opc].mnemo == i_BTST
735 || table68k[opc].mnemo == i_BSET
736 || table68k[opc].mnemo == i_BCLR
737 || table68k[opc].mnemo == i_BCHG)
738 {
739 sz = destmode == Dreg ? sz_long : sz_byte;
740 }
741 table68k[opc].size = sz;
742 table68k[opc].sreg = srcreg;
743 table68k[opc].dreg = destreg;
744 table68k[opc].smode = srcmode;
745 table68k[opc].dmode = destmode;
746 table68k[opc].spos = srcgather ? srcpos : -1;
747 table68k[opc].dpos = dstgather ? dstpos : -1;
748 table68k[opc].suse = usesrc;
749 table68k[opc].duse = usedst;
750 table68k[opc].stype = srctype;
751 table68k[opc].plev = id.plevel;
752 table68k[opc].clev = id.cpulevel;
753 table68k[opc].unimpclev = id.unimpcpulevel;
754
755 #if 0
756 for (i = 0; i < 5; i++) {
757 table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
758 table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
759 }
760 #endif
761 table68k[opc].flagdead = flagdead;
762 table68k[opc].flaglive = flaglive;
763 table68k[opc].isjmp = isjmp;
764 nomatch:
765 /* FOO! */;
766 }
767 }
768
769
read_table68k(void)770 void read_table68k (void)
771 {
772 int i;
773
774 xfree (table68k);
775 table68k = xmalloc (struct instr, 65536);
776 for (i = 0; i < 65536; i++) {
777 table68k[i].mnemo = i_ILLG;
778 table68k[i].handler = -1;
779 }
780 for (i = 0; i < n_defs68k; i++) {
781 build_insn (i);
782 }
783 }
784
785 static int imismatch;
786
handle_merges(long int opcode)787 static void handle_merges (long int opcode)
788 {
789 uae_u16 smsk;
790 uae_u16 dmsk;
791 int sbitdst, dstend;
792 int srcreg, dstreg;
793
794 if (table68k[opcode].spos == -1) {
795 sbitdst = 1; smsk = 0;
796 } else {
797 switch (table68k[opcode].stype) {
798 case 0:
799 smsk = 7; sbitdst = 8; break;
800 case 1:
801 smsk = 255; sbitdst = 256; break;
802 case 2:
803 smsk = 15; sbitdst = 16; break;
804 case 3:
805 smsk = 7; sbitdst = 8; break;
806 case 4:
807 smsk = 7; sbitdst = 8; break;
808 case 5:
809 smsk = 63; sbitdst = 64; break;
810 case 7:
811 smsk = 3; sbitdst = 4; break;
812 default:
813 smsk = 0; sbitdst = 0;
814 abort();
815 break;
816 }
817 smsk <<= table68k[opcode].spos;
818 }
819 if (table68k[opcode].dpos == -1) {
820 dstend = 1; dmsk = 0;
821 } else {
822 dmsk = 7 << table68k[opcode].dpos;
823 dstend = 8;
824 }
825 for (srcreg=0; srcreg < sbitdst; srcreg++) {
826 for (dstreg=0; dstreg < dstend; dstreg++) {
827 uae_u16 code = (uae_u16)opcode;
828
829 code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
830 code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
831
832 /* Check whether this is in fact the same instruction.
833 * The instructions should never differ, except for the
834 * Bcc.(BW) case. */
835 if (table68k[code].mnemo != table68k[opcode].mnemo
836 || table68k[code].size != table68k[opcode].size
837 || table68k[code].suse != table68k[opcode].suse
838 || table68k[code].duse != table68k[opcode].duse)
839 {
840 imismatch++; continue;
841 }
842 if (table68k[opcode].suse
843 && (table68k[opcode].spos != table68k[code].spos
844 || table68k[opcode].smode != table68k[code].smode
845 || table68k[opcode].stype != table68k[code].stype))
846 {
847 imismatch++; continue;
848 }
849 if (table68k[opcode].duse
850 && (table68k[opcode].dpos != table68k[code].dpos
851 || table68k[opcode].dmode != table68k[code].dmode))
852 {
853 imismatch++; continue;
854 }
855
856 if (code != opcode)
857 table68k[code].handler = opcode;
858 }
859 }
860 }
861
do_merges(void)862 void do_merges (void)
863 {
864 long int opcode;
865 int nr = 0;
866 imismatch = 0;
867 for (opcode = 0; opcode < 65536; opcode++) {
868 if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
869 continue;
870 nr++;
871 handle_merges (opcode);
872 }
873 nr_cpuop_funcs = nr;
874 }
875
get_no_mismatches(void)876 int get_no_mismatches (void)
877 {
878 return imismatch;
879 }
880