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

Subversion Repositories ao68000

[/] [ao68000/] [trunk/] [tests/] [compare_with_winuae/] [winuae/] [gencpu.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
* MC68000 emulation generator
5
*
6
* This is a fairly stupid program that generates a lot of case labels that
7
* can be #included in a switch statement.
8
* As an alternative, it can generate functions that handle specific
9
* MC68000 instructions, plus a prototype header file and a function pointer
10
* array to look up the function for an opcode.
11
* Error checking is bad, an illegal table68k file will cause the program to
12
* call abort().
13
* The generated code is sometimes sub-optimal, an optimizing compiler should
14
* take care of this.
15
*
16
* The source for the insn timings is Markt & Technik's Amiga Magazin 8/1992.
17
*
18
* Copyright 1995, 1996, 1997, 1998, 1999, 2000 Bernd Schmidt
19
*/
20
 
21
//AO#include "sysconfig.h"
22
//AO#include "sysdeps.h"
23
#include "ao.h"
24
#include <ctype.h>
25
 
26
#include "readcpu.h"
27
 
28
#define BOOL_TYPE "int"
29
/* Define the minimal 680x0 where NV flags are not affected by xBCD instructions.  */
30
#define xBCD_KEEPS_NV_FLAGS 4
31
 
32
static FILE *headerfile;
33
static FILE *stblfile;
34
 
35
static int using_prefetch, using_indirect, using_mmu;
36
static int using_ce020;
37
static int using_exception_3;
38
static int using_ce;
39
static int cpu_level;
40
static int count_read, count_write, count_cycles, count_ncycles;
41
static int count_read_ea, count_write_ea, count_cycles_ea;
42
 
43
static int optimized_flags;
44
 
45
#define GF_APDI 1
46
#define GF_AD8R 2
47
#define GF_PC8R 4
48
#define GF_AA 7
49
#define GF_NOREFILL 8
50
#define GF_PREFETCH 16
51
#define GF_FC 32
52
 
53
/* For the current opcode, the next lower level that will have different code.
54
* Initialized to -1 for each opcode. If it remains unchanged, indicates we
55
* are done with that opcode.  */
56
static int next_cpu_level;
57
 
58
static int *opcode_map;
59
static int *opcode_next_clev;
60
static int *opcode_last_postfix;
61
static unsigned long *counts;
62
static int generate_stbl;
63
static int fixupcnt;
64
 
65
#define GENA_GETV_NO_FETCH      0
66
#define GENA_GETV_FETCH         1
67
#define GENA_GETV_FETCH_ALIGN   2
68
#define GENA_MOVEM_DO_INC       0
69
#define GENA_MOVEM_NO_INC       1
70
#define GENA_MOVEM_MOVE16       2
71
 
72
static void read_counts (void)
73
{
74
        FILE *file;
75
        unsigned long opcode, count, total;
76
        char name[20];
77
        int nr = 0;
78
        memset (counts, 0, 65536 * sizeof *counts);
79
 
80
        count = 0;
81
        file = fopen ("frequent.68k", "r");
82
        if (file) {
83
                fscanf (file, "Total: %lu\n", &total);
84
                while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) {
85
                        opcode_next_clev[nr] = 5;
86
                        opcode_last_postfix[nr] = -1;
87
                        opcode_map[nr++] = opcode;
88
                        counts[opcode] = count;
89
                }
90
                fclose (file);
91
        }
92
        if (nr == nr_cpuop_funcs)
93
                return;
94
        for (opcode = 0; opcode < 0x10000; opcode++) {
95
                if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
96
                        && counts[opcode] == 0)
97
                {
98
                        opcode_next_clev[nr] = 5;
99
                        opcode_last_postfix[nr] = -1;
100
                        opcode_map[nr++] = opcode;
101
                        counts[opcode] = count;
102
                }
103
        }
104
        if (nr != nr_cpuop_funcs)
105
                abort ();
106
}
107
 
108
static char endlabelstr[80];
109
static int endlabelno = 0;
110
static int need_endlabel;
111
 
112
static int n_braces, limit_braces;
113
static int m68k_pc_offset;
114
static int insn_n_cycles, insn_n_cycles020;
115
 
116
static void fpulimit (void)
117
{
118
        if (limit_braces)
119
                return;
120
        printf ("\n#ifdef FPUEMU\n");
121
        limit_braces = n_braces;
122
        n_braces = 0;
123
}
124
static void cpulimit (void)
125
{
126
        printf ("#ifndef CPUEMU_68000_ONLY\n");
127
}
128
 
129
static void returncycles (char *s, int cycles)
130
{
131
        if (using_ce)
132
                return;
133
        if (using_ce020)
134
                printf ("%sreturn;\n", s);
135
        else
136
                printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles);
137
}
138
 
139
static void addcycles_ce020 (int cycles)
140
{
141
        if (!using_ce020)
142
                return;
143
        if (cycles > 0)
144
                printf ("\tregs.ce020memcycles += %d * cpucycleunit;\n", cycles);
145
        count_cycles += cycles;
146
}
147
static void addcycles000 (int cycles)
148
{
149
        if (!using_ce)
150
                return;
151
        printf ("\tdo_cycles_ce000 (%d);\n", cycles);
152
        count_cycles += cycles;
153
}
154
static void addcycles000_2 (char *s, int cycles)
155
{
156
        if (!using_ce)
157
                return;
158
        printf ("%sdo_cycles_ce000 (%d);\n", s, cycles);
159
        count_cycles += cycles;
160
}
161
 
162
static void addcycles000_3 (char *s)
163
{
164
        if (!using_ce)
165
                return;
166
        printf ("%sif (cycles > 0) do_cycles_ce000 (cycles);\n", s);
167
        count_ncycles++;
168
}
169
 
170
static int isreg (amodes mode)
171
{
172
        if (mode == Dreg || mode == Areg)
173
                return 1;
174
        return 0;
175
}
176
 
177
static void start_brace (void)
178
{
179
        n_braces++;
180
        printf ("{");
181
}
182
 
183
static void close_brace (void)
184
{
185
        assert (n_braces > 0);
186
        n_braces--;
187
        printf ("}");
188
}
189
 
190
static void finish_braces (void)
191
{
192
        while (n_braces > 0)
193
                close_brace ();
194
}
195
 
196
static void pop_braces (int to)
197
{
198
        while (n_braces > to)
199
                close_brace ();
200
}
201
 
202
static int bit_size (int size)
203
{
204
        switch (size) {
205
        case sz_byte: return 8;
206
        case sz_word: return 16;
207
        case sz_long: return 32;
208
        default: abort ();
209
        }
210
        return 0;
211
}
212
 
213
static const char *bit_mask (int size)
214
{
215
        switch (size) {
216
        case sz_byte: return "0xff";
217
        case sz_word: return "0xffff";
218
        case sz_long: return "0xffffffff";
219
        default: abort ();
220
        }
221
        return 0;
222
}
223
 
224
static void gen_nextilong (char *type, char *name, int norefill)
225
{
226
        int r = m68k_pc_offset;
227
        m68k_pc_offset += 4;
228
 
229
        if (using_ce020) {
230
                printf ("\t%s %s = get_long_ce020_prefetch (%d);\n", type, name, r);
231
                count_read += 2;
232
        } else if (using_ce) {
233
                printf ("\t%s %s;\n", type, name);
234
                /* we must do this because execution order of (something | something2) is not defined */
235
                if (norefill) {
236
                        printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2);
237
                        count_read++;
238
                        printf ("\t%s |= regs.irc;\n", name);
239
                } else {
240
                        printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2);
241
                        count_read++;
242
                        printf ("\t%s |= get_word_ce_prefetch (%d);\n", name, r + 4);
243
                        count_read++;
244
                }
245
        } else {
246
                if (using_prefetch) {
247
                        if (norefill) {
248
                                printf ("\t%s %s;\n", type, name);
249
                                printf ("\t%s = get_word_prefetch (%d) << 16;\n", name, r + 2);
250
                                count_read++;
251
                                printf ("\t%s |= regs.irc;\n", name);
252
                                insn_n_cycles += 4;
253
                        } else {
254
                                printf ("\t%s %s = get_long_prefetch (%d);\n", type, name, r + 2);
255
                                count_read++;
256
                                count_read++;
257
                                insn_n_cycles += 8;
258
                        }
259
                } else if (using_indirect) {
260
                        insn_n_cycles += 8;
261
                        printf ("\t%s %s = get_ilongi (%d);\n", type, name, r);
262
                } else if (using_mmu) {
263
                        insn_n_cycles += 8;
264
                        printf ("\t%s %s = get_ilong_mmu (%d);\n", type, name, r);
265
                } else {
266
                        insn_n_cycles += 8;
267
                        printf ("\t%s %s = get_ilong (%d);\n", type, name, r);
268
                }
269
        }
270
}
271
 
272
static const char *gen_nextiword (int norefill)
273
{
274
        static char buffer[80];
275
        int r = m68k_pc_offset;
276
        m68k_pc_offset += 2;
277
 
278
        if (using_ce020) {
279
                sprintf (buffer, "get_word_ce020_prefetch (%d)", r);
280
                count_read++;
281
        } else if (using_ce) {
282
                if (norefill) {
283
                        strcpy (buffer, "regs.irc");
284
                } else {
285
                        sprintf (buffer, "get_word_ce_prefetch (%d)", r + 2);
286
                        count_read++;
287
                }
288
        } else {
289
                if (using_prefetch) {
290
                        if (norefill) {
291
                                sprintf (buffer, "regs.irc", r);
292
                        } else {
293
                                sprintf (buffer, "get_word_prefetch (%d)", r + 2);
294
                                count_read++;
295
                                insn_n_cycles += 4;
296
                        }
297
                } else if (using_indirect) {
298
                        sprintf (buffer, "get_iwordi(%d)", r);
299
                        insn_n_cycles += 4;
300
                } else if (using_mmu) {
301
                        sprintf (buffer, "get_iword_mmu (%d)", r);
302
                        insn_n_cycles += 4;
303
                } else {
304
                        sprintf (buffer, "get_iword (%d)", r);
305
                        insn_n_cycles += 4;
306
                }
307
        }
308
        return buffer;
309
}
310
 
311
static const char *gen_nextibyte (int norefill)
312
{
313
        static char buffer[80];
314
        int r = m68k_pc_offset;
315
        m68k_pc_offset += 2;
316
 
317
        if (using_ce020) {
318
                sprintf (buffer, "(uae_u8)get_word_ce020_prefetch (%d)", r);
319
                count_read++;
320
        } else if (using_ce) {
321
                if (norefill) {
322
                        strcpy (buffer, "(uae_u8)regs.irc");
323
                } else {
324
                        sprintf (buffer, "(uae_u8)get_word_ce_prefetch (%d)", r + 2);
325
                        count_read++;
326
                }
327
        } else {
328
                insn_n_cycles += 4;
329
                if (using_prefetch) {
330
                        if (norefill) {
331
                                sprintf (buffer, "(uae_u8)regs.irc", r);
332
                        } else {
333
                                sprintf (buffer, "(uae_u8)get_word_prefetch (%d)", r + 2);
334
                                insn_n_cycles += 4;
335
                                count_read++;
336
                        }
337
                } else if (using_indirect)  {
338
                        sprintf (buffer, "get_ibytei (%d)", r);
339
                        insn_n_cycles += 4;
340
                } else if (using_mmu)  {
341
                        sprintf (buffer, "get_ibyte_mmu (%d)", r);
342
                        insn_n_cycles += 4;
343
                } else {
344
                        sprintf (buffer, "get_ibyte (%d)", r);
345
                        insn_n_cycles += 4;
346
                }
347
        }
348
        return buffer;
349
}
350
 
351
static void irc2ir (void)
352
{
353
        if (!using_prefetch)
354
                return;
355
        printf ("\tregs.ir = regs.irc;\n");
356
}
357
 
358
static int did_prefetch;
359
 
360
static void fill_prefetch_2 (void)
361
{
362
        if (!using_prefetch)
363
                return;
364
        if (using_ce)
365
                printf ("\tget_word_ce_prefetch (%d);\n", m68k_pc_offset + 2);
366
        else
367
                printf ("\tget_word_prefetch (%d);\n", m68k_pc_offset + 2);
368
        did_prefetch = 1;
369
        count_read++;
370
        insn_n_cycles += 4;
371
}
372
 
373
static void fill_prefetch_1 (int o)
374
{
375
        if (!using_prefetch)
376
                return;
377
        if (using_ce) {
378
                printf ("\tget_word_ce_prefetch (%d);\n", o);
379
        } else {
380
                printf ("\tget_word_prefetch (%d);\n", o);
381
        }
382
        did_prefetch = 1;
383
        count_read++;
384
        insn_n_cycles += 4;
385
}
386
 
387
static void fill_prefetch_full (void)
388
{
389
        fill_prefetch_1 (0);
390
        irc2ir ();
391
        fill_prefetch_1 (2);
392
}
393
 
394
static void fill_prefetch_0 (void)
395
{
396
        if (!using_prefetch)
397
                return;
398
        if (using_ce)
399
                printf ("\tget_word_ce_prefetch (0);\n");
400
        else
401
                printf ("\tget_word_prefetch (0);\n");
402
        did_prefetch = 1;
403
        count_read++;
404
        insn_n_cycles += 4;
405
}
406
 
407
static void fill_prefetch_next_1 (void)
408
{
409
        irc2ir ();
410
        fill_prefetch_1 (m68k_pc_offset + 2);
411
}
412
 
413
static void fill_prefetch_next (void)
414
{
415
        fill_prefetch_next_1 ();
416
}
417
 
418
#if 0
419
static void fill_prefetch_next_delay (int extracycles)
420
{
421
        if (!using_prefetch)
422
                return;
423
        if (using_ce) {
424
                if (extracycles > 0) {
425
                        printf("\t{\n");
426
                        fill_prefetch_next ();
427
                        printf("\tif (%d > 0) do_cycles(%d * CYCLE_UNIT / 2);\n",
428
                                extracycles, extracycles);
429
                        printf("\t}\n");
430
                } else {
431
                        fill_prefetch_next ();
432
                }
433
        } else {
434
                fill_prefetch_next ();
435
        }
436
}
437
#endif
438
 
439
static void fill_prefetch_finish (void)
440
{
441
        if (did_prefetch || !using_prefetch)
442
                return;
443
        fill_prefetch_1 (m68k_pc_offset);
444
}
445
 
446
static void setpc (const char *format, ...)
447
{
448
        va_list parms;
449
        char buffer[1000];
450
 
451
        va_start (parms, format);
452
        _vsnprintf (buffer, 1000 - 1, format, parms);
453
        va_end (parms);
454
 
455
        if (using_mmu)
456
                printf ("\tm68k_setpc_mmu (%s);\n", buffer);
457
        else
458
                printf ("\tm68k_setpc (%s);\n", buffer);
459
}
460
 
461
static void incpc (const char *format, ...)
462
{
463
        va_list parms;
464
        char buffer[1000];
465
 
466
        va_start (parms, format);
467
        _vsnprintf (buffer, 1000 - 1, format, parms);
468
        va_end (parms);
469
 
470
        if (using_mmu)
471
                printf ("\tm68k_incpci (%s);\n", buffer);
472
        else
473
                printf ("\tm68k_incpc (%s);\n", buffer);
474
}
475
 
476
static void sync_m68k_pc (void)
477
{
478
        if (m68k_pc_offset == 0)
479
                return;
480
        incpc ("%d", m68k_pc_offset);
481
        m68k_pc_offset = 0;
482
}
483
 
484
static void gen_set_fault_pc (void)
485
{
486
        if (!using_mmu)
487
                return;
488
        sync_m68k_pc ();
489
        printf ("\tregs.fault_pc = m68k_getpci ();\n");
490
        m68k_pc_offset = 0;
491
}
492
 
493
/* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
494
* the calling routine handles Apdi and Aipi modes.
495
* gb-- movem == 2 means the same thing but for a MOVE16 instruction */
496
 
497
/* fixup indicates if we want to fix up adress registers in pre decrement
498
* or post increment mode now (0) or later (1). A value of 2 will then be
499
* used to do the actual fix up. This allows to do all memory readings
500
* before any register is modified, and so to rerun operation without
501
* side effect in case a bus fault is generated by any memory access.
502
* XJ - 2006/11/13 */
503
 
504
static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int fixup, int e3fudge)
505
{
506
        char namea[100];
507
        //AO extra
508
        //int m68k_pc_offset_last = m68k_pc_offset;
509
 
510
        sprintf (namea, "%sa", name);
511
 
512
        start_brace ();
513
        switch (mode) {
514
        case Dreg:
515
                if (movem)
516
                        abort ();
517
                if (getv == 1)
518
                        switch (size) {
519
                        case sz_byte:
520
#ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION
521
                                /* This causes the target compiler to generate better code on few systems */
522
                                printf ("\tuae_s8 %s = ((uae_u8*)&m68k_dreg (regs, %s))[3];\n", name, reg);
523
#else
524
                                printf ("\tuae_s8 %s = m68k_dreg (regs, %s);\n", name, reg);
525
#endif
526
                                break;
527
                        case sz_word:
528
#ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION
529
                                printf ("\tuae_s16 %s = ((uae_s16*)&m68k_dreg (regs, %s))[1];\n", name, reg);
530
#else
531
                                printf ("\tuae_s16 %s = m68k_dreg (regs, %s);\n", name, reg);
532
#endif
533
                                break;
534
                        case sz_long:
535
                                printf ("\tuae_s32 %s = m68k_dreg (regs, %s);\n", name, reg);
536
                                break;
537
                        default:
538
                                abort ();
539
                }
540
                return;
541
        case Areg:
542
                if (movem)
543
                        abort ();
544
                if (getv == 1)
545
                        switch (size) {
546
                        case sz_word:
547
                                printf ("\tuae_s16 %s = m68k_areg (regs, %s);\n", name, reg);
548
                                break;
549
                        case sz_long:
550
                                printf ("\tuae_s32 %s = m68k_areg (regs, %s);\n", name, reg);
551
                                break;
552
                        default:
553
                                abort ();
554
                }
555
                return;
556
        case Aind: // (An)
557
                printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg);
558
                break;
559
        case Aipi: // (An)+
560
                printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg);
