Statistics
| Branch: | Revision:

root / target-m68k / op.c @ 0cf5c677

History | View | Annotate | Download (20.7 kB)

1
/*
2
 *  m68k micro operations
3
 * 
4
 *  Copyright (c) 2006-2007 CodeSourcery
5
 *  Written by Paul Brook
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21

    
22
#include "exec.h"
23
#include "m68k-qreg.h"
24

    
25
#ifndef offsetof
26
#define offsetof(type, field) ((size_t) &((type *)0)->field)
27
#endif
28

    
29
static long qreg_offsets[] = {
30
#define DEFO32(name, offset) offsetof(CPUState, offset),
31
#define DEFR(name, reg, mode) -1,
32
#define DEFF64(name, offset) offsetof(CPUState, offset),
33
    0,
34
#include "qregs.def"
35
};
36

    
37
#define CPU_FP_STATUS env->fp_status
38

    
39
#define RAISE_EXCEPTION(n) do { \
40
    env->exception_index = n; \
41
    cpu_loop_exit(); \
42
    } while(0)
43

    
44
#define get_op helper_get_op
45
#define set_op helper_set_op
46
#define get_opf64 helper_get_opf64
47
#define set_opf64 helper_set_opf64
48
uint32_t
49
get_op(int qreg)
50
{
51
    if (qreg >= TARGET_NUM_QREGS) {
52
        return env->qregs[qreg - TARGET_NUM_QREGS];
53
    } else if (qreg == QREG_T0) {
54
        return T0;
55
    } else {
56
        return *(uint32_t *)(((long)env) + qreg_offsets[qreg]);
57
    }
58
}
59

    
60
void set_op(int qreg, uint32_t val)
61
{
62
    if (qreg >= TARGET_NUM_QREGS) {
63
        env->qregs[qreg - TARGET_NUM_QREGS] = val;
64
    } else if (qreg == QREG_T0) {
65
        T0 = val;
66
    } else {
67
        *(uint32_t *)(((long)env) + qreg_offsets[qreg]) = val;
68
    }
69
}
70

    
71
float64 get_opf64(int qreg)
72
{
73
    if (qreg < TARGET_NUM_QREGS) {
74
        return *(float64 *)(((long)env) + qreg_offsets[qreg]);
75
    } else {
76
        return *(float64 *)&env->qregs[qreg - TARGET_NUM_QREGS];
77
    }
78
}
79

    
80
void set_opf64(int qreg, float64 val)
81
{
82
    if (qreg < TARGET_NUM_QREGS) {
83
        *(float64 *)(((long)env) + qreg_offsets[qreg]) = val;
84
    } else {
85
        *(float64 *)&env->qregs[qreg - TARGET_NUM_QREGS] = val;
86
    }
87
}
88

    
89
#define OP(name) void OPPROTO glue(op_,name) (void)
90

    
91
OP(mov32)
92
{
93
    set_op(PARAM1, get_op(PARAM2));
94
    FORCE_RET();
95
}
96

    
97
OP(mov32_im)
98
{
99
    set_op(PARAM1, PARAM2);
100
    FORCE_RET();
101
}
102

    
103
OP(movf64)
104
{
105
    set_opf64(PARAM1, get_opf64(PARAM2));
106
    FORCE_RET();
107
}
108

    
109
OP(zerof64)
110
{
111
    set_opf64(PARAM1, 0);
112
    FORCE_RET();
113
}
114

    
115
OP(add32)
116
{
117
    uint32_t op2 = get_op(PARAM2);
118
    uint32_t op3 = get_op(PARAM3);
119
    set_op(PARAM1, op2 + op3);
120
    FORCE_RET();
121
}
122

    
123
OP(sub32)
124
{
125
    uint32_t op2 = get_op(PARAM2);
126
    uint32_t op3 = get_op(PARAM3);
127
    set_op(PARAM1, op2 - op3);
128
    FORCE_RET();
129
}
130

    
131
OP(mul32)
132
{
133
    uint32_t op2 = get_op(PARAM2);
134
    uint32_t op3 = get_op(PARAM3);
135
    set_op(PARAM1, op2 * op3);
136
    FORCE_RET();
137
}
138

    
139
OP(not32)
140
{
141
    uint32_t arg = get_op(PARAM2);
142
    set_op(PARAM1, ~arg);
143
    FORCE_RET();
144
}
145

    
146
OP(neg32)
147
{
148
    uint32_t arg = get_op(PARAM2);
149
    set_op(PARAM1, -arg);
150
    FORCE_RET();
151
}
152

    
153
OP(bswap32)
154
{
155
    uint32_t arg = get_op(PARAM2);
156
    arg = (arg >> 24) | (arg << 24)
157
          | ((arg >> 16) & 0xff00) | ((arg << 16) & 0xff0000);
158
    set_op(PARAM1, arg);
159
    FORCE_RET();
160
}
161

    
162
OP(btest)
163
{
164
    uint32_t op1 = get_op(PARAM1);
165
    uint32_t op2 = get_op(PARAM2);
166
    if (op1 & op2)
167
        env->cc_dest &= ~CCF_Z;
168
    else
169
        env->cc_dest |= CCF_Z;
170
    FORCE_RET();
171
}
172

    
173
OP(ff1)
174
{
175
    uint32_t arg = get_op(PARAM2);
176
    int n;
177
    for (n = 32; arg; n--)
178
        arg >>= 1;
179
    set_op(PARAM1, n);
180
    FORCE_RET();
181
}
182

    
183
OP(subx_cc)
184
{
185
    uint32_t op1 = get_op(PARAM1);
186
    uint32_t op2 = get_op(PARAM2);
187
    uint32_t res;
188
    if (env->cc_x) {
189
        env->cc_x = (op1 <= op2);
190
        env->cc_op = CC_OP_SUBX;
191
        res = op1 - (op2 + 1);
192
    } else {
193
        env->cc_x = (op1 < op2);
194
        env->cc_op = CC_OP_SUB;
195
        res = op1 - op2;
196
    }
197
    set_op(PARAM1, res);
198
    FORCE_RET();
199
}
200

    
201
OP(addx_cc)
202
{
203
    uint32_t op1 = get_op(PARAM1);
204
    uint32_t op2 = get_op(PARAM2);
205
    uint32_t res;
206
    if (env->cc_x) {
207
        res = op1 + op2 + 1;
208
        env->cc_x = (res <= op2);
209
        env->cc_op = CC_OP_ADDX;
210
    } else {
211
        res = op1 + op2;
212
        env->cc_x = (res < op2);
213
        env->cc_op = CC_OP_ADD;
214
    }
215
    set_op(PARAM1, res);
216
    FORCE_RET();
217
}
218

    
219
/* Logic ops.  */
220

    
221
OP(and32)
222
{
223
    uint32_t op2 = get_op(PARAM2);
224
    uint32_t op3 = get_op(PARAM3);
225
    set_op(PARAM1, op2 & op3);
226
    FORCE_RET();
227
}
228

    
229
OP(or32)
230
{
231
    uint32_t op2 = get_op(PARAM2);
232
    uint32_t op3 = get_op(PARAM3);
233
    set_op(PARAM1, op2 | op3);
234
    FORCE_RET();
235
}
236

    
237
OP(xor32)
238
{
239
    uint32_t op2 = get_op(PARAM2);
240
    uint32_t op3 = get_op(PARAM3);
241
    set_op(PARAM1, op2 ^ op3);
242
    FORCE_RET();
243
}
244

    
245
/* Shifts.  */
246
OP(shl32)
247
{
248
    uint32_t op2 = get_op(PARAM2);
249
    uint32_t op3 = get_op(PARAM3);
250
    uint32_t result;
251
    result = op2 << op3;
252
    set_op(PARAM1, result);
253
    FORCE_RET();
254
}
255

    
256
OP(shl_cc)
257
{
258
    uint32_t op1 = get_op(PARAM1);
259
    uint32_t op2 = get_op(PARAM2);
260
    uint32_t result;
261
    result = op1 << op2;
262
    set_op(PARAM1, result);
263
    env->cc_x = (op1 << (op2 - 1)) & 1;
264
    FORCE_RET();
265
}
266

    
267
OP(shr32)
268
{
269
    uint32_t op2 = get_op(PARAM2);
270
    uint32_t op3 = get_op(PARAM3);
271
    uint32_t result;
272
    result = op2 >> op3;
273
    set_op(PARAM1, result);
274
    FORCE_RET();
275
}
276

    
277
OP(shr_cc)
278
{
279
    uint32_t op1 = get_op(PARAM1);
280
    uint32_t op2 = get_op(PARAM2);
281
    uint32_t result;
282
    result = op1 >> op2;
283
    set_op(PARAM1, result);
284
    env->cc_x = (op1 >> (op2 - 1)) & 1;
285
    FORCE_RET();
286
}
287

    
288
OP(sar32)
289
{
290
    int32_t op2 = get_op(PARAM2);
291
    uint32_t op3 = get_op(PARAM3);
292
    uint32_t result;
293
    result = op2 >> op3;
294
    set_op(PARAM1, result);
295
    FORCE_RET();
296
}
297

    
298
OP(sar_cc)
299
{
300
    int32_t op1 = get_op(PARAM1);
301
    uint32_t op2 = get_op(PARAM2);
302
    uint32_t result;
303
    result = op1 >> op2;
304
    set_op(PARAM1, result);
305
    env->cc_x = (op1 >> (op2 - 1)) & 1;
306
    FORCE_RET();
307
}
308

    
309
/* Value extend.  */
310

    
311
OP(ext8u32)
312
{
313
    uint32_t op2 = get_op(PARAM2);
314
    set_op(PARAM1, (uint8_t)op2);
315
    FORCE_RET();
316
}
317

    
318
OP(ext8s32)
319
{
320
    uint32_t op2 = get_op(PARAM2);
321
    set_op(PARAM1, (int8_t)op2);
322
    FORCE_RET();
323
}
324

    
325
OP(ext16u32)
326
{
327
    uint32_t op2 = get_op(PARAM2);
328
    set_op(PARAM1, (uint16_t)op2);
329
    FORCE_RET();
330
}
331

    
332
OP(ext16s32)
333
{
334
    uint32_t op2 = get_op(PARAM2);
335
    set_op(PARAM1, (int16_t)op2);
336
    FORCE_RET();
337
}
338

    
339
OP(flush_flags)
340
{
341
    cpu_m68k_flush_flags(env, env->cc_op);
342
    FORCE_RET();
343
}
344

    
345
OP(divu)
346
{
347
    uint32_t num;
348
    uint32_t den;
349
    uint32_t quot;
350
    uint32_t rem;
351
    uint32_t flags;
352
    
353
    num = env->div1;
354
    den = env->div2;
355
    /* ??? This needs to make sure the throwing location is accurate.  */
356
    if (den == 0)
357
        RAISE_EXCEPTION(EXCP_DIV0);
358
    quot = num / den;
359
    rem = num % den;
360
    flags = 0;
361
    /* Avoid using a PARAM1 of zero.  This breaks dyngen because it uses
362
       the address of a symbol, and gcc knows symbols can't have address
363
       zero.  */
364
    if (PARAM1 == 2 && quot > 0xffff)
365
        flags |= CCF_V;
366
    if (quot == 0)
367
        flags |= CCF_Z;
368
    else if ((int32_t)quot < 0)
369
        flags |= CCF_N;
370
    env->div1 = quot;
371
    env->div2 = rem;
372
    env->cc_dest = flags;
373
    FORCE_RET();
374
}
375

    
376
OP(divs)
377
{
378
    int32_t num;
379
    int32_t den;
380
    int32_t quot;
381
    int32_t rem;
382
    int32_t flags;
383
    
384
    num = env->div1;
385
    den = env->div2;
386
    if (den == 0)
387
        RAISE_EXCEPTION(EXCP_DIV0);
388
    quot = num / den;
389
    rem = num % den;
390
    flags = 0;
391
    if (PARAM1 == 2 && quot != (int16_t)quot)
392
        flags |= CCF_V;
393
    if (quot == 0)
394
        flags |= CCF_Z;
395
    else if (quot < 0)
396
        flags |= CCF_N;
397
    env->div1 = quot;
398
    env->div2 = rem;
399
    env->cc_dest = flags;
400
    FORCE_RET();
401
}
402

    
403
/* Halt is special because it may be a semihosting call.  */
404
OP(halt)
405
{
406
    RAISE_EXCEPTION(EXCP_HALT_INSN);
407
    FORCE_RET();
408
}
409

    
410
OP(stop)
411
{
412
    env->halted = 1;
413
    RAISE_EXCEPTION(EXCP_HLT);
414
    FORCE_RET();
415
}
416

    
417
OP(raise_exception)
418
{
419
    RAISE_EXCEPTION(PARAM1);
420
    FORCE_RET();
421
}
422

    
423
/* Floating point comparison sets flags differently to other instructions.  */
424

    
425
OP(sub_cmpf64)
426
{
427
    float64 src0;
428
    float64 src1;
429
    src0 = get_opf64(PARAM2);
430
    src1 = get_opf64(PARAM3);
431
    set_opf64(PARAM1, helper_sub_cmpf64(env, src0, src1));
432
    FORCE_RET();
433
}
434

    
435
OP(update_xflag_tst)
436
{
437
    uint32_t op1 = get_op(PARAM1);
438
    env->cc_x = op1;
439
    FORCE_RET();
440
}
441

    
442
OP(update_xflag_lt)
443
{
444
    uint32_t op1 = get_op(PARAM1);
445
    uint32_t op2 = get_op(PARAM2);
446
    env->cc_x = (op1 < op2);
447
    FORCE_RET();
448
}
449

    
450
OP(get_xflag)
451
{
452
    set_op(PARAM1, env->cc_x);
453
    FORCE_RET();
454
}
455

    
456
OP(logic_cc)
457
{
458
    uint32_t op1 = get_op(PARAM1);
459
    env->cc_dest = op1;
460
    FORCE_RET();
461
}
462

    
463
OP(update_cc_add)
464
{
465
    uint32_t op1 = get_op(PARAM1);
466
    uint32_t op2 = get_op(PARAM2);
467
    env->cc_dest = op1;
468
    env->cc_src = op2;
469
    FORCE_RET();
470
}
471

    
472
OP(fp_result)
473
{
474
    env->fp_result = get_opf64(PARAM1);
475
    FORCE_RET();
476
}
477

    
478
OP(set_sr)
479
{
480
    env->sr = get_op(PARAM1) & 0xffff;
481
    m68k_switch_sp(env);
482
    FORCE_RET();
483
}
484

    
485
OP(jmp)
486
{
487
    GOTO_LABEL_PARAM(1);
488
}
489

    
490
/* These ops involve a function call, which probably requires a stack frame
491
   and breaks things on some hosts.  */
