MCF5208 emulation.
[qemu] / target-m68k / op.c
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     int cc_op  = PARAM1;
342     if (cc_op == CC_OP_DYNAMIC)
343         cc_op = env->cc_op;
344     cpu_m68k_flush_flags(env, cc_op);
345     FORCE_RET();
346 }
347
348 OP(divu)
349 {
350     uint32_t num;
351     uint32_t den;
352     uint32_t quot;
353     uint32_t rem;
354     uint32_t flags;
355     
356     num = env->div1;
357     den = env->div2;
358     /* ??? This needs to make sure the throwing location is accurate.  */
359     if (den == 0)
360         RAISE_EXCEPTION(EXCP_DIV0);
361     quot = num / den;
362     rem = num % den;
363     flags = 0;
364     /* Avoid using a PARAM1 of zero.  This breaks dyngen because it uses
365        the address of a symbol, and gcc knows symbols can't have address
366        zero.  */
367     if (PARAM1 == 2 && quot > 0xffff)
368         flags |= CCF_V;
369     if (quot == 0)
370         flags |= CCF_Z;
371     else if ((int32_t)quot < 0)
372         flags |= CCF_N;
373     env->div1 = quot;
374     env->div2 = rem;
375     env->cc_dest = flags;
376     FORCE_RET();
377 }
378
379 OP(divs)
380 {
381     int32_t num;
382     int32_t den;
383     int32_t quot;
384     int32_t rem;
385     int32_t flags;
386     
387     num = env->div1;
388     den = env->div2;
389     if (den == 0)
390         RAISE_EXCEPTION(EXCP_DIV0);
391     quot = num / den;
392     rem = num % den;
393     flags = 0;
394     if (PARAM1 == 2 && quot != (int16_t)quot)
395         flags |= CCF_V;
396     if (quot == 0)
397         flags |= CCF_Z;
398     else if (quot < 0)
399         flags |= CCF_N;
400     env->div1 = quot;
401     env->div2 = rem;
402     env->cc_dest = flags;
403     FORCE_RET();
404 }
405
406 /* Halt is special because it may be a semihosting call.  */
407 OP(halt)
408 {
409     RAISE_EXCEPTION(EXCP_HALT_INSN);
410     FORCE_RET();
411 }
412
413 OP(stop)
414 {
415     env->halted = 1;
416     RAISE_EXCEPTION(EXCP_HLT);
417     FORCE_RET();
418 }
419
420 OP(raise_exception)
421 {
422     RAISE_EXCEPTION(PARAM1);
423     FORCE_RET();
424 }
425
426 /* Floating point comparison sets flags differently to other instructions.  */
427
428 OP(sub_cmpf64)
429 {
430     float64 src0;
431     float64 src1;
432     src0 = get_opf64(PARAM2);
433     src1 = get_opf64(PARAM3);
434     set_opf64(PARAM1, helper_sub_cmpf64(env, src0, src1));
435     FORCE_RET();
436 }
437
438 OP(update_xflag_tst)
439 {
440     uint32_t op1 = get_op(PARAM1);
441     env->cc_x = op1;
442     FORCE_RET();
443 }
444
445 OP(update_xflag_lt)
446 {
447     uint32_t op1 = get_op(PARAM1);
448     uint32_t op2 = get_op(PARAM2);
449     env->cc_x = (op1 < op2);
450     FORCE_RET();
451 }
452
453 OP(get_xflag)
454 {
455     set_op(PARAM1, env->cc_x);
456     FORCE_RET();
457 }
458
459 OP(logic_cc)
460 {
461     uint32_t op1 = get_op(PARAM1);
462     env->cc_dest = op1;
463     FORCE_RET();
464 }
465
466 OP(update_cc_add)
467 {
468     uint32_t op1 = get_op(PARAM1);
469     uint32_t op2 = get_op(PARAM2);
470     env->cc_dest = op1;
471     env->cc_src = op2;
472     FORCE_RET();
473 }
474
475 OP(fp_result)
476 {
477     env->fp_result = get_opf64(PARAM1);
478     FORCE_RET();
479 }
480
481 OP(set_sr)
482 {
483     env->sr = get_op(PARAM1);
484     m68k_switch_sp(env);
485     FORCE_RET();
486 }
487
488 OP(jmp)
489 {
490     GOTO_LABEL_PARAM(1);
491 }
492
493 /* These ops involve a function call, which probably requires a stack frame
494    and breaks things on some hosts.  */
495 OP(jmp_z32)
496 {
497     uint32_t arg = get_op(PARAM1);
498     if (arg == 0)
499         GOTO_LABEL_PARAM(2);
500     FORCE_RET();
501 }
502
503 OP(jmp_nz32)
504 {
505     uint32_t arg = get_op(PARAM1);
506     if (arg != 0)
507         GOTO_LABEL_PARAM(2);
508     FORCE_RET();
509 }
510
511 OP(jmp_s32)
512 {
513     int32_t arg = get_op(PARAM1);
514     if (arg < 0)
515         GOTO_LABEL_PARAM(2);
516     FORCE_RET();
517 }
518
519 OP(jmp_ns32)
520 {
521     int32_t arg = get_op(PARAM1);
522     if (arg >= 0)
523         GOTO_LABEL_PARAM(2);
524     FORCE_RET();
525 }
526
527 void OPPROTO op_goto_tb0(void)
528 {
529     GOTO_TB(op_goto_tb0, PARAM1, 0);
530 }
531
532 void OPPROTO op_goto_tb1(void)
533 {
534     GOTO_TB(op_goto_tb1, PARAM1, 1);
535 }
536
537 OP(exit_tb)
538 {
539     EXIT_TB();
540 }
541
542
543 /* Floating point.  */
544 OP(f64_to_i32)
545 {
546     set_op(PARAM1, float64_to_int32(get_opf64(PARAM2), &CPU_FP_STATUS));
547     FORCE_RET();
548 }
549
550 OP(f64_to_f32)
551 {
552     union {
553         float32 f;
554         uint32_t i;
555     } u;
556     u.f = float64_to_float32(get_opf64(PARAM2), &CPU_FP_STATUS);
557     set_op(PARAM1, u.i);
558     FORCE_RET();
559 }
560
561 OP(i32_to_f64)
562 {
563     set_opf64(PARAM1, int32_to_float64(get_op(PARAM2), &CPU_FP_STATUS));
564     FORCE_RET();
565 }
566
567 OP(f32_to_f64)
568 {
569     union {
570         float32 f;
571         uint32_t i;
572     } u;
573     u.i = get_op(PARAM2);
574     set_opf64(PARAM1, float32_to_float64(u.f, &CPU_FP_STATUS));
575     FORCE_RET();
576 }
577
578 OP(absf64)
579 {
580     float64 op0 = get_opf64(PARAM2);
581     set_opf64(PARAM1, float64_abs(op0));
582     FORCE_RET();
583 }
584
585 OP(chsf64)
586 {
587     float64 op0 = get_opf64(PARAM2);
588     set_opf64(PARAM1, float64_chs(op0));
589     FORCE_RET();
590 }
591
592 OP(sqrtf64)
593 {
594     float64 op0 = get_opf64(PARAM2);
595     set_opf64(PARAM1, float64_sqrt(op0, &CPU_FP_STATUS));
596     FORCE_RET();
597 }
598
599 OP(addf64)
600 {
601     float64 op0 = get_opf64(PARAM2);
602     float64 op1 = get_opf64(PARAM3);
603     set_opf64(PARAM1, float64_add(op0, op1, &CPU_FP_STATUS));
604     FORCE_RET();
605 }
606
607 OP(subf64)
608 {
609     float64 op0 = get_opf64(PARAM2);
610     float64 op1 = get_opf64(PARAM3);
611     set_opf64(PARAM1, float64_sub(op0, op1, &CPU_FP_STATUS));
612     FORCE_RET();
613 }
614
615 OP(mulf64)
616 {
617     float64 op0 = get_opf64(PARAM2);
618     float64 op1 = get_opf64(PARAM3);
619     set_opf64(PARAM1, float64_mul(op0, op1, &CPU_FP_STATUS));
620     FORCE_RET();
621 }
622
623 OP(divf64)
624 {
625     float64 op0 = get_opf64(PARAM2);
626     float64 op1 = get_opf64(PARAM3);
627     set_opf64(PARAM1, float64_div(op0, op1, &CPU_FP_STATUS));
628     FORCE_RET();
629 }
630
631 OP(iround_f64)
632 {
633     float64 op0 = get_opf64(PARAM2);
634     set_opf64(PARAM1, float64_round_to_int(op0, &CPU_FP_STATUS));
635     FORCE_RET();
636 }
637
638 OP(itrunc_f64)
639 {
640     float64 op0 = get_opf64(PARAM2);
641     set_opf64(PARAM1, float64_trunc_to_int(op0, &CPU_FP_STATUS));
642     FORCE_RET();
643 }
644
645 OP(compare_quietf64)
646 {
647     float64 op0 = get_opf64(PARAM2);
648     float64 op1 = get_opf64(PARAM3);
649     set_op(PARAM1, float64_compare_quiet(op0, op1, &CPU_FP_STATUS));
650     FORCE_RET();
651 }
652
653 OP(movec)
654 {
655     int op1 = get_op(PARAM1);
656     uint32_t op2 = get_op(PARAM2);
657     helper_movec(env, op1, op2);
658 }
659
660 /* Memory access.  */
661
662 #define MEMSUFFIX _raw
663 #include "op_mem.h"
664
665 #if !defined(CONFIG_USER_ONLY)
666 #define MEMSUFFIX _user
667 #include "op_mem.h"
668 #define MEMSUFFIX _kernel
669 #include "op_mem.h"
670 #endif
671
672 /* MAC unit.  */
673 /* TODO: The MAC instructions use 64-bit arithmetic fairly extensively.
674    This results in fairly large ops (and sometimes other issues) on 32-bit
675    hosts.  Maybe move most of them into helpers.  */
676 OP(macmuls)
677 {
678     uint32_t op1 = get_op(PARAM1);
679     uint32_t op2 = get_op(PARAM2);
680     int64_t product;
681     int64_t res;
682
683     product = (uint64_t)op1 * op2;
684     res = (product << 24) >> 24;
685     if (res != product) {
686         env->macsr |= MACSR_V;
687         if (env->macsr & MACSR_OMC) {
688             /* Make sure the accumulate operation overflows.  */
689             if (product < 0)
690                 res = ~(1ll << 50);
691             else
692                 res = 1ll << 50;
693         }
694     }
695     env->mactmp = res;
696     FORCE_RET();
697 }
698
699 OP(macmulu)
700 {
701     uint32_t op1 = get_op(PARAM1);
702     uint32_t op2 = get_op(PARAM2);
703     uint64_t product;
704
705     product = (uint64_t)op1 * op2;
706     if (product & (0xffffffull << 40)) {
707         env->macsr |= MACSR_V;
708         if (env->macsr & MACSR_OMC) {
709             /* Make sure the accumulate operation overflows.  */
710             product = 1ll << 50;
711         } else {
712             product &= ((1ull << 40) - 1);
713         }
714     }
715     env->mactmp = product;
716     FORCE_RET();
717 }
718
719 OP(macmulf)
720 {
721     int32_t op1 = get_op(PARAM1);
722     int32_t op2 = get_op(PARAM2);
723     uint64_t product;
724     uint32_t remainder;
725
726     product = (uint64_t)op1 * op2;
727     if (env->macsr & MACSR_RT) {
728         remainder = product & 0xffffff;
729         product >>= 24;
730         if (remainder > 0x800000)
731             product++;
732         else if (remainder == 0x800000)
733             product += (product & 1);
734     } else {
735         product >>= 24;
736     }
737     env->mactmp = product;
738     FORCE_RET();
739 }
740
741 OP(macshl)
742 {
743     env->mactmp <<= 1;
744 }
745
746 OP(macshr)
747 {
748     env->mactmp >>= 1;
749 }
750
751 OP(macadd)
752 {
753     int acc = PARAM1;
754     env->macc[acc] += env->mactmp;
755     FORCE_RET();
756 }
757
758 OP(macsub)
759 {
760     int acc = PARAM1;
761     env->macc[acc] -= env->mactmp;
762     FORCE_RET();
763 }
764
765 OP(macsats)
766 {
767     int acc = PARAM1;
768     int64_t sum;
769     int64_t result;
770
771     sum = env->macc[acc];
772     result = (sum << 16) >> 16;
773     if (result != sum) {
774         env->macsr |= MACSR_V;
775     }
776     if (env->macsr & MACSR_V) {
777         env->macsr |= MACSR_PAV0 << acc;
778         if (env->macsr & MACSR_OMC) {
779             /* The result is saturated to 32 bits, despite overflow occuring
780                at 48 bits.  Seems weird, but that's what the hardware docs
781                say.  */
782             result = (result >> 63) ^ 0x7fffffff;
783         }
784     }
785     env->macc[acc] = result;
786     FORCE_RET();
787 }
788
789 OP(macsatu)
790 {
791     int acc = PARAM1;
792     uint64_t sum;
793
794     sum = env->macc[acc];
795     if (sum & (0xffffull << 48)) {
796         env->macsr |= MACSR_V;
797     }
798     if (env->macsr & MACSR_V) {
799         env->macsr |= MACSR_PAV0 << acc;
800         if (env->macsr & MACSR_OMC) {
801             if (sum > (1ull << 53))
802                 sum = 0;
803             else
804                 sum = (1ull << 48) - 1;
805         } else {
806             sum &= ((1ull << 48) - 1);
807         }
808     }
809     FORCE_RET();
810 }
811
812 OP(macsatf)
813 {
814     int acc = PARAM1;
815     int64_t sum;
816     int64_t result;
817
818     sum = env->macc[acc];
819     result = (sum << 16) >> 16;
820     if (result != sum) {
821         env->macsr |= MACSR_V;
822     }
823     if (env->macsr & MACSR_V) {
824         env->macsr |= MACSR_PAV0 << acc;
825         if (env->macsr & MACSR_OMC) {
826             result = (result >> 63) ^ 0x7fffffffffffll;
827         }
828     }
829     env->macc[acc] = result;
830     FORCE_RET();
831 }
832
833 OP(mac_clear_flags)
834 {
835     env->macsr &= ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV);
836 }
837
838 OP(mac_set_flags)
839 {
840     int acc = PARAM1;
841     uint64_t val;
842     val = env->macc[acc];
843     if (val == 0)
844         env->macsr |= MACSR_Z;
845     else if (val & (1ull << 47));
846         env->macsr |= MACSR_N;
847     if (env->macsr & (MACSR_PAV0 << acc)) {
848         env->macsr |= MACSR_V;
849     }
850     if (env->macsr & MACSR_FI) {
851         val = ((int64_t)val) >> 40;
852         if (val != 0 && val != -1)
853             env->macsr |= MACSR_EV;
854     } else if (env->macsr & MACSR_SU) {
855         val = ((int64_t)val) >> 32;
856         if (val != 0 && val != -1)
857             env->macsr |= MACSR_EV;
858     } else {
859         if ((val >> 32) != 0)
860             env->macsr |= MACSR_EV;
861     }
862     FORCE_RET();
863 }
864
865 OP(get_macf)
866 {
867     int acc = PARAM2;
868     int64_t val;
869     int rem;
870     uint32_t result;
871
872     val = env->macc[acc];
873     if (env->macsr & MACSR_SU) {
874         /* 16-bit rounding.  */
875         rem = val & 0xffffff;
876         val = (val >> 24) & 0xffffu;
877         if (rem > 0x800000)
878             val++;
879         else if (rem == 0x800000)
880             val += (val & 1);
881     } else if (env->macsr & MACSR_RT) {
882         /* 32-bit rounding.  */
883         rem = val & 0xff;
884         val >>= 8;
885         if (rem > 0x80)
886             val++;
887         else if (rem == 0x80)
888             val += (val & 1);
889     } else {
890         /* No rounding.  */
891         val >>= 8;
892     }
893     if (env->macsr & MACSR_OMC) {
894         /* Saturate.  */
895         if (env->macsr & MACSR_SU) {
896             if (val != (uint16_t) val) {
897                 result = ((val >> 63) ^ 0x7fff) & 0xffff;
898             } else {
899                 result = val & 0xffff;
900             }
901         } else {
902             if (val != (uint32_t)val) {
903                 result = ((uint32_t)(val >> 63) & 0x7fffffff);
904             } else {
905                 result = (uint32_t)val;
906             }
907         }
908     } else {
909         /* No saturation.  */
910         if (env->macsr & MACSR_SU) {
911             result = val & 0xffff;
912         } else {
913             result = (uint32_t)val;
914         }
915     }
916     set_op(PARAM1, result);
917     FORCE_RET();
918 }
919
920 OP(get_maci)
921 {
922     int acc = PARAM2;
923     set_op(PARAM1, (uint32_t)env->macc[acc]);
924     FORCE_RET();
925 }
926
927 OP(get_macs)
928 {
929     int acc = PARAM2;
930     int64_t val = env->macc[acc];
931     uint32_t result;
932     if (val == (int32_t)val) {
933         result = (int32_t)val;
934     } else {
935         result = (val >> 61) ^ 0x7fffffff;
936     }
937     set_op(PARAM1, result);
938     FORCE_RET();
939 }
940
941 OP(get_macu)
942 {
943     int acc = PARAM2;
944     uint64_t val = env->macc[acc];
945     uint32_t result;
946     if ((val >> 32) == 0) {
947         result = (uint32_t)val;
948     } else {
949         result = 0xffffffffu;
950     }
951     set_op(PARAM1, result);
952     FORCE_RET();
953 }
954
955 OP(clear_mac)
956 {
957     int acc = PARAM1;
958
959     env->macc[acc] = 0;
960     env->macsr &= ~(MACSR_PAV0 << acc);
961     FORCE_RET();
962 }
963
964 OP(move_mac)
965 {
966     int dest = PARAM1;
967     int src = PARAM2;
968     uint32_t mask;
969     env->macc[dest] = env->macc[src];
970     mask = MACSR_PAV0 << dest;
971     if (env->macsr & (MACSR_PAV0 << src))
972         env->macsr |= mask;
973     else
974         env->macsr &= ~mask;
975     FORCE_RET();
976 }
977
978 OP(get_mac_extf)
979 {
980     uint32_t val;
981     int acc = PARAM2;
982     val = env->macc[acc] & 0x00ff;
983     val = (env->macc[acc] >> 32) & 0xff00;
984     val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
985     val |= (env->macc[acc + 1] >> 16) & 0xff000000;
986     set_op(PARAM1, val);
987     FORCE_RET();
988 }
989
990 OP(get_mac_exti)
991 {
992     uint32_t val;
993     int acc = PARAM2;
994     val = (env->macc[acc] >> 32) & 0xffff;
995     val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
996     set_op(PARAM1, val);
997     FORCE_RET();
998 }
999
1000 OP(set_macf)
1001 {
1002     int acc = PARAM2;
1003     int32_t val = get_op(PARAM1);
1004     env->macc[acc] = ((int64_t)val) << 8;
1005     env->macsr &= ~(MACSR_PAV0 << acc);
1006     FORCE_RET();
1007 }
1008
1009 OP(set_macs)
1010 {
1011     int acc = PARAM2;
1012     int32_t val = get_op(PARAM1);
1013     env->macc[acc] = val;
1014     env->macsr &= ~(MACSR_PAV0 << acc);
1015     FORCE_RET();
1016 }
1017
1018 OP(set_macu)
1019 {
1020     int acc = PARAM2;
1021     uint32_t val = get_op(PARAM1);
1022     env->macc[acc] = val;
1023     env->macsr &= ~(MACSR_PAV0 << acc);
1024     FORCE_RET();
1025 }
1026
1027 OP(set_mac_extf)
1028 {
1029     int acc = PARAM2;
1030     int32_t val = get_op(PARAM1);
1031     int64_t res;
1032     int32_t tmp;
1033     res = env->macc[acc] & 0xffffffff00ull;
1034     tmp = (int16_t)(val & 0xff00);
1035     res |= ((int64_t)tmp) << 32;
1036     res |= val & 0xff;
1037     env->macc[acc] = res;
1038     res = env->macc[acc + 1] & 0xffffffff00ull;
1039     tmp = (val & 0xff000000);
1040     res |= ((int64_t)tmp) << 16;
1041     res |= (val >> 16) & 0xff;
1042     env->macc[acc + 1] = res;
1043 }
1044
1045 OP(set_mac_exts)
1046 {
1047     int acc = PARAM2;
1048     int32_t val = get_op(PARAM1);
1049     int64_t res;
1050     int32_t tmp;
1051     res = (uint32_t)env->macc[acc];
1052     tmp = (int16_t)val;
1053     res |= ((int64_t)tmp) << 32;
1054     env->macc[acc] = res;
1055     res = (uint32_t)env->macc[acc + 1];
1056     tmp = val & 0xffff0000;
1057     res |= (int64_t)tmp << 16;
1058     env->macc[acc + 1] = res;
1059 }
1060
1061 OP(set_mac_extu)
1062 {
1063     int acc = PARAM2;
1064     int32_t val = get_op(PARAM1);
1065     uint64_t res;
1066     res = (uint32_t)env->macc[acc];
1067     res |= ((uint64_t)(val & 0xffff)) << 32;
1068     env->macc[acc] = res;
1069     res = (uint32_t)env->macc[acc + 1];
1070     res |= (uint64_t)(val & 0xffff0000) << 16;
1071     env->macc[acc + 1] = res;
1072 }
1073
1074 OP(set_macsr)
1075 {
1076     m68k_set_macsr(env, get_op(PARAM1));
1077 }