561
                break;
562
        case Apdi: // -(An)
563
                printf ("\tuaecptr %sa;\n", name);
564
                switch (size) {
565
                case sz_byte:
566
                        if (movem)
567
                                printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg);
568
                        else
569
                                printf ("\t%sa = m68k_areg (regs, %s) - areg_byteinc[%s];\n", name, reg, reg);
570
                        break;
571
                case sz_word:
572
                        printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 2);
573
                        break;
574
                case sz_long:
575
                        printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 4);
576
                        break;
577
                default:
578
                        abort ();
579
                }
580
                if (!(flags & GF_APDI)) {
581
                        addcycles000 (2);
582
                        insn_n_cycles += 2;
583
                        count_cycles_ea += 2;
584
                }
585
                break;
586
        case Ad16: // (d16,An)
587
                printf ("\tuaecptr %sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags & GF_NOREFILL));
588
                count_read_ea++;
589
                break;
590
        case Ad8r: // (d8,An,Xn)
591
                printf ("\tuaecptr %sa;\n", name);
592
                if (cpu_level > 1) {
593
                        if (next_cpu_level < 1)
594
                                next_cpu_level = 1;
595
                        sync_m68k_pc ();
596
                        start_brace ();
597
                        /* This would ordinarily be done in gen_nextiword, which we bypass.  */
598
                        insn_n_cycles += 4;
599
                        if (using_ce020)
600
                                printf ("\t%sa = get_disp_ea_020ce (m68k_areg (regs, %s), next_iword_020ce ());\n", name, reg);
601
                        else if (using_mmu)
602
                                printf ("\t%sa = get_disp_ea_040mmu (m68k_areg (regs, %s), next_iword_mmu ());\n", name, reg);
603
                        else
604
                                printf ("\t%sa = get_disp_ea_020 (m68k_areg (regs, %s), next_iword ());\n", name, reg);
605
                } else {
606
                        printf ("\t%sa = get_disp_ea_000 (m68k_areg (regs, %s), %s);\n", name, reg, gen_nextiword (flags & GF_NOREFILL));
607
                        count_read_ea++;
608
                }
609
                if (!(flags & GF_AD8R)) {
610
                        addcycles000 (2);
611
                        insn_n_cycles += 2;
612
                        count_cycles_ea += 2;
613
                }
614
                break;
615
        case PC16: // (d16,PC,Xn)
616
                printf ("\tuaecptr %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset);
617
                printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL));
618
                break;
619
        case PC8r: // (d8,PC,Xn)
620
                printf ("\tuaecptr tmppc;\n");
621
                printf ("\tuaecptr %sa;\n", name);
622
                if (cpu_level > 1) {
623
                        if (next_cpu_level < 1)
624
                                next_cpu_level = 1;
625
                        sync_m68k_pc ();
626
                        start_brace ();
627
                        /* This would ordinarily be done in gen_nextiword, which we bypass.  */
628
                        insn_n_cycles += 4;
629
                        printf ("\ttmppc = m68k_getpc ();\n");
630
                        if (using_ce020)
631
                                printf ("\t%sa = get_disp_ea_020ce (tmppc, next_iword_020ce ());\n", name);
632
                        else if (using_mmu)
633
                                printf ("\t%sa = get_disp_ea_040mmu (tmppc, next_iword_mmu ());\n", name);
634
                        else
635
                                printf ("\t%sa = get_disp_ea_020 (tmppc, next_iword ());\n", name);
636
                } else {
637
                        printf ("\ttmppc = m68k_getpc () + %d;\n", m68k_pc_offset);
638
                        printf ("\t%sa = get_disp_ea_000 (tmppc, %s);\n", name, gen_nextiword (flags & GF_NOREFILL));
639
                }
640
                if (!(flags & GF_PC8R)) {
641
                        addcycles000 (2);
642
                        insn_n_cycles += 2;
643
                        count_cycles_ea += 2;
644
                }
645
 
646
                break;
647
        case absw:
648
                printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL));
649
                break;
650
        case absl:
651
                gen_nextilong ("uaecptr", namea, flags & GF_NOREFILL);
652
                count_read_ea += 2;
653
                break;
654
        case imm:
655
                if (getv != 1)
656
                        abort ();
657
                insn_n_cycles020++;
658
                switch (size) {
659
                case sz_byte:
660
                        printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL));
661
                        count_read_ea++;
662
                        break;
663
                case sz_word:
664
                        printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL));
665
                        count_read_ea++;
666
                        break;
667
                case sz_long:
668
                        gen_nextilong ("uae_s32", name, flags & GF_NOREFILL);
669
                        count_read_ea += 2;
670
                        break;
671
                default:
672
                        abort ();
673
                }
674
                return;
675
        case imm0:
676
                if (getv != 1)
677
                        abort ();
678
                printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL));
679
                count_read_ea++;
680
                return;
681
        case imm1:
682
                if (getv != 1)
683
                        abort ();
684
                printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL));
685
                count_read_ea++;
686
                return;
687
        case imm2:
688
                if (getv != 1)
689
                        abort ();
690
                gen_nextilong ("uae_s32", name, flags & GF_NOREFILL);
691
                count_read_ea += 2;
692
                return;
693
        case immi:
694
                if (getv != 1)
695
                        abort ();
696
                printf ("\tuae_u32 %s = %s;\n", name, reg);
697
                return;
698
        default:
699
                abort ();
700
        }
701
 
702
        /* We get here for all non-reg non-immediate addressing modes to
703
        * actually fetch the value. */
704
 
705
        if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte) {
706
                printf ("\tif (%sa & 1) {\n", name);
707
                //AO extra, m68k_pc_offset_last -> mk68k_pc_offset
708
                if(getv == 4 && size == sz_word && mode == Apdi)
709
                        printf ("\t\texception3write (opcode, m68k_getpc () + %d, %sa - 2);\n",
710
                                m68k_pc_offset + e3fudge, name);
711
                else if(getv == 4 && size == sz_long && mode == Apdi)
712
                        printf ("\t\texception3write (opcode, m68k_getpc () + %d, %sa - 4);\n",
713
                                m68k_pc_offset + e3fudge, name);
714
                else if(getv == 3 || getv == 4)
715
                        printf ("\t\texception3write (opcode, m68k_getpc () + %d, %sa);\n",
716
                                m68k_pc_offset + e3fudge, name);
717
                else if(mode == PC16 || mode == PC8r)
718
                        printf ("\t\texception3i (opcode, m68k_getpc () + %d, %sa);\n",
719
                                m68k_pc_offset + e3fudge, name);
720
                else
721
                        printf ("\t\texception3 (opcode, m68k_getpc () + %d, %sa);\n",
722
                                m68k_pc_offset + e3fudge, name);
723
                printf ("\t\tgoto %s;\n", endlabelstr);
724
                printf ("\t}\n");
725
                need_endlabel = 1;
726
                start_brace ();
727
        }
728
 
729
        if (flags & GF_PREFETCH)
730
                fill_prefetch_next ();
731
 
732
        if (getv == 1) {
733
                start_brace ();
734
                if (using_ce020) {
735
                        switch (size) {
736
                        case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_ce020 (%sa);\n", name, name); count_read++; break;
737
                        case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_ce020 (%sa);\n", name, name); count_read++; break;
738
                        case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_ce020 (%sa);\n", name, name); count_read += 2; break;
739
                        default: abort ();
740
                        }
741
                } else if (using_ce) {
742
                        switch (size) {
743
                        case sz_byte: printf ("\tuae_s8 %s = get_byte_ce (%sa);\n", name, name); count_read++; break;
744
                        case sz_word: printf ("\tuae_s16 %s = get_word_ce (%sa);\n", name, name); count_read++; break;
745
                        case sz_long: printf ("\tuae_s32 %s = get_word_ce (%sa) << 16; %s |= get_word_ce (%sa + 2);\n", name, name, name, name); count_read += 2; break;
746
                        default: abort ();
747
                        }
748
                } else if (using_mmu) {
749
                        if (flags & GF_FC) {
750
                                switch (size) {
751
                                case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = sfc_get_byte (%sa);\n", name, name); break;
752
                                case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = sfc_get_word (%sa);\n", name, name); break;
753
                                case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = sfc_get_long (%sa);\n", name, name); break;
754
                                default: abort ();
755
                                }
756
                        } else {
757
                                switch (size) {
758
                                case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_mmu (%sa);\n", name, name); break;
759
                                case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_mmu (%sa);\n", name, name); break;
760
                                case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_mmu (%sa);\n", name, name); break;
761
                                default: abort ();
762
                                }
763
                        }
764
                } else {
765
                        switch (size) {
766
                        case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte (%sa);\n", name, name); count_read++; break;
767
                        case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word (%sa);\n", name, name); count_read++; break;
768
                        case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long (%sa);\n", name, name); count_read += 2; break;
769
                        default: abort ();
770
                        }
771
                }
772
        }
773
 
774
        /* We now might have to fix up the register for pre-dec or post-inc
775
        * addressing modes. */
776
        if (!movem)
777
                switch (mode) {
778
                case Aipi:
779
                        if (fixup == 1) {
780
                                printf ("\tmmufixup[%d].reg = %s;\n", fixupcnt, reg);
781
                                printf ("\tmmufixup[%d].value = m68k_areg (regs, %s);\n", fixupcnt, reg);
782
                        }
783
                        switch (size) {
784
                        case sz_byte:
785
                                printf ("\tm68k_areg (regs, %s) += areg_byteinc[%s];\n", reg, reg);
786
                                break;
787
                        case sz_word:
788
                                printf ("\tm68k_areg (regs, %s) += 2;\n", reg);
789
                                break;
790
                        case sz_long:
791
                                printf ("\tm68k_areg (regs, %s) += 4;\n", reg);
792
                                break;
793
                        default:
794
                                abort ();
795
                        }
796
                        break;
797
                case Apdi:
798
                        if (fixup == 1) {
799
                                printf ("\tmmufixup[%d].reg = %s;\n", fixupcnt, reg);
800
                                printf ("\tmmufixup[%d].value = m68k_areg (regs, %s);\n", fixupcnt, reg);
801
                        }
802
                        printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name);
803
                        break;
804
                default:
805
                        break;
806
        }
807
}
808
 
809
static void genamode_fixup (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int fixup)
810
{
811
        if (fixup != 2) {
812
                genamode2 (mode, reg, size, name, getv, movem, flags, fixup, 0);
813
        } else {
814
                if (!movem) {
815
                        switch (mode)
816
                        {
817
                        case Aipi:
818
                        case Apdi:
819
                                printf ("\tmmufixup[0].reg = -1;\n", fixupcnt);
820
                                break;
821
                        }
822
                }
823
        }
824
}
825
 
826
static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags)
827
{
828
        genamode2 (mode, reg, size, name, getv, movem, flags, 0, 0);
829
}
830
static void genamode_pre (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags)
831
{
832
        genamode_fixup (mode, reg, size, name, getv, movem, flags, using_mmu ? 1 : 0);
833
}
834
static void genamode_post (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags)
835
{
836
        if (using_mmu)
837
                genamode_fixup (mode, reg, size, name, getv, movem, flags, 2);
838
}
839
static void genamode_e3 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int e3fudge)
840
{
841
        genamode2 (mode, reg, size, name, getv, movem, flags, 0, e3fudge);
842
}
843
 
844
static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, char *to, int store_dir, int flags)
845
{
846
        switch (mode) {
847
        case Dreg:
848
                switch (size) {
849
                case sz_byte:
850
                        printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from);
851
                        break;
852
                case sz_word:
853
                        printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from);
854
                        break;
855
                case sz_long:
856
                        printf ("\tm68k_dreg (regs, %s) = (%s);\n", reg, from);
857
                        break;
858
                default:
859
                        abort ();
860
                }
861
                break;
862
        case Areg:
863
                switch (size) {
864
                case sz_word:
865
                        printf ("\tm68k_areg (regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from);
866
                        break;
867
                case sz_long:
868
                        printf ("\tm68k_areg (regs, %s) = (%s);\n", reg, from);
869
                        break;
870
                default:
871
                        abort ();
872
                }
873
                break;
874
        case Aind:
875
        case Aipi:
876
        case Apdi:
877
        case Ad16:
878
        case Ad8r:
879
        case absw:
880
        case absl:
881
        case PC16:
882
        case PC8r:
883
                gen_set_fault_pc ();
884
                if (using_ce020) {
885
                        switch (size) {
886
                        case sz_byte:
887
                                printf ("\tput_byte_ce020 (%sa,%s);\n", to, from);
888
                                count_write++;
889
                                break;
890
                        case sz_word:
891
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
892
                                        abort ();
893
                                printf ("\tput_word_ce020 (%sa,%s);\n", to, from);
894
                                count_write++;
895
                                break;
896
                        case sz_long:
897
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
898
                                        abort ();
899
                                printf ("\tput_long_ce020 (%sa, %s);\n", to, from);
900
                                count_write += 2;
901
                                break;
902
                        default:
903
                                abort ();
904
                        }
905
                } else if (using_ce) {
906
                        switch (size) {
907
                        case sz_byte:
908
                                printf ("\tput_byte_ce (%sa,%s);\n", to, from);
909
                                count_write++;
910
                                break;
911
                        case sz_word:
912
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
913
                                        abort ();
914
                                printf ("\tput_word_ce (%sa,%s);\n", to, from);
915
                                count_write++;
916
                                break;
917
                        case sz_long:
918
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
919
                                        abort ();
920
                                if (store_dir)
921
                                        printf ("\tput_word_ce (%sa + 2, %s); put_word_ce (%sa, %s >> 16);\n", to, from, to, from);
922
                                else
923
                                        printf ("\tput_word_ce (%sa, %s >> 16); put_word_ce (%sa + 2, %s);\n", to, from, to, from);
924
                                count_write += 2;
925
                                break;
926
                        default:
927
                                abort ();
928
                        }
929
                } else if (using_mmu) {
930
                        switch (size) {
931
                        case sz_byte:
932
                                insn_n_cycles += 4;
933
                                if (flags & GF_FC)
934
                                        printf ("\tdfc_put_byte (%sa,%s);\n", to, from);
935
                                else
936
                                        printf ("\tput_byte_mmu (%sa,%s);\n", to, from);
937
                                break;
938
                        case sz_word:
939
                                insn_n_cycles += 4;
940
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
941
                                        abort ();
942
                                if (flags & GF_FC)
943
                                        printf ("\tdfc_put_word (%sa,%s);\n", to, from);
944
                                else
945
                                        printf ("\tput_word_mmu (%sa,%s);\n", to, from);
946
                                break;
947
                        case sz_long:
948
                                insn_n_cycles += 8;
949
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
950
                                        abort ();
951
                                if (flags & GF_FC)
952
                                        printf ("\tdfc_put_long (%sa,%s);\n", to, from);
953
                                else
954
                                        printf ("\tput_long_mmu (%sa,%s);\n", to, from);
955
                                break;
956
                        default:
957
                                abort ();
958
                        }
959
                } else {
960
                        switch (size) {
961
                        case sz_byte:
962
                                insn_n_cycles += 4;
963
                                printf ("\tput_byte (%sa,%s);\n", to, from);
964
                                count_write++;
965
                                break;
966
                        case sz_word:
967
                                insn_n_cycles += 4;
968
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
969
                                        abort ();
970
                                printf ("\tput_word (%sa,%s);\n", to, from);
971
                                count_write++;
972
                                break;
973
                        case sz_long:
974
                                insn_n_cycles += 8;
975
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
976
                                        abort ();
977
                                printf ("\tput_long (%sa,%s);\n", to, from);
978
                                count_write += 2;
979
                                break;
980
                        default:
981
                                abort ();
982
                        }
983
                }
984
                break;
985
        case imm:
986
        case imm0:
987
        case imm1:
988
        case imm2:
989
        case immi:
990
                abort ();
991
                break;
992
        default:
993
                abort ();
994
        }
995
}
996
 
997
static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to)
998
{
999
        genastore_2 (from, mode, reg, size, to, 0, 0);
1000
}
1001
static void genastore_rev (char *from, amodes mode, char *reg, wordsizes size, char *to)
1002
{
1003
        genastore_2 (from, mode, reg, size, to, 1, 0);
1004
}
1005
static void genastore_fc (char *from, amodes mode, char *reg, wordsizes size, char *to)
1006
{
1007
        genastore_2 (from, mode, reg, size, to, 1, GF_FC);
1008
}
1009
 
1010
static void genmovemel (uae_u16 opcode)
1011
{
1012
        char getcode[100];
1013
        int size = table68k[opcode].size == sz_long ? 4 : 2;
1014
 
1015
        if (using_mmu) {
1016
                if (table68k[opcode].size == sz_long) {
1017
                        strcpy (getcode, "get_long_mmu (srca)");
1018
                } else {
1019
                        strcpy (getcode, "(uae_s32)(uae_s16)get_word_mmu (srca)");
1020
                }
1021
        } else {
1022
                if (table68k[opcode].size == sz_long) {
1023
                        strcpy (getcode, "get_long (srca)");
1024
                } else {
1025
                        strcpy (getcode, "(uae_s32)(uae_s16)get_word (srca)");
1026
                }
1027
        }
1028
        count_read += table68k[opcode].size == sz_long ? 2 : 1;
1029
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1030
        printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1031
        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0);
1032
        start_brace ();
1033
        printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask]; }\n",
1034
                getcode, size);
1035
        printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask]; }\n",
1036
                getcode, size);
1037
 