492
OP(jmp_z32)
493
{
494
    uint32_t arg = get_op(PARAM1);
495
    if (arg == 0)
496
        GOTO_LABEL_PARAM(2);
497
    FORCE_RET();
498
}
499

    
500
OP(jmp_nz32)
501
{
502
    uint32_t arg = get_op(PARAM1);
503
    if (arg != 0)
504
        GOTO_LABEL_PARAM(2);
505
    FORCE_RET();
506
}
507

    
508
OP(jmp_s32)
509
{
510
    int32_t arg = get_op(PARAM1);
511
    if (arg < 0)
512
        GOTO_LABEL_PARAM(2);
513
    FORCE_RET();
514
}
515

    
516
OP(jmp_ns32)
517
{
518
    int32_t arg = get_op(PARAM1);
519
    if (arg >= 0)
520
        GOTO_LABEL_PARAM(2);
521
    FORCE_RET();
522
}
523

    
524
void OPPROTO op_goto_tb0(void)
525
{
526
    GOTO_TB(op_goto_tb0, PARAM1, 0);
527
}
528

    
529
void OPPROTO op_goto_tb1(void)
530
{
531
    GOTO_TB(op_goto_tb1, PARAM1, 1);
532
}
533

    
534
OP(exit_tb)
535
{
536
    EXIT_TB();
537
}
538

    
539

    
540
/* Floating point.  */
541
OP(f64_to_i32)
542
{
543
    set_op(PARAM1, float64_to_int32(get_opf64(PARAM2), &CPU_FP_STATUS));
544
    FORCE_RET();
545
}
546

    
547
OP(f64_to_f32)
548
{
549
    union {
550
        float32 f;
551
        uint32_t i;
552
    } u;
553
    u.f = float64_to_float32(get_opf64(PARAM2), &CPU_FP_STATUS);
554
    set_op(PARAM1, u.i);
555
    FORCE_RET();
556
}
557

    
558
OP(i32_to_f64)
559
{
560
    set_opf64(PARAM1, int32_to_float64(get_op(PARAM2), &CPU_FP_STATUS));
561
    FORCE_RET();
562
}
563

    
564
OP(f32_to_f64)
565
{
566
    union {
567
        float32 f;
568
        uint32_t i;
569
    } u;
570
    u.i = get_op(PARAM2);
571
    set_opf64(PARAM1, float32_to_float64(u.f, &CPU_FP_STATUS));
572
    FORCE_RET();
573
}
574

    
575
OP(absf64)
576
{
577
    float64 op0 = get_opf64(PARAM2);
578
    set_opf64(PARAM1, float64_abs(op0));
579
    FORCE_RET();
580
}
581

    
582
OP(chsf64)
583
{
584
    float64 op0 = get_opf64(PARAM2);
585
    set_opf64(PARAM1, float64_chs(op0));
586
    FORCE_RET();
587
}
588

    
589
OP(sqrtf64)
590
{
591
    float64 op0 = get_opf64(PARAM2);
592
    set_opf64(PARAM1, float64_sqrt(op0, &CPU_FP_STATUS));
593
    FORCE_RET();
594
}
595

    
596
OP(addf64)
597
{
598
    float64 op0 = get_opf64(PARAM2);
599
    float64 op1 = get_opf64(PARAM3);
600
    set_opf64(PARAM1, float64_add(op0, op1, &CPU_FP_STATUS));
601
    FORCE_RET();
602
}
603

    
604
OP(subf64)
605
{
606
    float64 op0 = get_opf64(PARAM2);
607
    float64 op1 = get_opf64(PARAM3);
608
    set_opf64(PARAM1, float64_sub(op0, op1, &CPU_FP_STATUS));
609
    FORCE_RET();
610
}
611

    
612
OP(mulf64)
613
{
614
    float64 op0 = get_opf64(PARAM2);
615
    float64 op1 = get_opf64(PARAM3);
616
    set_opf64(PARAM1, float64_mul(op0, op1, &CPU_FP_STATUS));
617
    FORCE_RET();
618
}
619

    
620
OP(divf64)
621
{
622
    float64 op0 = get_opf64(PARAM2);
623
    float64 op1 = get_opf64(PARAM3);
624
    set_opf64(PARAM1, float64_div(op0, op1, &CPU_FP_STATUS));
625
    FORCE_RET();
626
}
627

    
628
OP(iround_f64)
629
{
630
    float64 op0 = get_opf64(PARAM2);
631
    set_opf64(PARAM1, float64_round_to_int(op0, &CPU_FP_STATUS));
632
    FORCE_RET();
633
}
634

    
635
OP(itrunc_f64)
636
{
637
    float64 op0 = get_opf64(PARAM2);
638
    set_opf64(PARAM1, float64_trunc_to_int(op0, &CPU_FP_STATUS));
639
    FORCE_RET();
640
}
641

    
642
OP(compare_quietf64)
643
{
644
    float64 op0 = get_opf64(PARAM2);
645
    float64 op1 = get_opf64(PARAM3);
646
    set_op(PARAM1, float64_compare_quiet(op0, op1, &CPU_FP_STATUS));
647
    FORCE_RET();
648
}
649

    
650
OP(movec)
651
{
652
    int op1 = get_op(PARAM1);
653
    uint32_t op2 = get_op(PARAM2);
654
    helper_movec(env, op1, op2);
655
}
656

    
657
/* Memory access.  */
658

    
659
#define MEMSUFFIX _raw
660
#include "op_mem.h"
661

    
662
#if !defined(CONFIG_USER_ONLY)
663
#define MEMSUFFIX _user
664
#include "op_mem.h"
665
#define MEMSUFFIX _kernel
666
#include "op_mem.h"
667
#endif
668

    
669
/* MAC unit.  */
670
/* TODO: The MAC instructions use 64-bit arithmetic fairly extensively.
671
   This results in fairly large ops (and sometimes other issues) on 32-bit
672
   hosts.  Maybe move most of them into helpers.  */
