OpenCores
URL https://opencores.org/ocsvn/ao68000/ao68000/trunk

Subversion Repositories ao68000

[/] [ao68000/] [trunk/] [tests/] [compare_with_winuae/] [winuae/] [readcpu.c] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.