1038
        if (table68k[opcode].dmode == Aipi) {
1039
                printf ("\tm68k_areg (regs, dstreg) = srca;\n");
1040
                count_read++;
1041
        }
1042
        fill_prefetch_next ();
1043
        count_ncycles++;
1044
}
1045
 
1046
static void genmovemel_ce (uae_u16 opcode)
1047
{
1048
        int size = table68k[opcode].size == sz_long ? 4 : 2;
1049
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1050
        printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1051
        printf ("\tuae_u32 v;\n");
1052
        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
1053
        if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
1054
                addcycles000 (2);
1055
        start_brace ();
1056
        if (table68k[opcode].size == sz_long) {
1057
                printf ("\twhile (dmask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_dreg (regs, movem_index1[dmask]) = v; srca += %d; dmask = movem_next[dmask]; }\n",
1058
                        size);
1059
                printf ("\twhile (amask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_areg (regs, movem_index1[amask]) = v; srca += %d; amask = movem_next[amask]; }\n",
1060
                        size);
1061
        } else {
1062
                printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; dmask = movem_next[dmask]; }\n",
1063
                        size);
1064
                printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; amask = movem_next[amask]; }\n",
1065
                        size);
1066
        }
1067
        printf ("\tget_word_ce (srca);\n"); // and final extra word fetch that goes nowhere..
1068
        count_read++;
1069
        if (table68k[opcode].dmode == Aipi)
1070
                printf ("\tm68k_areg (regs, dstreg) = srca;\n");
1071
        fill_prefetch_next ();
1072
        count_ncycles++;
1073
}
1074
 
1075
static void genmovemle (uae_u16 opcode)
1076
{
1077
        char *putcode;
1078
        int size = table68k[opcode].size == sz_long ? 4 : 2;
1079
 
1080
        if (using_mmu) {
1081
                if (table68k[opcode].size == sz_long) {
1082
                        putcode = "put_long_mmu (srca";
1083
                } else {
1084
                        putcode = "put_word_mmu (srca";
1085
                }
1086
        } else {
1087
                if (table68k[opcode].size == sz_long) {
1088
                        putcode = "put_long (srca";
1089
                } else {
1090
                        putcode = "put_word (srca";
1091
                }
1092
        }
1093
        count_write += table68k[opcode].size == sz_long ? 2 : 1;
1094
 
1095
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1096
        //AO extra: 2->4
1097
        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 4, 1, 0);
1098
        start_brace ();
1099
        if (table68k[opcode].dmode == Apdi) {
1100
                printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
1101
                if (!using_mmu)
1102
                        printf ("\tint type = get_cpu_model() >= 68020;\n");
1103
                printf ("\twhile (amask) {\n");
1104
                printf ("\t\tsrca -= %d;\n", size);
1105
                if (!using_mmu)
1106
                        printf ("\t\tif (type) m68k_areg (regs, dstreg) = srca;\n");
1107
                printf ("\t\t%s, m68k_areg (regs, movem_index2[amask]));\n", putcode);
1108
                printf ("\t\tamask = movem_next[amask];\n");
1109
                printf ("\t}\n");
1110
                printf ("\twhile (dmask) { srca -= %d; %s, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
1111
                        size, putcode);
1112
                printf ("\tm68k_areg (regs, dstreg) = srca;\n");
1113
        } else {
1114
                printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1115
                printf ("\twhile (dmask) { %s, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
1116
                        putcode, size);
1117
                printf ("\twhile (amask) { %s, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
1118
                        putcode, size);
1119
        }
1120
        if (using_prefetch) {
1121
                sync_m68k_pc ();
1122
                fill_prefetch_next ();
1123
        }
1124
        count_ncycles++;
1125
}
1126
 
1127
static void genmovemle_ce (uae_u16 opcode)
1128
{
1129
        int size = table68k[opcode].size == sz_long ? 4 : 2;
1130
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1131
        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
1132
 
1133
        if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) {
1134
                addcycles000 (2);
1135
        }
1136
        start_brace ();
1137
        if (table68k[opcode].size == sz_long) {
1138
                if (table68k[opcode].dmode == Apdi) {
1139
                        printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
1140
                        printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
1141
                                size);
1142
                        printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
1143
                                size);
1144
                        printf ("\tm68k_areg (regs, dstreg) = srca;\n");
1145
                } else {
1146
                        printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1147
                        printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
1148
                                size);
1149
                        printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
1150
                                size);
1151
                }
1152
        } else {
1153
                if (table68k[opcode].dmode == Apdi) {
1154
                        printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
1155
                        printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
1156
                                size);
1157
                        printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
1158
                                size);
1159
                        printf ("\tm68k_areg (regs, dstreg) = srca;\n");
1160
                } else {
1161
                        printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1162
                        printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
1163
                                size);
1164
                        printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
1165
                                size);
1166
                }
1167
        }
1168
        fill_prefetch_next ();
1169
        count_ncycles++;
1170
}
1171
 
1172
static void duplicate_carry (int n)
1173
{
1174
        int i;
1175
        for (i = 0; i <= n; i++)
1176
                printf ("\t");
1177
        printf ("COPY_CARRY ();\n");
1178
}
1179
 
1180
typedef enum
1181
{
1182
        flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn,
1183
        flag_av, flag_sv
1184
}
1185
flagtypes;
1186
 
1187
static void genflags_normal (flagtypes type, wordsizes size, char *value, char *src, char *dst)
1188
{
1189
        char vstr[100], sstr[100], dstr[100];
1190
        char usstr[100], udstr[100];
1191
        char unsstr[100], undstr[100];
1192
 
1193
        switch (size) {
1194
        case sz_byte:
1195
                strcpy (vstr, "((uae_s8)(");
1196
                strcpy (usstr, "((uae_u8)(");
1197
                break;
1198
        case sz_word:
1199
                strcpy (vstr, "((uae_s16)(");
1200
                strcpy (usstr, "((uae_u16)(");
1201
                break;
1202
        case sz_long:
1203
                strcpy (vstr, "((uae_s32)(");
1204
                strcpy (usstr, "((uae_u32)(");
1205
                break;
1206
        default:
1207
                abort ();
1208
        }
1209
        strcpy (unsstr, usstr);
1210
 
1211
        strcpy (sstr, vstr);
1212
        strcpy (dstr, vstr);
1213
        strcat (vstr, value);
1214
        strcat (vstr, "))");
1215
        strcat (dstr, dst);
1216
        strcat (dstr, "))");
1217
        strcat (sstr, src);
1218
        strcat (sstr, "))");
1219
 
1220
        strcpy (udstr, usstr);
1221
        strcat (udstr, dst);
1222
        strcat (udstr, "))");
1223
        strcat (usstr, src);
1224
        strcat (usstr, "))");
1225
 
1226
        strcpy (undstr, unsstr);
1227
        strcat (unsstr, "-");
1228
        strcat (undstr, "~");
1229
        strcat (undstr, dst);
1230
        strcat (undstr, "))");
1231
        strcat (unsstr, src);
1232
        strcat (unsstr, "))");
1233
 
1234
        switch (type) {
1235
        case flag_logical_noclobber:
1236
        case flag_logical:
1237
        case flag_z:
1238
        case flag_zn:
1239
        case flag_av:
1240
        case flag_sv:
1241
        case flag_addx:
1242
        case flag_subx:
1243
                break;
1244
 
1245
        case flag_add:
1246
                start_brace ();
1247
                printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr);
1248
                break;
1249
        case flag_sub:
1250
        case flag_cmp:
1251
                start_brace ();
1252
                printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr);
1253
                break;
1254
        }
1255
 
1256
        switch (type) {
1257
        case flag_logical_noclobber:
1258
        case flag_logical:
1259
        case flag_zn:
1260
                break;
1261
 
1262
        case flag_add:
1263
        case flag_sub:
1264
        case flag_addx:
1265
        case flag_subx:
1266
        case flag_cmp:
1267
        case flag_av:
1268
        case flag_sv:
1269
                start_brace ();
1270
                printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr);
1271
                printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr);
1272
                printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr);
1273
                break;
1274
        }
1275
 
1276
        switch (type) {
1277
        case flag_logical:
1278
                printf ("\tCLEAR_CZNV ();\n");
1279
                printf ("\tSET_ZFLG   (%s == 0);\n", vstr);
1280
                printf ("\tSET_NFLG   (%s < 0);\n", vstr);
1281
                break;
1282
        case flag_logical_noclobber:
1283
                printf ("\tSET_ZFLG (%s == 0);\n", vstr);
1284
                printf ("\tSET_NFLG (%s < 0);\n", vstr);
1285
                break;
1286
        case flag_av:
1287
                printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
1288
                break;
1289
        case flag_sv:
1290
                printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
1291
                break;
1292
        case flag_z:
1293
                printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
1294
                break;
1295
        case flag_zn:
1296
                printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
1297
                printf ("\tSET_NFLG (%s < 0);\n", vstr);
1298
                break;
1299
        case flag_add:
1300
                printf ("\tSET_ZFLG (%s == 0);\n", vstr);
1301
                printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
1302
                printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr);
1303
                duplicate_carry (0);
1304
                printf ("\tSET_NFLG (flgn != 0);\n");
1305
                break;
1306
        case flag_sub:
1307
                printf ("\tSET_ZFLG (%s == 0);\n", vstr);
1308
                printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
1309
                printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
1310
                duplicate_carry (0);
1311
                printf ("\tSET_NFLG (flgn != 0);\n");
1312
                break;
1313
        case flag_addx:
1314
                printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */
1315
                printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */
1316
                duplicate_carry (0);
1317
                break;
1318
        case flag_subx:
1319
                printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */
1320
                printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */
1321
                duplicate_carry (0);
1322
                break;
1323
        case flag_cmp:
1324
                printf ("\tSET_ZFLG (%s == 0);\n", vstr);
1325
                printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n");
1326
                printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
1327
                printf ("\tSET_NFLG (flgn != 0);\n");
1328
                break;
1329
        }
1330
}
1331
 