673
OP(macmuls)
674
{
675
    uint32_t op1 = get_op(PARAM1);
676
    uint32_t op2 = get_op(PARAM2);
677
    int64_t product;
678
    int64_t res;
679

    
680
    product = (uint64_t)op1 * op2;
681
    res = (product << 24) >> 24;
682
    if (res != product) {
683
        env->macsr |= MACSR_V;
684
        if (env->macsr & MACSR_OMC) {
685
            /* Make sure the accumulate operation overflows.  */
686
            if (product < 0)
687
                res = ~(1ll << 50);
688
            else
689
                res = 1ll << 50;
690
        }
691
    }
692
    env->mactmp = res;
693
    FORCE_RET();
694
}
695

    
696
OP(macmulu)
697
{
698
    uint32_t op1 = get_op(PARAM1);
699
    uint32_t op2 = get_op(PARAM2);
700
    uint64_t product;
701

    
702
    product = (uint64_t)op1 * op2;
703
    if (product & (0xffffffull << 40)) {
704
        env->macsr |= MACSR_V;
705
        if (env->macsr & MACSR_OMC) {
706
            /* Make sure the accumulate operation overflows.  */
707
            product = 1ll << 50;
708
        } else {
709
            product &= ((1ull << 40) - 1);
710
        }
711
    }
712
    env->mactmp = product;
713
    FORCE_RET();
714
}
715

    
716
OP(macmulf)
717
{
718
    int32_t op1 = get_op(PARAM1);
719
    int32_t op2 = get_op(PARAM2);
720
    uint64_t product;
721
    uint32_t remainder;
722

    
723
    product = (uint64_t)op1 * op2;
724
    if (env->macsr & MACSR_RT) {
725
        remainder = product & 0xffffff;
726
        product >>= 24;
727
        if (remainder > 0x800000)
728
            product++;
729
        else if (remainder == 0x800000)
730
            product += (product & 1);
731
    } else {
732
        product >>= 24;
733
    }
734
    env->mactmp = product;
735
    FORCE_RET();
736
}
737

    
738
OP(macshl)
739
{
740
    env->mactmp <<= 1;
741
}
742

    
743
OP(macshr)
744
{
745
    env->mactmp >>= 1;
746
}
747

    
748
OP(macadd)
749
{
750
    int acc = PARAM1;
751
    env->macc[acc] += env->mactmp;
752
    FORCE_RET();
753
}
754

    
755
OP(macsub)
756
{
757
    int acc = PARAM1;
758
    env->macc[acc] -= env->mactmp;
759
    FORCE_RET();
760
}
761

    
762
OP(macsats)
763
{
764
    int acc = PARAM1;
765
    int64_t sum;
766
    int64_t result;
767

    
768
    sum = env->macc[acc];
769
    result = (sum << 16) >> 16;
770
    if (result != sum) {
771
        env->macsr |= MACSR_V;
772
    }
773
    if (env->macsr & MACSR_V) {
774
        env->macsr |= MACSR_PAV0 << acc;
775
        if (env->macsr & MACSR_OMC) {
776
            /* The result is saturated to 32 bits, despite overflow occuring
777
               at 48 bits.  Seems weird, but that's what the hardware docs
778
               say.  */
779
            result = (result >> 63) ^ 0x7fffffff;
780
        }
781
    }
782
    env->macc[acc] = result;
783
    FORCE_RET();
784
}
785

    
786
OP(macsatu)
787
{
788
    int acc = PARAM1;
789
    uint64_t sum;
790

    
791
    sum = env->macc[acc];
792
    if (sum & (0xffffull << 48)) {
793
        env->macsr |= MACSR_V;
794
    }
795
    if (env->macsr & MACSR_V) {
796
        env->macsr |= MACSR_PAV0 << acc;
797
        if (env->macsr & MACSR_OMC) {
798
            if (sum > (1ull << 53))
799
                sum = 0;
800
            else
801
                sum = (1ull << 48) - 1;
802
        } else {
803
            sum &= ((1ull << 48) - 1);
804
        }
805
    }
806
    FORCE_RET();
807
}
808

    
809
OP(macsatf)
810
{
811
    int acc = PARAM1;
812
    int64_t sum;
813
    int64_t result;
814

    
815
    sum = env->macc[acc];
816
    result = (sum << 16) >> 16;
817
    if (result != sum) {
818
        env->macsr |= MACSR_V;
819
    }
820
    if (env->macsr & MACSR_V) {
821
        env->macsr |= MACSR_PAV0 << acc;
822
        if (env->macsr & MACSR_OMC) {
823
            result = (result >> 63) ^ 0x7fffffffffffll;
824
        }
825
    }
826
    env->macc[acc] = result;
827
    FORCE_RET();
828
}
829

    
830
OP(mac_clear_flags)
831
{
832
    env->macsr &= ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV);