1332
static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst)
1333
{
1334
        /* Temporarily deleted 68k/ARM flag optimizations.  I'd prefer to have
1335
        them in the appropriate m68k.h files and use just one copy of this
1336
        code here.  The API can be changed if necessary.  */
1337
        if (optimized_flags) {
1338
                switch (type) {
1339
                case flag_add:
1340
                case flag_sub:
1341
                        start_brace ();
1342
                        printf ("\tuae_u32 %s;\n", value);
1343
                        break;
1344
 
1345
                default:
1346
                        break;
1347
                }
1348
 
1349
                /* At least some of those casts are fairly important! */
1350
                switch (type) {
1351
                case flag_logical_noclobber:
1352
                        printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n");
1353
                        if (strcmp (value, "0") == 0) {
1354
                                printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n");
1355
                        } else {
1356
                                switch (size) {
1357
                                case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
1358
                                case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
1359
                                case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
1360
                                }
1361
                                printf ("\tIOR_CZNV (oldcznv);\n");
1362
                        }
1363
                        printf ("\t}\n");
1364
                        return;
1365
                case flag_logical:
1366
                        if (strcmp (value, "0") == 0) {
1367
                                printf ("\tSET_CZNV (FLAGVAL_Z);\n");
1368
                        } else {
1369
                                switch (size) {
1370
                                case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
1371
                                case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
1372
                                case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
1373
                                }
1374
                        }
1375
                        return;
1376
 
1377
                case flag_add:
1378
                        switch (size) {
1379
                        case sz_byte: printf ("\toptflag_addb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
1380
                        case sz_word: printf ("\toptflag_addw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
1381
                        case sz_long: printf ("\toptflag_addl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
1382
                        }
1383
                        return;
1384
 
1385
                case flag_sub:
1386
                        switch (size) {
1387
                        case sz_byte: printf ("\toptflag_subb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
1388
                        case sz_word: printf ("\toptflag_subw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
1389
                        case sz_long: printf ("\toptflag_subl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
1390
                        }
1391
                        return;
1392
 
1393
                case flag_cmp:
1394
                        switch (size) {
1395
                        case sz_byte: printf ("\toptflag_cmpb (regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
1396
                        case sz_word: printf ("\toptflag_cmpw (regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
1397
                        case sz_long: printf ("\toptflag_cmpl (regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
1398
                        }
1399
                        return;
1400
 
1401
                default:
1402
                        break;
1403
                }
1404
        }
1405
 
1406
        genflags_normal (type, size, value, src, dst);
1407
}
1408
 
1409
static void force_range_for_rox (const char *var, wordsizes size)
1410
{
1411
        /* Could do a modulo operation here... which one is faster? */
1412
        switch (size) {
1413
        case sz_long:
1414
                printf ("\tif (%s >= 33) %s -= 33;\n", var, var);
1415
                break;
1416
        case sz_word:
1417
                printf ("\tif (%s >= 34) %s -= 34;\n", var, var);
1418
                printf ("\tif (%s >= 17) %s -= 17;\n", var, var);
1419
                break;
1420
        case sz_byte:
1421
                printf ("\tif (%s >= 36) %s -= 36;\n", var, var);
1422
                printf ("\tif (%s >= 18) %s -= 18;\n", var, var);
1423
                printf ("\tif (%s >= 9) %s -= 9;\n", var, var);
1424
                break;
1425
        }
1426
}
1427
 
1428
static const char *cmask (wordsizes size)
1429
{
1430
        switch (size) {
1431
        case sz_byte: return "0x80";
1432
        case sz_word: return "0x8000";
1433
        case sz_long: return "0x80000000";
1434
        default: abort ();
1435
        }
1436
}
1437
 
1438
static int source_is_imm1_8 (struct instr *i)
1439
{
1440
        return i->stype == 3;
1441
}
1442
 
1443
static void shift_ce (amodes dmode, int size)
1444
{
1445
        if (using_ce && isreg (dmode)) {
1446
                int c = size == sz_long ? 4 : 2;
1447
                printf ("\t{\n");
1448
                printf ("\t\tint cycles = %d;\n", c);
1449
                printf ("\t\tcycles += 2 * ccnt;\n");
1450
                addcycles000_3 ("\t\t");
1451
                printf ("\t}\n");
1452
                count_cycles += c;
1453
        }
1454
}
1455
 
1456
// BCHG/BSET/BCLR Dx,Dx or #xx,Dx adds 2 cycles if bit number > 15 
1457
static void bsetcycles (struct instr *curi)
1458
{
1459
        if (curi->size == sz_byte) {
1460
                printf ("\tsrc &= 7;\n");
1461
        } else {
1462
                printf ("\tsrc &= 31;\n");
1463
                if (isreg (curi->dmode)) {
1464
                        addcycles000 (2);
1465
                        if (curi->mnemo != i_BTST && using_ce) {
1466
                                printf ("\tif (src > 15) do_cycles_ce000 (2);\n");
1467
                                count_ncycles++;
1468
                        }
1469
                }
1470
        }
1471
}
1472
 
1473
static int islongimm (struct instr *curi)
1474
{
1475
        return (curi->size == sz_long && (curi->smode == Dreg || curi->smode == imm));
1476
}
1477
 
1478
static void gen_opcode (unsigned long int opcode)
1479
{
1480
        struct instr *curi = table68k + opcode;
1481
        char *srcl, *dstl;
1482
        char *srcw, *dstw;
1483
        char *srcb, *dstb;
1484
 
1485
        insn_n_cycles = using_prefetch ? 0 : 4;
1486
 
1487
        if (using_ce020) {
1488
                srcl = "get_long_ce020";
1489
                dstl = "put_long_ce020";
1490
                srcw = "get_word_ce020";
1491
                dstw = "put_word_ce020";
1492
                srcb = "get_byte_ce020";
1493
                dstb = "put_byte_ce020";
1494
        } else if (using_mmu) {
1495
                srcl = "get_long_mmu";
1496
                dstl = "put_long_mmu";
1497
                srcw = "get_word_mmu";
1498
                dstw = "put_word_mmu";
1499
                srcb = "get_byte_mmu";
1500
                dstb = "put_byte_mmu";
1501
        } else if (using_ce) {
1502
                srcl = "get_long_ce";
1503
                dstl = "put_long_ce";
1504
                srcw = "get_word_ce";
1505
                dstw = "put_word_ce";
1506
                srcb = "get_byte_ce";
1507
                dstb = "put_byte_ce";
1508
        } else {
1509
                srcl = "get_long";
1510
                dstl = "put_long";
1511
                srcw = "get_word";
1512
                dstw = "put_word";
1513
                srcb = "get_byte";
1514
                dstb = "put_byte";
1515
        }
1516
 
1517
        insn_n_cycles020 = 0;
1518
 
1519
        start_brace ();
1520
        m68k_pc_offset = 2;
1521
        switch (curi->plev) {
1522
        case 0: /* not privileged */
1523
                break;
1524
        case 1: /* unprivileged only on 68000 */
1525
                if (cpu_level == 0)
1526
                        break;
1527
                if (next_cpu_level < 0)
1528
                        next_cpu_level = 0;
1529
 
1530
                /* fall through */
1531
        case 2: /* priviledged */
1532
                printf ("if (!regs.s) { Exception (8, 0); goto %s; }\n", endlabelstr);
1533
                need_endlabel = 1;
1534
                start_brace ();
1535
                break;
1536
        case 3: /* privileged if size == word */
1537
                if (curi->size == sz_byte)
1538
                        break;
1539
                printf ("if (!regs.s) { Exception (8, 0); goto %s; }\n", endlabelstr);
1540
                need_endlabel = 1;
1541
                start_brace ();
1542
                break;
1543
        }
1544
        switch (curi->mnemo) {
1545
        case i_OR:
1546
        case i_AND:
1547
        case i_EOR:
1548
        {
1549
                int c = 0;
1550
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1551
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1552
                printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^');
1553
                genflags (flag_logical, curi->size, "src", "", "");
1554
                if (curi->dmode == Dreg && curi->size == sz_long) {
1555
                        c += 2;
1556
                        if (curi->smode == imm || curi->smode == Dreg)
1557
                                c += 2;
1558
                }
1559
                if (c > 0)
1560
                        addcycles000 (c);
1561
                fill_prefetch_next ();
1562
                genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1563
                break;
1564
        }
1565
        case i_ORSR:
1566
        case i_EORSR:
1567
                printf ("\tMakeSR ();\n");
1568
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1569
                if (curi->size == sz_byte) {
1570
                        printf ("\tsrc &= 0xFF;\n");
1571
                }
1572
                addcycles000 (4);
1573
                fill_prefetch_next ();
1574
                printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
1575
                printf ("\tMakeFromSR ();\n");
1576
                break;
1577
        case i_ANDSR:
1578
                printf ("\tMakeSR ();\n");
1579
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1580
                if (curi->size == sz_byte) {
1581
                        printf ("\tsrc |= 0xFF00;\n");
1582
                }
1583
                addcycles000 (4);
1584
                fill_prefetch_next ();
1585
                printf ("\tregs.sr &= src;\n");
1586
                printf ("\tMakeFromSR ();\n");
1587
                break;
1588
        case i_SUB:
1589
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1590
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1591
                if (curi->dmode == Dreg) {
1592
                        int c = 0;
1593
                        if (curi->size == sz_long) {
1594
                                c += 2;
1595
                                if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg)
1596
                                        c += 2;
1597
                        }
1598
                        if (c > 0)
1599
                                addcycles000 (c);
1600
                }
1601
                fill_prefetch_next ();
1602
                start_brace ();
1603
                genflags (flag_sub, curi->size, "newv", "src", "dst");
1604
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1605
                break;
1606
        case i_SUBA:
1607
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1608
                genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1609
                if (curi->smode == immi) {
1610
                        int c = 4;
1611
                        if (c > 0)
1612
                                addcycles000 (c);
1613
                } else {
1614
                        int c = curi->size == sz_long ? 2 : 4;
1615
                        if (islongimm (curi))
1616
                                c += 2;
1617
                        if (c > 0)
1618
                                addcycles000 (c);
1619
                }
1620
                fill_prefetch_next ();
1621
                start_brace ();
1622
                printf ("\tuae_u32 newv = dst - src;\n");
1623
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1624
                break;
1625
        case i_SUBX:
1626
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1627
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1628
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1629
                if (curi->size == sz_long && isreg (curi->smode))
1630
                        addcycles000 (4);
1631
                if (!isreg (curi->smode))
1632
                        addcycles000 (2);
1633
                fill_prefetch_next ();
1634
                start_brace ();
1635
                printf ("\tuae_u32 newv = dst - src - (GET_XFLG () ? 1 : 0);\n");
1636
                genflags (flag_subx, curi->size, "newv", "src", "dst");
1637
                genflags (flag_zn, curi->size, "newv", "", "");
1638
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1639
                break;
1640
        case i_SBCD:
1641
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1642
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1643
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1644
                fill_prefetch_next ();
1645
                start_brace ();
1646
                printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n");
1647
                printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n");
1648
                printf ("\tuae_u16 newv, tmp_newv;\n");
1649
                printf ("\tint bcd = 0;\n");
1650
                printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n");
1651
                printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n");
1652
                printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG () ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n");
1653
                printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG () ? 1 : 0)) & 0x300) > 0xFF);\n");
1654
                duplicate_carry (0);
1655
                /* Manual says bits NV are undefined though a real 68040/060 don't change them */
1656
                if (cpu_level >= xBCD_KEEPS_NV_FLAGS) {
1657
                        if (next_cpu_level < xBCD_KEEPS_NV_FLAGS)
1658
                                next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1;
1659
                        genflags (flag_z, curi->size, "newv", "", "");
1660
                } else {
1661
                        genflags (flag_zn, curi->size, "newv", "", "");
1662
                        printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
1663
                }
1664
                addcycles000 (2);
1665
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1666
                break;
1667
        case i_ADD:
1668
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1669
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1670
                if (curi->dmode == Dreg) {
1671
                        int c = 0;
1672
                        if (curi->size == sz_long) {
1673
                                c += 2;
1674
                                if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg)
1675
                                        c += 2;
1676
                        }
1677
                        if (c > 0)
1678
                                addcycles000 (c);
1679
                }
1680
                fill_prefetch_next ();
1681
                start_brace ();
1682
                genflags (flag_add, curi->size, "newv", "src", "dst");
1683
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1684
                break;
1685
        case i_ADDA:
1686
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1687
                genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1688
                if (curi->smode == immi) {
1689
                        int c = curi->size == sz_long ? 4 : 0;
1690
                        if (islongimm (curi))
1691
                                c += 2;
1692
                        if (c > 0)
1693
                                addcycles000 (c);
1694
                } else {
1695
                        int c = curi->size == sz_long ? 2 : 4;
1696
                        if (islongimm (curi))
1697
                                c += 2;
1698
                        if (c > 0)
1699
                                addcycles000 (c);
1700
                }
1701
                fill_prefetch_next ();
1702
                start_brace ();
1703
                printf ("\tuae_u32 newv = dst + src;\n");
1704
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1705
                break;
1706
        case i_ADDX:
1707
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1708
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1709
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1710
                if (curi->size == sz_long && isreg (curi->smode))
1711
                        addcycles000 (4);
1712
                if (!isreg (curi->smode))
1713
                        addcycles000 (2);
1714
                fill_prefetch_next ();
1715
                start_brace ();
1716
                printf ("\tuae_u32 newv = dst + src + (GET_XFLG () ? 1 : 0);\n");
1717
                genflags (flag_addx, curi->size, "newv", "src", "dst");
1718
                genflags (flag_zn, curi->size, "newv", "", "");
1719
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1720
                break;
1721
        case i_ABCD:
1722
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1723
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1724
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1725
                fill_prefetch_next ();
1726
                start_brace ();
1727
                printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG () ? 1 : 0);\n");
1728
                printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
1729
                printf ("\tuae_u16 newv, tmp_newv;\n");
1730
                printf ("\tint cflg;\n");
1731
                printf ("\tnewv = tmp_newv = newv_hi + newv_lo;");
1732
                printf ("\tif (newv_lo > 9) { newv += 6; }\n");
1733
                printf ("\tcflg = (newv & 0x3F0) > 0x90;\n");
1734
                printf ("\tif (cflg) newv += 0x60;\n");
1735
                printf ("\tSET_CFLG (cflg);\n");
1736
                duplicate_carry (0);
1737
                /* Manual says bits NV are undefined though a real 68040 don't change them */
1738
                if (cpu_level >= xBCD_KEEPS_NV_FLAGS) {
1739
                        if (next_cpu_level < xBCD_KEEPS_NV_FLAGS)
1740
                                next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1;
1741
                        genflags (flag_z, curi->size, "newv", "", "");
1742
                }
1743
                else {
1744
                        genflags (flag_zn, curi->size, "newv", "", "");
1745
                        printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
1746
                }
1747
                addcycles000 (2);
1748
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1749
                break;
1750
        case i_NEG:
1751
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1752
                if (isreg (curi->smode) && curi->size == sz_long)
1753
                        addcycles000 (2);
1754
                fill_prefetch_next ();
1755
                start_brace ();
1756
                genflags (flag_sub, curi->size, "dst", "src", "0");
1757
                genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
1758
                break;
1759
        case i_NEGX:
1760
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1761
                if (isreg (curi->smode) && curi->size == sz_long)
1762
                        addcycles000 (2);
1763
                fill_prefetch_next ();
1764
                start_brace ();
1765
                printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n");
1766
                genflags (flag_subx, curi->size, "newv", "src", "0");
1767
                genflags (flag_zn, curi->size, "newv", "", "");
1768
                genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src");
1769
                break;
1770
        case i_NBCD:
1771
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1772
                if (isreg (curi->smode))
1773
                        addcycles000 (2);
1774
                fill_prefetch_next ();
1775
                start_brace ();
1776
                printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n");
1777
                printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n");
1778
                printf ("\tuae_u16 newv;\n");
1779
                printf ("\tint cflg;\n");
1780
                printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
1781
                printf ("\tnewv = newv_hi + newv_lo;");
1782
                printf ("\tcflg = (newv & 0x1F0) > 0x90;\n");
1783
                printf ("\tif (cflg) newv -= 0x60;\n");
1784
                printf ("\tSET_CFLG (cflg);\n");
1785
                duplicate_carry(0);
1786
                /* Manual says bits NV are undefined though a real 68040 don't change them */
1787
                if (cpu_level >= xBCD_KEEPS_NV_FLAGS) {
1788
                        if (next_cpu_level < xBCD_KEEPS_NV_FLAGS)
1789
                                next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1;
1790
                        genflags (flag_z, curi->size, "newv", "", "");
1791
                }
1792
                else {
1793
                        genflags (flag_zn, curi->size, "newv", "", "");
1794
                }
1795
                genastore ("newv", curi->smode, "srcreg", curi->size, "src");
1796
                break;
1797
        case i_CLR:
1798
                genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
1799
                if (isreg (curi->smode) && curi->size == sz_long)
1800
                        addcycles000 (2);
1801
                fill_prefetch_next ();
1802
                genflags (flag_logical, curi->size, "0", "", "");
1803
                genastore_rev ("0", curi->smode, "srcreg", curi->size, "src");
1804
                break;
1805
        case i_NOT:
1806
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1807
                if (isreg (curi->smode) && curi->size == sz_long)
1808
                        addcycles000 (2);
1809
                fill_prefetch_next ();
1810
                start_brace ();
1811
                printf ("\tuae_u32 dst = ~src;\n");
1812
                genflags (flag_logical, curi->size, "dst", "", "");
1813
                genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
1814
                break;
1815
        case i_TST:
1816
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1817
                fill_prefetch_next ();
1818
                genflags (flag_logical, curi->size, "src", "", "");
1819
                break;
1820
        case i_BTST:
1821
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1822
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1823
                fill_prefetch_next ();
1824
                bsetcycles (curi);
1825
                printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1826
                break;
1827
        case i_BCHG:
1828
        case i_BCLR:
1829
        case i_BSET:
1830
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1831
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1832
                bsetcycles (curi);
1833
                if (curi->mnemo == i_BCLR && curi->dmode == Dreg)
1834
                        addcycles000 (2);
1835
                fill_prefetch_next ();
1836
                if (curi->mnemo == i_BCHG) {
1837
                        printf ("\tdst ^= (1 << src);\n");
1838
                        printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n");
1839
                } else if (curi->mnemo == i_BCLR) {
1840
                        printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1841
                        printf ("\tdst &= ~(1 << src);\n");
1842
                } else if (curi->mnemo == i_BSET) {
1843
                        printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1844
                        printf ("\tdst |= (1 << src);\n");
1845
                }
1846
                genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1847
                break;
1848
        case i_CMPM:
1849
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1850
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1851
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1852
                fill_prefetch_next ();
1853
                start_brace ();
1854
                genflags (flag_cmp, curi->size, "newv", "src", "dst");
1855
                break;
1856
        case i_CMP:
1857
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1858
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1859
                if (curi->dmode == Dreg && curi->size == sz_long)
1860
                        addcycles000 (2);
1861
                fill_prefetch_next ();
1862
                start_brace ();
1863
                genflags (flag_cmp, curi->size, "newv", "src", "dst");
1864
                break;
1865
        case i_CMPA:
1866
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1867
                genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1868
                fill_prefetch_next ();
1869
                addcycles000 (2);
1870
                start_brace ();
1871
                genflags (flag_cmp, sz_long, "newv", "src", "dst");
1872
                break;
1873
                /* The next two are coded a little unconventional, but they are doing
1874
                * weird things... */
1875
        case i_MVPRM: // MOVEP R->M
1876
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1877
                printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
1878
                if (curi->size == sz_word) {
1879
                        printf ("\t%s (memp, src >> 8); %s (memp + 2, src);\n", dstb, dstb);
1880
                        count_write += 2;
1881
                } else {
1882
                        printf ("\t%s (memp, src >> 24); %s (memp + 2, src >> 16);\n", dstb, dstb);
1883
                        printf ("\t%s (memp + 4, src >> 8); %s (memp + 6, src);\n", dstb, dstb);
1884
                        count_write += 4;
1885
                }
1886
                fill_prefetch_next ();
1887
                break;
1888
        case i_MVPMR: // MOVEP M->R
1889
                printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
1890
                genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
1891
                if (curi->size == sz_word) {
1892
                        printf ("\tuae_u16 val = (%s (memp) << 8) + %s (memp + 2);\n", srcb, srcb);
1893
                        count_read += 2;
1894
                } else {
1895
                        printf ("\tuae_u32 val = (%s (memp) << 24) + (%s (memp + 2) << 16)\n", srcb, srcb);
1896
                        printf ("              + (%s (memp + 4) << 8) + %s (memp + 6);\n", srcb, srcb);
1897
                        count_read += 4;
1898
                }
1899
                fill_prefetch_next ();
1900
                genastore ("val", curi->dmode, "dstreg", curi->size, "dst");
1901
                break;
1902
        case i_MOVE:
1903
        case i_MOVEA:
1904
                {
1905
                        /* 2 MOVE instructions have special prefetch sequence:
1906
                        * - MOVE <ea>,-(An) = prefetch is before writes (Apdi)
1907
                        * - MOVE memory,(xxx).L, the most stupid ever. 2 prefetches after write
1908
                        * - all others = prefetch is done after writes
1909
                        */
1910
                        int prefetch_done = 0;
1911
                        int dualprefetch = curi->dmode == absl && (curi->smode != Dreg && curi->smode != Areg && curi->smode != imm);
1912
                        genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1913
                        /* MOVE.L dx,(ax) exception3 PC points to next instruction. hackhackhack */
1914
                        //AO extra: 2->3; (Aind ? 2) -> (Aind ? 0)
1915
                        genamode_e3 (curi->dmode, "dstreg", curi->size, "dst", 3, 0, 1 | (dualprefetch ? GF_NOREFILL : 0), curi->smode == Dreg && curi->dmode == Aind ? 0 : 0);
1916
                        genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1917
                        if (curi->mnemo == i_MOVEA && curi->size == sz_word)
1918
                                printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
1919
                        if (curi->dmode == Apdi) {
1920
                                fill_prefetch_next ();
1921
                                prefetch_done = 1;
1922
                        }
1923
                        if (curi->mnemo == i_MOVE)
1924
                                genflags (flag_logical, curi->size, "src", "", "");
1925
                        genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1926
                        sync_m68k_pc ();
1927
                        if (dualprefetch) {
1928
                                fill_prefetch_full ();
1929
                                prefetch_done = 1;
1930
                        }
1931
                        if (!prefetch_done)
1932
                                fill_prefetch_next ();
1933
                }
1934
                break;
1935
        case i_MVSR2: // MOVE FROM SR (like CLR, does dummy read first on 68000)
1936
                //AO extra: (cpu_level == 0 ? 1 : 2) -> 3
1937
                genamode (curi->smode, "srcreg", sz_word, "src", 3, 0, 0);
1938
                if (isreg (curi->smode))
1939
                        addcycles000 (2);
1940
                fill_prefetch_next ();
1941
                printf ("\tMakeSR ();\n");
1942
                if (curi->size == sz_byte)
1943
                        genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src");
1944
                else
1945
                        genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src");
1946
                break;
1947
        case i_MV2SR: // MOVE TO SR
1948
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
1949
                if (curi->size == sz_byte) {
1950
                        addcycles000 (8);
1951
                        printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
1952
                } else {
1953
                        addcycles000 (4);
1954
                        printf ("\tregs.sr = src;\n");
1955
                }
1956
                fill_prefetch_next ();
1957
                printf ("\tMakeFromSR ();\n");
1958
                break;
1959
        case i_SWAP:
1960
                genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
1961
                fill_prefetch_next ();
1962
                start_brace ();
1963
                printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
1964
                genflags (flag_logical, sz_long, "dst", "", "");
1965
                genastore ("dst", curi->smode, "srcreg", sz_long, "src");
1966
                break;
1967
        case i_EXG:
1968
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1969
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1970
                addcycles000 (2);
1971
                fill_prefetch_next ();
1972
                genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1973
                genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1974
                break;
1975
        case i_EXT:
1976
                genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
1977
                fill_prefetch_next ();
1978
                start_brace ();
1979
                switch (curi->size) {
1980
                case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break;
1981
                case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break;
1982
                case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break;
1983
                default: abort ();
1984
                }
1985
                genflags (flag_logical,
1986
                        curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
1987
                genastore ("dst", curi->smode, "srcreg",
1988
                        curi->size == sz_word ? sz_word : sz_long, "src");
1989
                break;
1990
        case i_MVMEL:
1991
                if (using_ce)
1992
                        genmovemel_ce (opcode);
1993
                else
1994
                        genmovemel (opcode);
1995
                break;
1996
        case i_MVMLE:
1997
                if (using_ce)
1998
                        genmovemle_ce (opcode);
1999
                else
2000
                        genmovemle (opcode);
2001
                break;
2002
        case i_TRAP:
2003
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2004
                gen_set_fault_pc ();
2005
                sync_m68k_pc ();
2006
                printf ("\tException (src + 32, 0);\n");
2007
                did_prefetch = 1;
2008
                m68k_pc_offset = 0;
2009
                break;
2010
        case i_MVR2USP:
2011
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2012
                fill_prefetch_next ();
2013
                printf ("\tregs.usp = src;\n");
2014
                break;
2015
        case i_MVUSP2R:
2016
                genamode (curi->smode, "srcreg", curi->size, "src", 2, 0, 0);
2017
                fill_prefetch_next ();
2018
                genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src");
2019
                break;
2020
        case i_RESET:
2021
                fill_prefetch_next ();
2022
                printf ("\tcpureset ();\n");
2023
                addcycles000 (128);
2024
                if (using_prefetch)
2025
                        printf ("\tregs.irc = get_iword (4);\n");
2026
                break;
2027
        case i_NOP:
2028
                fill_prefetch_next ();
2029
                break;
2030
        case i_STOP:
2031
                if (using_prefetch) {
2032
                        printf ("\tregs.sr = regs.irc;\n");
2033
                        m68k_pc_offset += 2;
2034
                } else {
2035
                        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2036
                        printf ("\tregs.sr = src;\n");
2037
                }
2038
                printf ("\tMakeFromSR ();\n");
2039
                printf ("\tm68k_setstopped ();\n");
2040
                sync_m68k_pc ();
2041
                // STOP does not prefetch anything
2042
                did_prefetch = -1;
2043
                break;
2044
        case i_LPSTOP: /* 68060 */
2045
                printf ("\tuae_u16 sw = get_iword (2);\n");
2046
                printf ("\tuae_u16 sr;\n");
2047
                printf ("\tif (sw != (0x100|0x80|0x40)) { Exception (4, 0); goto %s; }\n", endlabelstr);
2048
                printf ("\tsr = get_iword (4);\n");
2049
                printf ("\tif (!(sr & 0x8000)) { Exception (8, 0); goto %s; }\n", endlabelstr);
2050
                printf ("\tregs.sr = sr;\n");
2051
                printf ("\tMakeFromSR ();\n");
2052
                printf ("\tm68k_setstopped();\n");
2053
                m68k_pc_offset += 4;
2054
                sync_m68k_pc ();
2055
                fill_prefetch_full ();
2056
                break;
2057
        case i_RTE:
2058
                if (cpu_level == 0) {
2059
                        genamode (Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
2060
                        genamode (Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
2061
                        printf ("\tregs.sr = sr;\n");
2062
                        //AO extra start
2063
                        printf ("\tMakeFromSR ();\n");
2064
                        printf ("\tif (pc & 1)\n");
2065
                        printf ("\t\texception3i(0x%04X, m68k_getpc () + 2, pc);\n", opcode);
2066
                        printf ("\telse\n");
2067
                        //AO extra end
2068
                        setpc ("pc");
2069
                        //printf ("\tMakeFromSR ();\n");
2070
                } else {
2071
                        int old_brace_level = n_braces;
2072
                        if (next_cpu_level < 0)
2073
                                next_cpu_level = 0;
2074
                        genamode (Aipi, "7", sz_word, "sr", 1, 0, 0);
2075
                        genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
2076
                        genamode (Aipi, "7", sz_word, "format", 1, 0, 0);
2077
                        printf ("\tm68k_do_rte (pc, sr, format, 0x%04x);\n", opcode);
2078
                }
2079
                /* PC is set and prefetch filled. */
2080
                m68k_pc_offset = 0;
2081
                fill_prefetch_full ();
2082
                break;
2083
        case i_RTD:
2084
                if (using_mmu) {
2085
                        genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
2086
                        genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
2087
                        printf ("\tm68k_areg(regs, 7) += offs;\n");
2088
                        setpc ("pc");
2089
                } else {
2090
                        genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
2091
                        genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0);
2092
                        printf ("\tm68k_areg (regs, 7) += offs;\n");
2093
                        printf ("\tif (pc & 1)\n");
2094
                        printf ("\t\texception3 (0x%04X, m68k_getpc (), pc);\n", opcode);
2095
                        printf ("\telse\n");
2096
                        setpc ("pc");
2097
                }
2098
                /* PC is set and prefetch filled. */
2099
                m68k_pc_offset = 0;
2100
                fill_prefetch_full ();
2101
                break;
2102
        case i_LINK:
2103
                if (using_mmu) {
2104
                        genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
2105
                        genamode (Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0);
2106
                        genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
2107
                        genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src");
2108
                        printf ("\tm68k_areg(regs, 7) += offs;\n");
2109
                        genastore ("src", Apdi, "7", sz_long, "old");
2110
                } else {
2111
                        //AO extra: 2->3
2112
                        genamode (Apdi, "7", sz_long, "old", 3, 0, GF_AA);
2113
                        genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA);
2114
                        genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0);
2115
                        genastore ("src", Apdi, "7", sz_long, "old");
2116
                        genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src");
2117
                        printf ("\tm68k_areg (regs, 7) += offs;\n");
2118
                        fill_prefetch_next ();
2119
                }
2120
                break;
2121
        case i_UNLK:
2122
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2123
                printf ("\tm68k_areg (regs, 7) = src;\n");
2124
                genamode (Aipi, "7", sz_long, "old", 1, 0, 0);
2125
                fill_prefetch_next ();
2126
                genastore ("old", curi->smode, "srcreg", curi->size, "src");
2127
                break;
2128
        case i_RTS:
2129
                if (using_ce)
2130
                        printf ("\tm68k_do_rts_ce ();\n");
2131
                else if (using_indirect)
2132
                        printf ("\tm68k_do_rtsi ();\n");
2133
                else if (using_mmu)
2134
                        printf ("\tm68k_do_rts_mmu ();\n");
2135
                else
2136
                        printf ("\tm68k_do_rts ();\n");
2137
                count_read += 2;
2138
                m68k_pc_offset = 0;
2139
                fill_prefetch_full ();
2140
                break;
2141
        case i_TRAPV:
2142
                sync_m68k_pc ();
2143
                //fill_prefetch_next ();
2144
                printf ("\tif (GET_VFLG ()) {\n");
2145
                printf ("\t\tException (7, m68k_getpc ());\n");
2146
                printf ("\t\tgoto %s;\n", endlabelstr);
2147
                printf ("\t}\n");
2148
                //AO extra
2149
                fill_prefetch_next ();
2150
                need_endlabel = 1;
2151
                break;
2152
        case i_RTR:
2153
                printf ("\tMakeSR ();\n");
2154
                genamode_pre (Aipi, "7", sz_word, "sr", 1, 0, 0);
2155
                genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
2156
                genamode_post (Aipi, "7", sz_word, "sr", 1, 0, 0);
2157
                printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
2158
                printf ("\tregs.sr |= sr;\n");
2159
                //AO extra start
2160
                printf ("\tMakeFromSR ();\n");
2161
                printf ("\tif (pc & 1)\n");
2162
                printf ("\t\texception3i(0x%04X, m68k_getpc () + 2, pc);\n", opcode);
2163
                printf ("\telse\n");
2164
                //AO extra end
2165
                setpc ("pc");
2166
                //printf ("\tMakeFromSR ();\n");
2167
                m68k_pc_offset = 0;
2168
                fill_prefetch_full ();
2169
                break;
2170
        case i_JSR: // TODO: check stack write order
2171
                genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
2172
                start_brace ();
2173
                printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset);
2174
                if (using_exception_3) {
2175
                        printf ("\tif (srca & 1) {\n");
2176
                        printf ("\t\texception3i (opcode, oldpc, srca);\n");
2177
                        printf ("\t\tgoto %s;\n", endlabelstr);
2178
                        printf ("\t}\n");
2179
                        need_endlabel = 1;
2180
                }
2181
                if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16)
2182
                        addcycles000 (2);
2183
 
2184
                setpc ("srca");
2185
                m68k_pc_offset = 0;
2186
                fill_prefetch_1 (0);
2187
                if (curi->smode == Ad8r || curi->smode == PC8r)
2188
                        addcycles000 (6);
2189
 
2190
                //AO extra start
2191
                genamode (Apdi, "7", sz_long, "dst", 3, 0, GF_AA);
2192
                genastore ("oldpc", Apdi, "7", sz_long, "dst");
2193
                //AO extra end
2194
 
2195
                //printf ("\tm68k_areg (regs, 7) -= 4;\n");
2196
                //if (using_ce) {
2197
                //      printf ("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n");
2198
                //      printf ("\tput_word_ce (m68k_areg (regs, 7) + 2, oldpc);\n");
2199
                //} else {
2200
                //      printf ("\t%s (m68k_areg (regs, 7), oldpc);\n", dstl);
2201
                //}
2202
                count_write += 2;
2203
                fill_prefetch_next ();
2204
                break;
2205
        case i_JMP:
2206
                genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA | ((curi->smode == Ad8r || curi->smode == PC8r) ? 0 : GF_NOREFILL));
2207
                if (using_exception_3) {
2208
                        printf ("\tif (srca & 1) {\n");
2209
                        //AO extra 6->2
2210
                        printf ("\t\texception3i (opcode, m68k_getpc () + %d, srca);\n", m68k_pc_offset);
2211
                        //printf ("\t\texception3i (opcode, m68k_getpc () + 6, srca);\n");
2212
                        printf ("\t\tgoto %s;\n", endlabelstr);
2213
                        printf ("\t}\n");
2214
                        need_endlabel = 1;
2215
                }
2216
                if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r)
2217
                        addcycles000 (2);
2218
                setpc ("srca");
2219
                m68k_pc_offset = 0;
2220
                fill_prefetch_full ();
2221
                break;
2222
        case i_BSR:
2223
                //AO extra
2224
                if(curi->size == sz_long) {
2225
                        printf ("\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n");
2226
                        printf ("\t\tgoto %s;\n", endlabelstr);
2227
                        need_endlabel = 1;
2228
                        break;
2229
                }
2230
                //AO extra end
2231
                printf ("\tuae_s32 s;\n");
2232
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL);
2233
                printf ("\ts = (uae_s32)src + 2;\n");
2234
                if (using_exception_3) {
2235
                        printf ("\tif (src & 1) {\n");
2236
                        //AO extra
2237
                        printf ("\t\texception3i (opcode, m68k_getpc () + %d, m68k_getpc () + s);\n", m68k_pc_offset);
2238
                        //printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + s);\n");
2239
                        printf ("\t\tgoto %s;\n", endlabelstr);
2240
                        printf ("\t}\n");
2241
                        need_endlabel = 1;
2242
                }
2243
                addcycles000 (2);
2244
                if (using_ce) {
2245
                        printf ("\tm68k_do_bsr_ce (m68k_getpc () + %d, s);\n", m68k_pc_offset);
2246
                } else if (using_indirect) {
2247
                        printf ("\tm68k_do_bsri (m68k_getpc () + %d, s);\n", m68k_pc_offset);
2248
                } else if (using_mmu) {
2249
                        printf ("\tm68k_do_bsr_mmu (m68k_getpc () + %d, s);\n", m68k_pc_offset);
2250
                } else {
2251
                        printf ("\tm68k_do_bsr (m68k_getpc () + %d, s, opcode);\n", m68k_pc_offset);
2252
                }
2253
                count_write += 2;
2254
                m68k_pc_offset = 0;
2255
                fill_prefetch_full ();
2256
                break;
2257
        case i_Bcc:
2258
                if (curi->size == sz_long) {
2259
                        if (cpu_level < 2) {
2260
                                addcycles000 (2);
2261
                                printf ("\tif (cctrue (%d)) {\n", curi->cc);
2262
                                printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n");
2263
                                printf ("\t\tgoto %s;\n", endlabelstr);
2264
                                printf ("\t}\n");
2265
                                sync_m68k_pc ();
2266
                                irc2ir ();
2267
                                fill_prefetch_2 ();
2268
                                printf ("\tgoto %s;\n", endlabelstr);
2269
                                need_endlabel = 1;
2270
                        } else {
2271
                                if (next_cpu_level < 1)
2272
                                        next_cpu_level = 1;
2273
                        }
2274
                }
2275
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
2276
                addcycles000 (2);
2277
                printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc);
2278
                if (using_exception_3) {
2279
                        printf ("\tif (src & 1) {\n");
2280
                        //AO extra
2281
                        printf ("\t\texception3i (opcode, m68k_getpc () + %d, m68k_getpc () + 2 + (uae_s32)src);\n", m68k_pc_offset);
2282
                        //printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)src);\n");
2283
                        printf ("\t\tgoto %s;\n", endlabelstr);
2284
                        printf ("\t}\n");
2285
                        need_endlabel = 1;
2286
                }
2287
                if (using_prefetch) {
2288
                        incpc ("(uae_s32)src + 2");
2289
                        fill_prefetch_full ();
2290
                        if (using_ce)
2291
                                printf ("\treturn;\n");
2292
                        else
2293
                                printf ("\treturn 10 * CYCLE_UNIT / 2;\n");
2294
                } else {
2295
                        incpc ("(uae_s32)src + 2");
2296
                        returncycles ("\t", 10);
2297
                }
2298
                printf ("didnt_jump:;\n");
2299
                need_endlabel = 1;
2300
                sync_m68k_pc ();
2301
                if (curi->size == sz_byte) {
2302
                        addcycles000 (2);
2303
                        irc2ir ();
2304
                        fill_prefetch_2 ();
2305
                } else if (curi->size == sz_word) {
2306
                        addcycles000 (2);
2307
                        fill_prefetch_full ();
2308
                } else {
2309
                        fill_prefetch_full ();
2310
                }
2311
                insn_n_cycles = curi->size == sz_byte ? 8 : 12;
2312
                break;
2313
        case i_LEA:
2314
                genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
2315
                genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
2316
                if (curi->smode == Ad8r || curi->smode == PC8r)
2317
                        addcycles000 (2);
2318
                fill_prefetch_next ();
2319
                if (curi->smode == Ad8r || curi->smode == PC8r)
2320
                        addcycles000 (2);
2321
                genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
2322
                break;
2323
        case i_PEA:
2324
                genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
2325
                //AO extra: 3
2326
                genamode (Apdi, "7", sz_long, "dst", 3, 0, GF_AA);
2327
                if (curi->smode == Ad8r || curi->smode == PC8r)
2328
                        addcycles000 (2);
2329
                if (!(curi->smode == absw || curi->smode == absl))
2330
                        fill_prefetch_next ();
2331
                if (curi->smode == Ad8r || curi->smode == PC8r)
2332
                        addcycles000 (2);
2333
                genastore ("srca", Apdi, "7", sz_long, "dst");
2334
                if ((curi->smode == absw || curi->smode == absl))
2335
                        fill_prefetch_next ();
2336
                break;
2337
        case i_DBcc:
2338
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
2339
                genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL);
2340
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
2341
                addcycles000 (2);
2342
                printf ("\tif (!cctrue (%d)) {\n", curi->cc);
2343
                incpc ("(uae_s32)offs + 2");
2344
                //AO extra: comment out
2345
                //printf ("\t"); fill_prefetch_1 (0);
2346
                printf ("\t"); genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src");
2347
 
2348
                printf ("\t\tif (src) {\n");
2349
                addcycles_ce020 (4);
2350
                if (using_exception_3) {
2351
                        printf ("\t\t\tif (offs & 1) {\n");
2352
                        //AO extra: (m68k_getpc () + 2 + (uae_s32)offs + 2) -> m68k_getpc (); (m68k_getpc () + 2) -> oldpc
2353
                        printf ("\t\t\t\texception3i (opcode, oldpc + 2, m68k_getpc ());\n");
2354
                        printf ("\t\t\t\tgoto %s;\n", endlabelstr);
2355
                        printf ("\t\t\t}\n");
2356
                        need_endlabel = 1;
2357
                }
2358
                irc2ir ();
2359
                fill_prefetch_1 (2);
2360
                returncycles ("\t\t\t", 12);
2361
                if (using_ce)
2362
                        printf ("\t\t\treturn;\n");
2363
                printf ("\t\t}\n");
2364
                addcycles_ce020 (8);
2365
                printf ("\t} else {\n");
2366
                addcycles000_2 ("\t\t", 2);
2367
                addcycles_ce020 (4);
2368
                printf ("\t}\n");
2369
                setpc ("oldpc + %d", m68k_pc_offset);
2370
                m68k_pc_offset = 0;
2371
                fill_prefetch_full ();
2372
                insn_n_cycles = 12;
2373
                need_endlabel = 1;
2374
                break;
2375
        case i_Scc:
2376
                genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
2377
                start_brace ();
2378
                fill_prefetch_next();
2379
                start_brace ();
2380
                printf ("\tint val = cctrue (%d) ? 0xff : 0;\n", curi->cc);
2381
                if (using_ce) {
2382
                        printf ("\tint cycles = 0;\n");
2383
                        if (isreg (curi->smode))
2384
                                printf ("\tif (val) cycles += 2;\n");
2385
                        addcycles000_3 ("\t");
2386
                }
2387
                genastore ("val", curi->smode, "srcreg", curi->size, "src");
2388
                break;
2389
        case i_DIVU:
2390
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
2391
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
2392
                genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
2393
                printf ("\tCLEAR_CZNV ();\n");
2394
                printf ("\tif (src == 0) {\n");
2395
                if (cpu_level > 0) {
2396
                        /* 68020 sets V when dividing by zero and N if dst is negative
2397
                        * 68000 clears both
2398
                        */
2399
                        printf("\t\tSET_VFLG (1);\n");
2400
                        printf("\t\tif (dst < 0) SET_NFLG (1);\n");
2401
                }
2402
                incpc ("%d", m68k_pc_offset);
2403
                printf ("\t\tException (5, oldpc);\n");
2404
                printf ("\t\tgoto %s;\n", endlabelstr);
2405
                printf ("\t} else {\n");
2406
                printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
2407
                printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n");
2408
                fill_prefetch_next ();
2409
                if (using_ce) {
2410
                        start_brace ();
2411
                        printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src));\n");
2412
                        addcycles000_3 ("\t\t");
2413
                } else if (using_ce020) {
2414
                        addcycles_ce020 (36);
2415
                }
2416
                /* The N flag appears to be set each time there is an overflow.
2417
                * Weird. but 68020 only sets N when dst is negative.. */
2418
                printf ("\t\tif (newv > 0xffff) {\n");
2419
                printf ("\t\t\tSET_VFLG (1);\n");
2420
#ifdef UNDEF68020
2421
                if (cpu_level >= 2)
2422
                        printf ("\t\t\tif (currprefs.cpu_level == 0 || dst < 0) SET_NFLG (&regs, 1);\n");