833
}
834

    
835
OP(mac_set_flags)
836
{
837
    int acc = PARAM1;
838
    uint64_t val;
839
    val = env->macc[acc];
840
    if (val == 0)
841
        env->macsr |= MACSR_Z;
842
    else if (val & (1ull << 47));
843
        env->macsr |= MACSR_N;
844
    if (env->macsr & (MACSR_PAV0 << acc)) {
845
        env->macsr |= MACSR_V;
846
    }
847
    if (env->macsr & MACSR_FI) {
848
        val = ((int64_t)val) >> 40;
849
        if (val != 0 && val != -1)
850
            env->macsr |= MACSR_EV;
851
    } else if (env->macsr & MACSR_SU) {
852
        val = ((int64_t)val) >> 32;
853
        if (val != 0 && val != -1)
854
            env->macsr |= MACSR_EV;
855
    } else {
856
        if ((val >> 32) != 0)
857
            env->macsr |= MACSR_EV;
858
    }
859
    FORCE_RET();
860
}
861

    
862
OP(get_macf)
863
{
864
    int acc = PARAM2;
865
    int64_t val;
866
    int rem;
867
    uint32_t result;
868

    
869
    val = env->macc[acc];
870
    if (env->macsr & MACSR_SU) {
871
        /* 16-bit rounding.  */
872
        rem = val & 0xffffff;
873
        val = (val >> 24) & 0xffffu;
874
        if (rem > 0x800000)
875
            val++;
876
        else if (rem == 0x800000)
877
            val += (val & 1);
878
    } else if (env->macsr & MACSR_RT) {
879
        /* 32-bit rounding.  */
880
        rem = val & 0xff;
881
        val >>= 8;
882
        if (rem > 0x80)
883
            val++;
884
        else if (rem == 0x80)
885
            val += (val & 1);
886
    } else {
887
        /* No rounding.  */
888
        val >>= 8;
889
    }
890
    if (env->macsr & MACSR_OMC) {
891
        /* Saturate.  */
892
        if (env->macsr & MACSR_SU) {
893
            if (val != (uint16_t) val) {
894
                result = ((val >> 63) ^ 0x7fff) & 0xffff;
895
            } else {
896
                result = val & 0xffff;
897
            }
898
        } else {
899
            if (val != (uint32_t)val) {
900
                result = ((uint32_t)(val >> 63) & 0x7fffffff);
901
            } else {
902
                result = (uint32_t)val;
903
            }
904
        }
905
    } else {
906
        /* No saturation.  */
907
        if (env->macsr & MACSR_SU) {
908
            result = val & 0xffff;
909
        } else {
910
            result = (uint32_t)val;
911
        }
912
    }
913
    set_op(PARAM1, result);
914
    FORCE_RET();
915
}
916

    
917
OP(get_maci)
918
{
919
    int acc = PARAM2;
920
    set_op(PARAM1, (uint32_t)env->macc[acc]);
921
    FORCE_RET();
922
}
923

    
924
OP(get_macs)
925
{
926
    int acc = PARAM2;
927
    int64_t val = env->macc[acc];
928
    uint32_t result;
929
    if (val == (int32_t)val) {
930
        result = (int32_t)val;
931
    } else {
932
        result = (val >> 61) ^ 0x7fffffff;
933
    }
934
    set_op(PARAM1, result);
935
    FORCE_RET();
936
}
937

    
938
OP(get_macu)
939
{
940
    int acc = PARAM2;
941
    uint64_t val = env->macc[acc];
942
    uint32_t result;
943
    if ((val >> 32) == 0) {
944
        result = (uint32_t)val;
945
    } else {
946
        result = 0xffffffffu;
947
    }
948
    set_op(PARAM1, result);
949
    FORCE_RET();
950
}
951

    
952
OP(clear_mac)
953
{
954
    int acc = PARAM1;
955

    
956
    env->macc[acc] = 0;
957
    env->macsr &= ~(MACSR_PAV0 << acc);
958
    FORCE_RET();
959
}
960

    
961
OP(move_mac)
962
{
963
    int dest = PARAM1;
964
    int src = PARAM2;
965
    uint32_t mask;
966
    env->macc[dest] = env->macc[src];
967
    mask = MACSR_PAV0 << dest;
968
    if (env->macsr & (MACSR_PAV0 << src))
969
        env->macsr |= mask;
970
    else
971
        env->macsr &= ~mask;
972
    FORCE_RET();
973
}
974

    
975
OP(get_mac_extf)
976
{
977
    uint32_t val;
978
    int acc = PARAM2;
979
    val = env->macc[acc] & 0x00ff;
980
    val = (env->macc[acc] >> 32) & 0xff00;
981
    val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
982
    val |= (env->macc[acc + 1] >> 16) & 0xff000000;
983
    set_op(PARAM1, val);
984
    FORCE_RET();
985
}
986

    
987
OP(get_mac_exti)
988
{
989
    uint32_t val;
990
    int acc = PARAM2;
991
    val = (env->macc[acc] >> 32) & 0xffff;
992
    val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
993
    set_op(PARAM1, val);
994
    FORCE_RET();
995
}
996

    
997
OP(set_macf)
998
{
999
    int acc = PARAM2;
1000
    int32_t val = get_op(PARAM1);
1001
    env->macc[acc] = ((int64_t)val) << 8;
1002
    env->macsr &= ~(MACSR_PAV0 << acc);
1003
    FORCE_RET();
1004
}
1005

    
1006
OP(set_macs)
1007
{
1008
    int acc = PARAM2;
1009
    int32_t val = get_op(PARAM1);
1010
    env->macc[acc] = val;
1011
    env->macsr &= ~(MACSR_PAV0 << acc);
1012
    FORCE_RET();
1013
}
1014

    
1015
OP(set_macu)
1016
{
1017
    int acc = PARAM2;
1018
    uint32_t val = get_op(PARAM1);
1019
    env->macc[acc] = val;
1020
    env->macsr &= ~(MACSR_PAV0 << acc);
1021
    FORCE_RET();
1022
}
1023

    
1024
OP(set_mac_extf)
1025
{
1026
    int acc = PARAM2;
1027
    int32_t val = get_op(PARAM1);
1028
    int64_t res;
1029
    int32_t tmp;
1030
    res = env->macc[acc] & 0xffffffff00ull;
1031
    tmp = (int16_t)(val & 0xff00);
1032
    res |= ((int64_t)tmp) << 32;
1033
    res |= val & 0xff;
1034
    env->macc[acc] = res;
1035
    res = env->macc[acc + 1] & 0xffffffff00ull;
1036
    tmp = (val & 0xff000000);
1037
    res |= ((int64_t)tmp) << 16;
1038
    res |= (val >> 16) & 0xff;
1039
    env->macc[acc + 1] = res;
1040
}
1041

    
1042
OP(set_mac_exts)
1043
{
1044
    int acc = PARAM2;
1045
    int32_t val = get_op(PARAM1);
1046
    int64_t res;
1047
    int32_t tmp;
1048
    res = (uint32_t)env->macc[acc];
1049
    tmp = (int16_t)val;
1050
    res |= ((int64_t)tmp) << 32;
1051
    env->macc[acc] = res;
1052
    res = (uint32_t)env->macc[acc + 1];
1053
    tmp = val & 0xffff0000;
1054
    res |= (int64_t)tmp << 16;
1055
    env->macc[acc + 1] = res;
1056
}
1057

    
1058
OP(set_mac_extu)
1059
{
1060
    int acc = PARAM2;
1061
    int32_t val = get_op(PARAM1);
1062
    uint64_t res;
1063
    res = (uint32_t)env->macc[acc];
1064
    res |= ((uint64_t)(val & 0xffff)) << 32;
1065
    env->macc[acc] = res;
1066
    res = (uint32_t)env->macc[acc + 1];
1067
    res |= (uint64_t)(val & 0xffff0000) << 16;
1068
    env->macc[acc + 1] = res;
1069
}
1070

    
1071
OP(set_macsr)
1072
{
1073
    m68k_set_macsr(env, get_op(PARAM1));
1074
}