2423
                else /* ??? some 68000 revisions may not set NFLG when overflow happens.. */
2424
#endif
2425
                        printf ("\t\t\tSET_NFLG (1);\n");
2426
                printf ("\t\t} else {\n");
2427
                printf ("\t\t"); genflags (flag_logical, sz_word, "newv", "", "");
2428
                printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
2429
                printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
2430
                printf ("\t\t}\n");
2431
                sync_m68k_pc ();
2432
                printf ("\t}\n");
2433
                count_ncycles++;
2434
                insn_n_cycles += 136 - (136 - 76) / 2; /* average */
2435
                need_endlabel = 1;
2436
                break;
2437
        case i_DIVS:
2438
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
2439
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
2440
                genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
2441
                printf ("\tCLEAR_CZNV ();\n");
2442
                printf ("\tif (src == 0) {\n");
2443
                if (cpu_level > 0) {
2444
                        /* 68020 sets V when dividing by zero. Z is also set.
2445
                        * 68000 clears both
2446
                        */
2447
                        printf("\t\tSET_VFLG (1);\n");
2448
                        printf("\t\tSET_ZFLG (1);\n");
2449
                }
2450
                incpc ("%d", m68k_pc_offset);
2451
                printf ("\t\tException (5, oldpc);\n");
2452
                printf ("\t\tgoto %s;\n", endlabelstr);
2453
                printf ("\t} else {\n");
2454
                printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
2455
                printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
2456
                fill_prefetch_next ();
2457
                if (using_ce) {
2458
                        start_brace ();
2459
                        printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src));\n");
2460
                        addcycles000_3 ("\t\t");
2461
                } else if (using_ce020) {
2462
                        addcycles_ce020 (46);
2463
                }
2464
                printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n");
2465
                printf ("\t\t\tSET_VFLG (1);\n");
2466
#ifdef UNDEF68020
2467
                if (cpu_level > 0)
2468
                        printf ("\t\t\tif (currprefs.cpu_level == 0) SET_NFLG (&regs, 1);\n");
2469
                else
2470
#endif
2471
                        printf ("\t\t\tSET_NFLG (1);\n");
2472
                printf ("\t\t} else {\n");
2473
                printf ("\t\t\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n");
2474
                genflags (flag_logical, sz_word, "newv", "", "");
2475
                printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
2476
                printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
2477
                printf ("\t\t}\n");
2478
                sync_m68k_pc ();
2479
                printf ("\t}\n");
2480
                count_ncycles++;
2481
                insn_n_cycles += 156 - (156 - 120) / 2; /* average */
2482
                need_endlabel = 1;
2483
                break;
2484
        case i_MULU:
2485
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
2486
                genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0);
2487
                fill_prefetch_next();
2488
                start_brace ();
2489
                printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
2490
                if (using_ce)
2491
                        printf ("\tint cycles = 38 - 4, bits;\n");
2492
                genflags (flag_logical, sz_long, "newv", "", "");
2493
                if (using_ce) {
2494
                        printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n");
2495
                        printf ("\t\tif (src & 1) cycles += 2;\n");
2496
                        addcycles000_3 ("\t");
2497
                } else if (using_ce020) {
2498
                        addcycles_ce020 (20);
2499
                }
2500
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
2501
                sync_m68k_pc ();
2502
                count_cycles += 38 - 4;
2503
                count_ncycles++;
2504
                insn_n_cycles += (70 - 38) / 2 + 38; /* average */
2505
                break;
2506
        case i_MULS:
2507
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
2508
                genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0);
2509
                fill_prefetch_next();
2510
                start_brace ();
2511
                printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
2512
                if (using_ce) {
2513
                        printf ("\tint cycles = 38 - 4, bits;\n");
2514
                        printf ("\tuae_u32 usrc;\n");
2515
                }
2516
                genflags (flag_logical, sz_long, "newv", "", "");
2517
                if (using_ce) {
2518
                        printf ("\tusrc = ((uae_u32)src) << 1;\n");
2519
                        printf ("\tfor(bits = 0; bits < 16 && usrc; bits++, usrc >>= 1)\n");
2520
                        printf ("\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) cycles += 2;\n");
2521
                        addcycles000_3 ("\t");
2522
                } else if (using_ce020) {
2523
                        addcycles_ce020 (20);
2524
                }
2525
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
2526
                count_cycles += 38 - 4;
2527
                count_ncycles++;
2528
                insn_n_cycles += (70 - 38) / 2 + 38; /* average */
2529
                break;
2530
        case i_CHK:
2531
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
2532
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2533
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
2534
                sync_m68k_pc ();
2535
                addcycles000 (4);
2536
                printf ("\tif (dst > src) {\n");
2537
                printf ("\t\tSET_NFLG (0);\n");
2538
                printf ("\t\tException (6, oldpc);\n");
2539
                printf ("\t\tgoto %s;\n", endlabelstr);
2540
                printf ("\t}\n");
2541
                addcycles000 (2);
2542
                printf ("\tif ((uae_s32)dst < 0) {\n");
2543
                printf ("\t\tSET_NFLG (1);\n");
2544
                printf ("\t\tException (6, oldpc);\n");
2545
                printf ("\t\tgoto %s;\n", endlabelstr);
2546
                printf ("\t}\n");
2547
                fill_prefetch_next ();
2548
                need_endlabel = 1;
2549
                break;
2550
        case i_CHK2:
2551
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
2552
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
2553
                genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
2554
                fill_prefetch_0 ();
2555
                printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
2556
                switch (curi->size) {
2557
                case sz_byte:
2558
                        printf ("\tlower = (uae_s32)(uae_s8)%s (dsta); upper = (uae_s32)(uae_s8)%s (dsta + 1);\n", srcb, srcb);
2559
                        printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n");
2560
                        break;
2561
                case sz_word:
2562
                        printf ("\tlower = (uae_s32)(uae_s16)%s (dsta); upper = (uae_s32)(uae_s16)%s (dsta + 2);\n", srcw, srcw);
2563
                        printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n");
2564
                        break;
2565
                case sz_long:
2566
                        printf ("\tlower = %s (dsta); upper = %s (dsta + 4);\n", srcl, srcl);
2567
                        break;
2568
                default:
2569
                        abort ();
2570
                }
2571
                printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
2572
                printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
2573
                printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6, oldpc); goto %s; }\n}\n", endlabelstr);
2574
                need_endlabel = 1;
2575
                break;
2576
 
2577
        case i_ASR:
2578
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2579
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2580
                fill_prefetch_next();
2581
                start_brace ();
2582
                switch (curi->size) {
2583
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2584
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2585
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2586
                default: abort ();
2587
                }
2588
                printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1);
2589
                printf ("\tint ccnt = cnt & 63;\n");
2590
                printf ("\tcnt &= 63;\n");
2591
                printf ("\tCLEAR_CZNV ();\n");
2592
                printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
2593
                printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size));
2594
                printf ("\t\tSET_CFLG (sign);\n");
2595
                duplicate_carry (1);
2596
                if (source_is_imm1_8 (curi))
2597
                        printf ("\t} else {\n");
2598
                else
2599
                        printf ("\t} else if (cnt > 0) {\n");
2600
                printf ("\t\tval >>= cnt - 1;\n");
2601
                printf ("\t\tSET_CFLG (val & 1);\n");
2602
                duplicate_carry (1);
2603
                printf ("\t\tval >>= 1;\n");
2604
                printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n",
2605
                        bit_mask (curi->size),
2606
                        bit_size (curi->size));
2607
                printf ("\t\tval &= %s;\n", bit_mask (curi->size));
2608
                printf ("\t}\n");
2609
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2610
                shift_ce (curi->dmode, curi->size);
2611
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2612
                break;
2613
        case i_ASL:
2614
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2615
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2616
                fill_prefetch_next();
2617
                start_brace ();
2618
                switch (curi->size) {
2619
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2620
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2621
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2622
                default: abort ();
2623
                }
2624
                printf ("\tint ccnt = cnt & 63;\n");
2625
                printf ("\tcnt &= 63;\n");
2626
                printf ("\tCLEAR_CZNV ();\n");
2627
                printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
2628
                printf ("\t\tSET_VFLG (val != 0);\n");
2629
                printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
2630
                        bit_size (curi->size));
2631
                duplicate_carry (1);
2632
                printf ("\t\tval = 0;\n");
2633
                if (source_is_imm1_8 (curi))
2634
                        printf ("\t} else {\n");
2635
                else
2636
                        printf ("\t} else if (cnt > 0) {\n");
2637
                printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n",
2638
                        bit_mask (curi->size),
2639
                        bit_size (curi->size) - 1,
2640
                        bit_mask (curi->size));
2641
                printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n");
2642
                printf ("\t\tval <<= cnt - 1;\n");
2643
                printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
2644
                duplicate_carry (1);
2645
                printf ("\t\tval <<= 1;\n");
2646
                printf ("\t\tval &= %s;\n", bit_mask (curi->size));
2647
                printf ("\t}\n");
2648
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2649
                shift_ce (curi->dmode, curi->size);
2650
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2651
                break;
2652
        case i_LSR:
2653
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2654
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2655
                fill_prefetch_next();
2656
                start_brace ();
2657
                switch (curi->size) {
2658
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2659
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2660
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2661
                default: abort ();
2662
                }
2663
                printf ("\tint ccnt = cnt & 63;\n");
2664
                printf ("\tcnt &= 63;\n");
2665
                printf ("\tCLEAR_CZNV ();\n");
2666
                printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
2667
                printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n",
2668
                        bit_size (curi->size), bit_size (curi->size) - 1);
2669
                duplicate_carry (1);
2670
                printf ("\t\tval = 0;\n");
2671
                if (source_is_imm1_8 (curi))
2672
                        printf ("\t} else {\n");
2673
                else
2674
                        printf ("\t} else if (cnt > 0) {\n");
2675
                printf ("\t\tval >>= cnt - 1;\n");
2676
                printf ("\t\tSET_CFLG (val & 1);\n");
2677
                duplicate_carry (1);
2678
                printf ("\t\tval >>= 1;\n");
2679
                printf ("\t}\n");
2680
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2681
                shift_ce (curi->dmode, curi->size);
2682
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2683
                break;
2684
        case i_LSL:
2685
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2686
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2687
                fill_prefetch_next();
2688
                start_brace ();
2689
                switch (curi->size) {
2690
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2691
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2692
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2693
                default: abort ();
2694
                }
2695
                printf ("\tint ccnt = cnt & 63;\n");
2696
                printf ("\tcnt &= 63;\n");
2697
                printf ("\tCLEAR_CZNV ();\n");
2698
                printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
2699
                printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size (curi->size));
2700
                duplicate_carry (1);
2701
                printf ("\t\tval = 0;\n");
2702
                if (source_is_imm1_8 (curi))
2703
                        printf ("\t} else {\n");
2704
                else
2705
                        printf ("\t} else if (cnt > 0) {\n");
2706
                printf ("\t\tval <<= (cnt - 1);\n");
2707
                printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
2708
                duplicate_carry (1);
2709
                printf ("\t\tval <<= 1;\n");
2710
                printf ("\tval &= %s;\n", bit_mask (curi->size));
2711
                printf ("\t}\n");
2712
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2713
                shift_ce (curi->dmode, curi->size);
2714
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2715
                break;
2716
        case i_ROL:
2717
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2718
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2719
                fill_prefetch_next ();
2720
                start_brace ();
2721
                switch (curi->size) {
2722
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2723
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2724
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2725
                default: abort ();
2726
                }
2727
                printf ("\tint ccnt = cnt & 63;\n");
2728
                printf ("\tcnt &= 63;\n");
2729
                printf ("\tCLEAR_CZNV ();\n");
2730
                if (source_is_imm1_8 (curi))
2731
                        printf ("{");
2732
                else
2733
                        printf ("\tif (cnt > 0) {\n");
2734
                printf ("\tuae_u32 loval;\n");
2735
                printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
2736
                printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size));
2737
                printf ("\tval <<= cnt;\n");
2738
                printf ("\tval |= loval;\n");
2739
                printf ("\tval &= %s;\n", bit_mask (curi->size));
2740
                printf ("\tSET_CFLG (val & 1);\n");
2741
                printf ("}\n");
2742
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2743
                shift_ce (curi->dmode, curi->size);
2744
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2745
                break;
2746
        case i_ROR:
2747
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2748
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2749
                fill_prefetch_next ();
2750
                start_brace ();
2751
                switch (curi->size) {
2752
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2753
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2754
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2755
                default: abort ();
2756
                }
2757
                printf ("\tint ccnt = cnt & 63;\n");
2758
                printf ("\tcnt &= 63;\n");
2759
                printf ("\tCLEAR_CZNV ();\n");
2760
                if (source_is_imm1_8 (curi))
2761
                        printf ("{");
2762
                else
2763
                        printf ("\tif (cnt > 0) {");
2764
                printf ("\tuae_u32 hival;\n");
2765
                printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
2766
                printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size));
2767
                printf ("\tval >>= cnt;\n");
2768
                printf ("\tval |= hival;\n");
2769
                printf ("\tval &= %s;\n", bit_mask (curi->size));
2770
                printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
2771
                printf ("\t}\n");
2772
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2773
                shift_ce (curi->dmode, curi->size);
2774
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2775
                break;
2776
        case i_ROXL:
2777
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2778
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2779
                fill_prefetch_next ();
2780
                start_brace ();
2781
                switch (curi->size) {
2782
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2783
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2784
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2785
                default: abort ();
2786
                }
2787
                printf ("\tint ccnt = cnt & 63;\n");
2788
                printf ("\tcnt &= 63;\n");
2789
                printf ("\tCLEAR_CZNV ();\n");
2790
                if (source_is_imm1_8 (curi))
2791
                        printf ("{");
2792
                else {
2793
                        force_range_for_rox ("cnt", curi->size);
2794
                        printf ("\tif (cnt > 0) {\n");
2795
                }
2796
                printf ("\tcnt--;\n");
2797
                printf ("\t{\n\tuae_u32 carry;\n");
2798
                printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1);
2799
                printf ("\tcarry = loval & 1;\n");
2800
                printf ("\tval = (((val << 1) | GET_XFLG ()) << cnt) | (loval >> 1);\n");
2801
                printf ("\tSET_XFLG (carry);\n");
2802
                printf ("\tval &= %s;\n", bit_mask (curi->size));
2803
                printf ("\t} }\n");
2804
                printf ("\tSET_CFLG (GET_XFLG ());\n");
2805
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2806
                shift_ce (curi->dmode, curi->size);
2807
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2808
                break;
2809
        case i_ROXR:
2810
                genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2811
                genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
2812
                fill_prefetch_next ();
2813
                start_brace ();
2814
                switch (curi->size) {
2815
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2816
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2817
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2818
                default: abort ();
2819
                }
2820
                printf ("\tint ccnt = cnt & 63;\n");
2821
                printf ("\tcnt &= 63;\n");
2822
                printf ("\tCLEAR_CZNV ();\n");
2823
                if (source_is_imm1_8 (curi))
2824
                        printf ("{");
2825
                else {
2826
                        force_range_for_rox ("cnt", curi->size);
2827
                        printf ("\tif (cnt > 0) {\n");
2828
                }
2829
                printf ("\tcnt--;\n");
2830
                printf ("\t{\n\tuae_u32 carry;\n");
2831
                printf ("\tuae_u32 hival = (val << 1) | GET_XFLG ();\n");
2832
                printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1);
2833
                printf ("\tval >>= cnt;\n");
2834
                printf ("\tcarry = val & 1;\n");
2835
                printf ("\tval >>= 1;\n");
2836
                printf ("\tval |= hival;\n");
2837
                printf ("\tSET_XFLG (carry);\n");
2838
                printf ("\tval &= %s;\n", bit_mask (curi->size));
2839
                printf ("\t} }\n");
2840
                printf ("\tSET_CFLG (GET_XFLG ());\n");
2841
                genflags (flag_logical_noclobber, curi->size, "val", "", "");
2842
                shift_ce (curi->dmode, curi->size);
2843
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
2844
                break;
2845
        case i_ASRW:
2846
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2847
                fill_prefetch_next ();
2848
                start_brace ();
2849
                switch (curi->size) {
2850
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2851
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2852
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2853
                default: abort ();
2854
                }
2855
                printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
2856
                printf ("\tuae_u32 cflg = val & 1;\n");
2857
                printf ("\tval = (val >> 1) | sign;\n");
2858
                genflags (flag_logical, curi->size, "val", "", "");
2859
                printf ("\tSET_CFLG (cflg);\n");
2860
                duplicate_carry (0);
2861
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2862
                break;
2863
        case i_ASLW:
2864
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2865
                fill_prefetch_next ();
2866
                start_brace ();
2867
                switch (curi->size) {
2868
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2869
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2870
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2871
                default: abort ();
2872
                }
2873
                printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
2874
                printf ("\tuae_u32 sign2;\n");
2875
                printf ("\tval <<= 1;\n");
2876
                genflags (flag_logical, curi->size, "val", "", "");
2877
                printf ("\tsign2 = %s & val;\n", cmask (curi->size));
2878
                printf ("\tSET_CFLG (sign != 0);\n");
2879
                duplicate_carry (0);
2880
 
2881
                printf ("\tSET_VFLG (GET_VFLG () | (sign2 != sign));\n");
2882
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2883
                break;
2884
        case i_LSRW:
2885
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2886
                fill_prefetch_next ();
2887
                start_brace ();
2888
                switch (curi->size) {
2889
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2890
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2891
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2892
                default: abort ();
2893
                }
2894
                printf ("\tuae_u32 carry = val & 1;\n");
2895
                printf ("\tval >>= 1;\n");
2896
                genflags (flag_logical, curi->size, "val", "", "");
2897
                printf ("\tSET_CFLG (carry);\n");
2898
                duplicate_carry (0);
2899
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2900
                break;
2901
        case i_LSLW:
2902
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2903
                fill_prefetch_next ();
2904
                start_brace ();
2905
                switch (curi->size) {
2906
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2907
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2908
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2909
                default: abort ();
2910
                }
2911
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
2912
                printf ("\tval <<= 1;\n");
2913
                genflags (flag_logical, curi->size, "val", "", "");
2914
                printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2915
                duplicate_carry (0);
2916
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2917
                break;
2918
        case i_ROLW:
2919
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2920
                fill_prefetch_next ();
2921
                start_brace ();
2922
                switch (curi->size) {
2923
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2924
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2925
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2926
                default: abort ();
2927
                }
2928
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
2929
                printf ("\tval <<= 1;\n");
2930
                printf ("\tif (carry)  val |= 1;\n");
2931
                genflags (flag_logical, curi->size, "val", "", "");
2932
                printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2933
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2934
                break;
2935
        case i_RORW:
2936
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2937
                fill_prefetch_next ();
2938
                start_brace ();
2939
                switch (curi->size) {
2940
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2941
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2942
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2943
                default: abort ();
2944
                }
2945
                printf ("\tuae_u32 carry = val & 1;\n");
2946
                printf ("\tval >>= 1;\n");
2947
                printf ("\tif (carry) val |= %s;\n", cmask (curi->size));
2948
                genflags (flag_logical, curi->size, "val", "", "");
2949
                printf ("\tSET_CFLG (carry);\n");
2950
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2951
                break;
2952
        case i_ROXLW:
2953
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2954
                fill_prefetch_next ();
2955
                start_brace ();
2956
                switch (curi->size) {
2957
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2958
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2959
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2960
                default: abort ();
2961
                }
2962
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
2963
                printf ("\tval <<= 1;\n");
2964
                printf ("\tif (GET_XFLG ()) val |= 1;\n");
2965
                genflags (flag_logical, curi->size, "val", "", "");
2966
                printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2967
                duplicate_carry (0);
2968
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2969
                break;
2970
        case i_ROXRW:
2971
                genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2972
                fill_prefetch_next ();
2973
                start_brace ();
2974
                switch (curi->size) {
2975
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2976
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2977
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2978
                default: abort ();
2979
                }
2980
                printf ("\tuae_u32 carry = val & 1;\n");
2981
                printf ("\tval >>= 1;\n");
2982
                printf ("\tif (GET_XFLG ()) val |= %s;\n", cmask (curi->size));
2983
                genflags (flag_logical, curi->size, "val", "", "");
2984
                printf ("\tSET_CFLG (carry);\n");
2985
                duplicate_carry (0);
2986
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
2987
                break;
2988
        case i_MOVEC2:
2989
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2990
                fill_prefetch_next ();
2991
                start_brace ();
2992
                printf ("\tint regno = (src >> 12) & 15;\n");
2993
                printf ("\tuae_u32 *regp = regs.regs + regno;\n");
2994
                printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
2995
                break;
2996
        case i_MOVE2C:
2997
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2998
                fill_prefetch_next ();
2999
                start_brace ();
3000
                printf ("\tint regno = (src >> 12) & 15;\n");
3001
                printf ("\tuae_u32 *regp = regs.regs + regno;\n");
3002
                printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
3003
                break;
3004
        case i_CAS:
3005
                {
3006
                        int old_brace_level;
3007
                        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3008
                        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
3009
                        fill_prefetch_0 ();
3010
                        start_brace ();
3011
                        printf ("\tint ru = (src >> 6) & 7;\n");
3012
                        printf ("\tint rc = src & 7;\n");
3013
                        genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, rc)", "dst");
3014
                        printf ("\tif (GET_ZFLG ())");
3015
                        old_brace_level = n_braces;
3016
                        start_brace ();
3017
                        genastore ("(m68k_dreg (regs, ru))", curi->dmode, "dstreg", curi->size, "dst");
3018
                        pop_braces (old_brace_level);
3019
                        printf ("else");
3020
                        start_brace ();
3021
                        printf ("m68k_dreg (regs, rc) = dst;\n");
3022
                        pop_braces (old_brace_level);
3023
                }
3024
                break;
3025
        case i_CAS2:
3026
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3027
                printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n");
3028
                printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n");
3029
                if (curi->size == sz_word) {
3030
                        int old_brace_level = n_braces;
3031
                        printf ("\tuae_u16 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcw, srcw);
3032
                        genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1");
3033
                        printf ("\tif (GET_ZFLG ()) {\n");
3034
                        genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2");
3035
                        printf ("\tif (GET_ZFLG ()) {\n");
3036
                        printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstw);
3037
                        printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n", dstw);
3038
                        printf ("\t}}\n");
3039
                        pop_braces (old_brace_level);
3040
                        printf ("\tif (! GET_ZFLG ()) {\n");
3041
                        printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = (m68k_dreg (regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
3042
                        printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = (m68k_dreg (regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
3043
                        printf ("\t}\n");
3044
                } else {
3045
                        int old_brace_level = n_braces;
3046
                        printf ("\tuae_u32 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcl, srcl);
3047
                        genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1");
3048
                        printf ("\tif (GET_ZFLG ()) {\n");
3049
                        genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2");
3050
                        printf ("\tif (GET_ZFLG ()) {\n");
3051
                        printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstl);
3052
                        printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n", dstl);
3053
                        printf ("\t}}\n");
3054
                        pop_braces (old_brace_level);
3055
                        printf ("\tif (! GET_ZFLG ()) {\n");
3056
                        printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = dst1;\n");
3057
                        printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = dst2;\n");
3058
                        printf ("\t}\n");
3059
                }
3060
                break;
3061
        case i_MOVES: /* ignore DFC and SFC when using_mmu == false */
3062
                {
3063
                        int old_brace_level;
3064
                        genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3065
                        printf ("\tif (extra & 0x800)\n");
3066
                        {
3067
                                int old_m68k_pc_offset = m68k_pc_offset;
3068
                                old_brace_level = n_braces;
3069
                                start_brace ();
3070
                                printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
3071
                                genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
3072
                                genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst");
3073
                                pop_braces (old_brace_level);
3074
                                m68k_pc_offset = old_m68k_pc_offset;
3075
                        }
3076
                        printf ("else");
3077
                        {
3078
                                start_brace ();
3079
                                genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0, GF_FC);
3080
                                printf ("\tif (extra & 0x8000) {\n");
3081
                                switch (curi->size) {
3082
                                case sz_byte: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break;
3083
                                case sz_word: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break;
3084
                                case sz_long: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = src;\n"); break;
3085
                                default: abort ();
3086
                                }
3087
                                printf ("\t} else {\n");
3088
                                genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, "");
3089
                                printf ("\t}\n");
3090
                                sync_m68k_pc ();
3091
                                pop_braces (old_brace_level);
3092
                        }
3093
                }
3094
                break;
3095
        case i_BKPT:            /* only needed for hardware emulators */
3096
                sync_m68k_pc ();
3097
                printf ("\top_illg (opcode);\n");
3098
                break;
3099
        case i_CALLM:           /* not present in 68030 */
3100
                sync_m68k_pc ();
3101
                printf ("\top_illg (opcode);\n");
3102
                break;
3103
        case i_RTM:             /* not present in 68030 */
3104
                sync_m68k_pc ();
3105
                printf ("\top_illg (opcode);\n");
3106
                break;
3107
        case i_TRAPcc:
3108
                if (curi->smode != am_unknown && curi->smode != am_illg)
3109
                        genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
3110
                fill_prefetch_0 ();
3111
                printf ("\tif (cctrue (%d)) { Exception (7, m68k_getpc ()); goto %s; }\n", curi->cc, endlabelstr);
3112
                need_endlabel = 1;
3113
                break;
3114
        case i_DIVL:
3115
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
3116
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3117
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
3118
                if (using_ce020) {
3119
                        addcycles_ce020 (70);
3120
                }
3121
                sync_m68k_pc ();
3122
                printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n");
3123
                break;
3124
        case i_MULL:
3125
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3126
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
3127
                if (using_ce020) {
3128
                        addcycles_ce020 (40);
3129
                }
3130
                sync_m68k_pc ();
3131
                printf ("\tm68k_mull(opcode, dst, extra);\n");
3132
                break;
3133
        case i_BFTST:
3134
        case i_BFEXTU:
3135
        case i_BFCHG:
3136
        case i_BFEXTS:
3137
        case i_BFCLR:
3138
        case i_BFFFO:
3139
        case i_BFSET:
3140
        case i_BFINS:
3141
                {
3142
                        char *getb, *putb;
3143
 
3144
                        if (using_mmu) {
3145
                                getb = "get_bitfield_040mmu";
3146
                                putb = "put_bitfield_040mmu";
3147
                        } else if (using_ce020) {
3148
                                getb = "get_bitfield_020ce";
3149
                                putb = "put_bitfield_020ce";
3150
                        } else {
3151
                                getb = "get_bitfield";
3152
                                putb = "put_bitfield";
3153
                        }
3154
 
3155
                        genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3156
                        genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0);
3157
                        start_brace ();
3158
                        printf ("\tuae_u32 bdata[2];\n");
3159
                        printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n");
3160
                        printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n");
3161
                        if (curi->dmode == Dreg) {
3162
                                printf ("\tuae_u32 tmp = m68k_dreg(regs, dstreg);\n");
3163
                                printf ("\toffset &= 0x1f;\n");
3164
                                printf ("\ttmp = (tmp << offset) | (tmp >> (32 - offset));\n");
3165
                                printf ("\tbdata[0] = tmp & ((1 << (32 - width)) - 1);\n");
3166
                        } else {
3167
                                printf ("\tuae_u32 tmp;\n");
3168
                                printf ("\tdsta += offset >> 3;\n");
3169
                                printf ("\ttmp = %s (dsta, bdata, offset, width);\n", getb);
3170
                        }
3171
                        printf ("\tSET_NFLG_ALWAYS (((uae_s32)tmp) < 0 ? 1 : 0);\n");
3172
                        if (curi->mnemo == i_BFEXTS)
3173
                                printf ("\ttmp = (uae_s32)tmp >> (32 - width);\n");
3174
                        else
3175
                                printf ("\ttmp >>= (32 - width);\n");
3176
                        printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n");
3177
                        switch (curi->mnemo) {
3178
                        case i_BFTST:
3179
                                break;
3180
                        case i_BFEXTU:
3181
                        case i_BFEXTS:
3182
                                printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = tmp;\n");
3183
                                break;
3184
                        case i_BFCHG:
3185
                                printf ("\ttmp = tmp ^ (0xffffffffu >> (32 - width));\n");
3186
                                break;
3187
                        case i_BFCLR:
3188
                                printf ("\ttmp = 0;\n");
3189
                                break;
3190
                        case i_BFFFO:
3191
                                printf ("\t{ uae_u32 mask = 1 << (width - 1);\n");
3192
                                printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n");
3193
                                printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = offset;\n");
3194
                                break;
3195
                        case i_BFSET:
3196
                                printf ("\ttmp = 0xffffffffu >> (32 - width);\n");
3197
                                break;
3198
                        case i_BFINS:
3199
                                printf ("\ttmp = m68k_dreg (regs, (extra >> 12) & 7);\n");
3200
                                printf ("\ttmp = tmp & (0xffffffffu >> (32 - width));\n");
3201
                                printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n");
3202
                                printf ("\tSET_ZFLG (tmp == 0);\n");
3203
                                break;
3204
                        default:
3205
                                break;
3206
                        }
3207
                        if (curi->mnemo == i_BFCHG
3208
                                || curi->mnemo == i_BFCLR
3209
                                || curi->mnemo == i_BFSET
3210
                                || curi->mnemo == i_BFINS) {
3211
                                        if (curi->dmode == Dreg) {
3212
                                                printf ("\ttmp = bdata[0] | (tmp << (32 - width));\n");
3213
                                                printf ("\tm68k_dreg(regs, dstreg) = (tmp >> offset) | (tmp << (32 - offset));\n");
3214
                                        } else {
3215
                                                printf ("\t%s(dsta, bdata, tmp, offset, width);\n", putb);
3216
                                        }
3217
                        }
3218
                }
3219
                break;
3220
        case i_PACK:
3221
                if (curi->smode == Dreg) {
3222
                        printf ("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0));
3223
                        printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
3224
                } else {
3225
                        printf ("\tuae_u16 val;\n");
3226
                        printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
3227
                        printf ("\tval = (uae_u16)%s (m68k_areg (regs, srcreg));\n", srcb);
3228
                        printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
3229
                        printf ("\tval = (val | ((uae_u16)%s (m68k_areg (regs, srcreg)) << 8)) + %s;\n", srcb, gen_nextiword (0));
3230
                        printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
3231
                        gen_set_fault_pc ();
3232
                        printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb);
3233
                }
3234
                break;
3235
        case i_UNPK:
3236
                if (curi->smode == Dreg) {
3237
                        printf ("\tuae_u16 val = m68k_dreg (regs, srcreg);\n");
3238
                        printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
3239
                        printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffff0000) | (val & 0xffff);\n");
3240
                } else {
3241
                        printf ("\tuae_u16 val;\n");
3242
                        printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
3243
                        printf ("\tval = (uae_u16)%s (m68k_areg (regs, srcreg));\n", srcb);
3244
                        printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
3245
                        if (cpu_level >= 2) {
3246
                                printf ("\tm68k_areg (regs, dstreg) -= 2 * areg_byteinc[dstreg];\n");
3247
                                printf ("\t%s (m68k_areg (regs, dstreg) + areg_byteinc[dstreg], val);\n", dstb);
3248
                                printf ("\t%s (m68k_areg (regs, dstreg), val >> 8);\n", dstb);
3249
                        } else {
3250
                                printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
3251
                                printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb);
3252
                                printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
3253
                                gen_set_fault_pc ();
3254
                                printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb);
3255
                        }
3256
                }
3257
                break;
3258
        case i_TAS:
3259
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3260
                genflags (flag_logical, curi->size, "src", "", "");
3261
                if (!isreg (curi->smode))
3262
                        addcycles000 (2);
3263
                fill_prefetch_next ();
3264
                printf ("\tsrc |= 0x80;\n");
3265
                if (cpu_level >= 2 || curi->smode == Dreg || !using_ce) {
3266
                        if (next_cpu_level < 2)
3267
                                next_cpu_level = 2 - 1;
3268
                        genastore ("src", curi->smode, "srcreg", curi->size, "src");
3269
                } else {
3270
                        printf ("\tif (!is_cycle_ce ()) {\n");
3271
                        genastore ("src", curi->smode, "srcreg", curi->size, "src");
3272
                        printf ("\t} else {\n");
3273
                        printf ("\t\tdo_cycles_ce000 (4);\n");
3274
                        printf ("\t}\n");
3275
                }
3276
                break;
3277
        case i_FPP:
3278
                fpulimit();
3279
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3280
                sync_m68k_pc ();
3281
                printf ("\tfpuop_arithmetic(opcode, extra);\n");
3282
                break;
3283
        case i_FDBcc:
3284
                fpulimit();
3285
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3286
                sync_m68k_pc ();
3287
                printf ("\tfpuop_dbcc (opcode, extra);\n");
3288
                break;
3289
        case i_FScc:
3290
                fpulimit();
3291
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
3292
                sync_m68k_pc ();
3293
                printf ("\tfpuop_scc (opcode, extra);\n");
3294
                break;
3295
        case i_FTRAPcc:
3296
                fpulimit();
3297
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
3298
                printf ("\tuae_u16 extra = %s;\n", gen_nextiword (0));
3299
                if (curi->smode != am_unknown && curi->smode != am_illg)
3300
                        genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
3301
                sync_m68k_pc ();
3302
                printf ("\tfpuop_trapcc (opcode, oldpc, extra);\n");
3303
                break;
3304
        case i_FBcc:
3305
                fpulimit();
3306
                sync_m68k_pc ();
3307
                start_brace ();
3308
                printf ("\tuaecptr pc = m68k_getpc ();\n");
3309
                genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0);
3310
                sync_m68k_pc ();
3311
                printf ("\tfpuop_bcc (opcode, pc,extra);\n");
3312
                break;
3313
        case i_FSAVE:
3314
                fpulimit();
3315
                sync_m68k_pc ();
3316
                printf ("\tfpuop_save (opcode);\n");
3317
                break;
3318
        case i_FRESTORE:
3319
                fpulimit();
3320
                sync_m68k_pc ();
3321
                printf ("\tfpuop_restore (opcode);\n");
3322
                break;
3323
 
3324
        case i_CINVL:
3325
        case i_CINVP:
3326
        case i_CINVA:
3327
        case i_CPUSHL:
3328
        case i_CPUSHP:
3329
        case i_CPUSHA:
3330
                if (using_mmu)
3331
                        printf ("\tflush_mmu(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n");
3332
                printf ("\tif (opcode & 0x80)\n");
3333
                printf ("\t\tflush_icache(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n");
3334
                break;
3335
 
3336
        case i_MOVE16:
3337
                {
3338
                        if ((opcode & 0xfff8) == 0xf620) {
3339
                                /* MOVE16 (Ax)+,(Ay)+ */
3340
                                printf ("\tuae_u32 v1, v2, v3, v4;\n");
3341
                                printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
3342
                                printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
3343
                                printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
3344
                                printf ("\tv1 = %s (mems);\n", srcl);
3345
                                printf ("\tv2 = %s (mems + 4);\n", srcl);
3346
                                printf ("\tv3 = %s (mems + 8);\n", srcl);
3347
                                printf ("\tv4 = %s (mems + 12);\n", srcl);
3348
                                printf ("\t%s (memd , v1);\n", dstl);
3349
                                printf ("\t%s (memd + 4, v2);\n", dstl);
3350
                                printf ("\t%s (memd + 8, v3);\n", dstl);
3351
                                printf ("\t%s (memd + 12, v4);\n", dstl);
3352
                                printf ("\tif (srcreg != dstreg)\n");
3353
                                printf ("\t\tm68k_areg (regs, srcreg) += 16;\n");
3354
                                printf ("\tm68k_areg (regs, dstreg) += 16;\n");
3355
                        } else {
3356
                                /* Other variants */
3357
                                printf ("\tuae_u32 v1, v2, v3, v4;\n");
3358
                                genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
3359
                                genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
3360
                                printf ("\tmemsa &= ~15;\n");
3361
                                printf ("\tmemda &= ~15;\n");
3362
                                printf ("\tv1 = %s (memsa);\n", srcl);
3363
                                printf ("\tv2 = %s (memsa + 4);\n", srcl);
3364
                                printf ("\tv3 = %s (memsa + 8);\n", srcl);
3365
                                printf ("\tv4 = %s (memsa + 12);\n", srcl);
3366
                                printf ("\t%s (memda , v1);\n", dstl);
3367
                                printf ("\t%s (memda + 4, v2);\n", dstl);
3368
                                printf ("\t%s (memda + 8, v3);\n", dstl);
3369
                                printf ("\t%s (memda + 12, v4);\n", dstl);
3370
                                if ((opcode & 0xfff8) == 0xf600)
3371
                                        printf ("\tm68k_areg (regs, srcreg) += 16;\n");
3372
                                else if ((opcode & 0xfff8) == 0xf608)
3373
                                        printf ("\tm68k_areg (regs, dstreg) += 16;\n");
3374
                        }
3375
                }
3376
                break;
3377
 
3378
        case i_PFLUSHN:
3379
        case i_PFLUSH:
3380
        case i_PFLUSHAN:
3381
        case i_PFLUSHA:
3382
        case i_PLPAR:
3383
        case i_PLPAW:
3384
        case i_PTESTR:
3385
        case i_PTESTW:
3386
                sync_m68k_pc ();
3387
                printf ("\tmmu_op (opcode, 0);\n");
3388
                break;
3389
        case i_MMUOP030:
3390
                printf ("\tuaecptr pc = m68k_getpc ();\n");
3391
                printf ("\tuae_u16 extra = get_word (pc + 2);\n");
3392
                m68k_pc_offset += 2;
3393
                sync_m68k_pc ();
3394
                if (curi->smode == Areg || curi->smode == Dreg)
3395
                        printf("\tuae_u16 extraa = 0;\n");
3396
                else
3397
                        genamode (curi->smode, "srcreg", curi->size, "extra", 0, 0, 0);
3398
                sync_m68k_pc ();
3399
                printf ("\tmmu_op30 (pc, opcode, extra, extraa);\n");
3400
                break;
3401
        default:
3402
                abort ();
3403
                break;
3404
        }
3405
        finish_braces ();
3406
        if (limit_braces) {
3407
                printf ("\n#endif\n");
3408
                n_braces = limit_braces;
3409
                limit_braces = 0;
3410
                finish_braces ();
3411
        }
3412
        if (did_prefetch >= 0)
3413
                fill_prefetch_finish ();
3414
        if (!count_cycles)
3415
                addcycles_ce020 (2);
3416
        sync_m68k_pc ();
3417
        did_prefetch = 0;
3418
}
3419
 
3420
static void generate_includes (FILE * f)
3421
{
3422
//AO68000
3423
        fprintf(f, "#include \"ao.h\"\n");
3424
///     fprintf (f, "#include \"sysconfig.h\"\n");
3425
///     fprintf (f, "#include \"sysdeps.h\"\n");
3426
///     fprintf (f, "#include \"options.h\"\n");
3427
//      fprintf (f, "#include \"memory.h\"\n");
3428
///     fprintf (f, "#include \"custom.h\"\n");
3429
///     fprintf (f, "#include \"events.h\"\n");
3430
///     fprintf (f, "#include \"newcpu.h\"\n");
3431
///     fprintf (f, "#include \"cpu_prefetch.h\"\n");
3432
        fprintf (f, "#include \"cputbl.h\"\n");
3433
///     fprintf (f, "#include \"cpummu.h\"\n");
3434
//AO68000 end
3435
 
3436
 
3437
        fprintf (f, "#define CPUFUNC(x) x##_ff\n"
3438
                "#define SET_CFLG_ALWAYS(x) SET_CFLG(x)\n"
3439
                "#define SET_NFLG_ALWAYS(x) SET_NFLG(x)\n"
3440
                "#ifdef NOFLAGS\n"
3441
                "#include \"noflags.h\"\n"
3442
                "#endif\n");
3443
}
3444
 
3445
static int postfix;
3446
 
3447
 
3448
static char *decodeEA (amodes mode, wordsizes size)
3449
{
3450
        static char buffer[80];
3451
 
3452
        buffer[0] = 0;
3453
        switch (mode){
3454
        case Dreg:
3455
                strcpy (buffer,"Dn");
3456
                break;
3457
        case Areg:
3458
                strcpy (buffer,"An");
3459
                break;
3460
        case Aind:
3461
                strcpy (buffer,"(An)");
3462
                break;
3463
        case Aipi:
3464
                strcpy (buffer,"(An)+");
3465
                break;
3466
        case Apdi:
3467
                strcpy (buffer,"-(An)");
3468
                break;
3469
        case Ad16:
3470
                strcpy (buffer,"(d16,An)");
3471
                break;
3472
        case Ad8r:
3473
                strcpy (buffer,"(d8,An,Xn)");
3474
                break;
3475
        case PC16:
3476
                strcpy (buffer,"(d16,PC)");
3477
                break;
3478
        case PC8r:
3479
                strcpy (buffer,"(d8,PC,Xn)");
3480
                break;
3481
        case absw:
3482
                strcpy (buffer,"(xxx).W");
3483
                break;
3484
        case absl:
3485
                strcpy (buffer,"(xxx).L");
3486
                break;
3487
        case imm:
3488
                switch (size){
3489
                case sz_byte:
3490
                        strcpy (buffer,"#<data>.B");
3491
                        break;
3492
                case sz_word:
3493
                        strcpy (buffer,"#<data>.W");
3494
                        break;
3495
                case sz_long:
3496
                        strcpy (buffer,"#<data>.L");
3497
                        break;
3498
                default:
3499
                        break;
3500
                }
3501
                break;
3502
        case imm0:
3503
                strcpy (buffer,"#<data>.B");
3504
                break;
3505
        case imm1:
3506
                strcpy (buffer,"#<data>.W");
3507
                break;
3508
        case imm2:
3509
                strcpy (buffer,"#<data>.L");
3510
                break;
3511
        case immi:
3512
                strcpy (buffer,"#<data>");
3513
                break;
3514
 
3515
        default:
3516
                break;
3517
        }
3518
        return buffer;
3519
}
3520
 
3521
static char *outopcode (int opcode)
3522
{
3523
        static char out[100];
3524
        struct instr *ins;
3525
        int i;
3526
 
3527
        ins = &table68k[opcode];
3528
        for (i = 0; lookuptab[i].name[0]; i++) {
3529
                if (ins->mnemo == lookuptab[i].mnemo)
3530
                        break;
3531
        }
3532
        {
3533
                char *s = ua (lookuptab[i].name);
3534
                strcpy (out, s);
3535
                xfree (s);
3536
        }
3537
        if (ins->smode == immi)
3538
                strcat (out, "Q");
3539
        if (ins->size == sz_byte)
3540
                strcat (out,".B");
3541
        if (ins->size == sz_word)
3542
                strcat (out,".W");
3543
        if (ins->size == sz_long)
3544
                strcat (out,".L");
3545
        strcat (out," ");
3546
        if (ins->suse)
3547
                strcat (out, decodeEA (ins->smode, ins->size));
3548
        if (ins->duse) {
3549
                if (ins->suse) strcat (out,",");
3550
                strcat (out, decodeEA (ins->dmode, ins->size));
3551
        }
3552
        return out;
3553
}
3554
 
3555
static void generate_one_opcode (int rp)
3556
{
3557
        int idx;
3558
        uae_u16 smsk, dmsk;
3559
        long int opcode = opcode_map[rp];
3560
        int i68000 = table68k[opcode].clev > 0;
3561
 
3562
        if (table68k[opcode].mnemo == i_ILLG
3563
                || table68k[opcode].clev > cpu_level)
3564
                return;
3565
 
3566
        for (idx = 0; lookuptab[idx].name[0]; idx++) {
3567
                if (table68k[opcode].mnemo == lookuptab[idx].mnemo)
3568
                        break;
3569
        }
3570
 
3571
        if (table68k[opcode].handler != -1)
3572
                return;
3573
 
3574
        if (opcode_next_clev[rp] != cpu_level) {
3575
                char *name = ua (lookuptab[idx].name);
3576
                if (generate_stbl)
3577
                        fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n",
3578
                        (using_ce || using_ce020) ? "(cpuop_func*)" : "",
3579
                        opcode, opcode_last_postfix[rp],
3580
                        opcode, name);
3581
                xfree (name);
3582
                return;
3583
        }
3584
        fprintf (headerfile, "extern %s op_%04lx_%d_nf;\n",
3585
                (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix);
3586
        fprintf (headerfile, "extern %s op_%04lx_%d_ff;\n",
3587
                (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix);
3588
        printf ("/* %s */\n", outopcode (opcode));
3589
        if (i68000)
3590
                printf("#ifndef CPUEMU_68000_ONLY\n");
3591
        printf ("%s REGPARAM2 CPUFUNC(op_%04lx_%d)(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "unsigned long", opcode, postfix);
3592
 
3593
        switch (table68k[opcode].stype) {
3594
        case 0: smsk = 7; break;
3595
        case 1: smsk = 255; break;
3596
        case 2: smsk = 15; break;
3597
        case 3: smsk = 7; break;
3598
        case 4: smsk = 7; break;
3599
        case 5: smsk = 63; break;
3600
        case 7: smsk = 3; break;
3601
        default: abort ();
3602
        }
3603
        dmsk = 7;
3604
 
3605
        next_cpu_level = -1;
3606
        if (table68k[opcode].suse
3607
                && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
3608
                && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
3609
                && table68k[opcode].smode != absw && table68k[opcode].smode != absl
3610
                && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
3611
        {
3612
                if (table68k[opcode].spos == -1) {
3613
                        if (((int) table68k[opcode].sreg) >= 128)
3614
                                printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
3615
                        else
3616
                                printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg);
3617
                } else {
3618
                        char source[100];
3619
                        int pos = table68k[opcode].spos;
3620
 
3621
                        if (pos)
3622
                                sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
3623
                        else
3624
                                sprintf (source, "(opcode & %d)", smsk);
3625
 
3626
                        if (table68k[opcode].stype == 3)
3627
                                printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
3628
                        else if (table68k[opcode].stype == 1)
3629
                                printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
3630
                        else
3631
                                printf ("\tuae_u32 srcreg = %s;\n", source);
3632
                }
3633
        }
3634
        if (table68k[opcode].duse
3635
                /* Yes, the dmode can be imm, in case of LINK or DBcc */
3636
                && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
3637
                && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
3638
                && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
3639
        {
3640
                if (table68k[opcode].dpos == -1) {
3641
                        if (((int) table68k[opcode].dreg) >= 128)
3642
                                printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
3643
                        else
3644
                                printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg);
3645
                } else {
3646
                        int pos = table68k[opcode].dpos;
3647
                        if (pos)
3648
                                printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
3649
                                pos, dmsk);
3650
                        else
3651
                                printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
3652
                }
3653
        }
3654
        need_endlabel = 0;
3655
        endlabelno++;
3656
        sprintf (endlabelstr, "endlabel%d", endlabelno);
3657
        count_read = count_write = count_ncycles = count_cycles = 0;
3658
        count_read_ea = count_write_ea = count_cycles_ea = 0;
3659
        gen_opcode (opcode);
3660
        if (need_endlabel)
3661
                printf ("%s: ;\n", endlabelstr);
3662
        returncycles ("", insn_n_cycles);
3663
        printf ("}");
3664
        if (using_ce || using_prefetch) {
3665
                if (count_read + count_write + count_cycles == 0)
3666
                        count_cycles = 4;
3667
                printf (" /* %d%s (%d/%d)",
3668
                        (count_read + count_write) * 4 + count_cycles, count_ncycles ? "+" : "", count_read, count_write);
3669
                printf (" */\n");
3670
        } else {
3671
                printf("\n");
3672
        }
3673
        printf ("\n");
3674
        if (i68000)
3675
                printf("#endif\n");
3676
        opcode_next_clev[rp] = next_cpu_level;
3677
        opcode_last_postfix[rp] = postfix;
3678
 
3679
        if (generate_stbl) {
3680
                char *name = ua (lookuptab[idx].name);
3681
                if (i68000)
3682
                        fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
3683
                fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n",
3684
                        (using_ce || using_ce020) ? "(cpuop_func*)" : "",
3685
                        opcode, postfix, opcode, name);
3686
                if (i68000)
3687
                        fprintf (stblfile, "#endif\n");
3688
                xfree (name);
3689
        }
3690
}
3691
 
3692
static void generate_func (void)
3693
{
3694
        int j, rp;
3695
 
3696
        /* sam: this is for people with low memory (eg. me :)) */
3697
        printf ("\n"
3698
                "#if !defined(PART_1) && !defined(PART_2) && "
3699
                "!defined(PART_3) && !defined(PART_4) && "
3700
                "!defined(PART_5) && !defined(PART_6) && "
3701
                "!defined(PART_7) && !defined(PART_8)"
3702
                "\n"
3703
                "#define PART_1 1\n"
3704
                "#define PART_2 1\n"
3705
                "#define PART_3 1\n"
3706
                "#define PART_4 1\n"
3707
                "#define PART_5 1\n"
3708
                "#define PART_6 1\n"
3709
                "#define PART_7 1\n"
3710
                "#define PART_8 1\n"
3711
                "#endif\n\n");
3712
 
3713
        rp = 0;
3714
        for(j = 1; j <= 8; ++j) {
3715
                int k = (j * nr_cpuop_funcs) / 8;
3716
                printf ("#ifdef PART_%d\n",j);
3717
                for (; rp < k; rp++)
3718
                        generate_one_opcode (rp);
3719
                printf ("#endif\n\n");
3720
        }
3721
 
3722
        if (generate_stbl)
3723
                fprintf (stblfile, "{ 0, 0 }};\n");
3724
}
3725
 
3726
int main (int argc, char **argv)
3727
{
3728
        int i, rp, postfix2;
3729
        char fname[100];
3730
 
3731
        read_table68k ();
3732
        do_merges ();
3733
 
3734
        opcode_map = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
3735
        opcode_last_postfix = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
3736
        opcode_next_clev = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
3737
        counts = (unsigned long *) xmalloc (65536 * sizeof (unsigned long));
3738
        read_counts ();
3739
 
3740
        /* It would be a lot nicer to put all in one file (we'd also get rid of
3741
        * cputbl.h that way), but cpuopti can't cope.  That could be fixed, but
3742
        * I don't dare to touch the 68k version.  */
3743
 
3744
        headerfile = fopen ("cputbl.h", "wb");
3745
 
3746
        stblfile = fopen ("cpustbl.c", "wb");
3747
        generate_includes (stblfile);
3748
 
3749
        using_prefetch = 0;
3750
        using_indirect = 0;
3751
        using_exception_3 = 1;
3752
        using_ce = 0;
3753
 
3754
        postfix2 = -1;
3755
        for (i = 0; i < 32; i++) {
3756
                postfix = i;
3757
                if ((i >= 6 && i < 11) || (i > 12 && i < 20) || (i > 23 && i < 31))
3758
                        continue;
3759
                generate_stbl = 1;
3760
                if (i == 0 || i == 11 || i == 12 || i == 20 || i == 31) {
3761
                        if (generate_stbl)
3762
                                fprintf (stblfile, "#ifdef CPUEMU_%d\n", postfix);
3763
                        postfix2 = postfix;
3764
                        sprintf (fname, "cpuemu_%d.c", postfix);
3765
                        freopen (fname, "wb", stdout);
3766
                        generate_includes (stdout);
3767
                }
3768
                using_mmu = 0;
3769
                using_prefetch = 0;
3770
                using_ce = 0;
3771
                using_ce020 = 0;
3772
                using_mmu = 0;
3773
                cpu_level = 5 - i;
3774
                if (i == 11 || i == 12) {
3775
                        cpu_level = 0;
3776
                        using_prefetch = 1;
3777
                        using_exception_3 = 1;
3778
                        if (i == 12)
3779
                                using_ce = 1;
3780
                        for (rp = 0; rp < nr_cpuop_funcs; rp++)
3781
                                opcode_next_clev[rp] = 0;
3782
                } else if (i >= 20 && i < 30) {
3783
                        cpu_level = 25 - i;
3784
                        using_ce020 = 1;
3785
                        if (i == 20)
3786
                                read_counts ();
3787
                } else if (i >= 31 && i < 40) {
3788
                        cpu_level = 4;
3789
                        using_mmu = 1;
3790
                        if (i == 31)
3791
                                read_counts ();
3792
                        for (rp = 0; rp < nr_cpuop_funcs; rp++)
3793
                                opcode_next_clev[rp] = 4;
3794
                }
3795
 
3796
                if (generate_stbl) {
3797
                        if ((i > 0 && i < 10) || (i >= 20))
3798
                                fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
3799
                        fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix);
3800
                }
3801
                generate_func ();
3802
                if (generate_stbl) {
3803
                        if ((i > 0 && i < 10) || (i >= 20))
3804
                                fprintf (stblfile, "#endif /* CPUEMU_68000_ONLY */\n");
3805
                        if (postfix2 >= 0)
3806
                                fprintf (stblfile, "#endif /* CPUEMU_%d */\n", postfix2);
3807
                }
3808
                postfix2 = -1;
3809
        }
3810
 
3811
        free (table68k);
3812
        return 0;
3813
}

powered by: WebSVN 2.1.0

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