use the TCG code generator
[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, float64_zero);
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_im)
486 {
487     GOTO_LABEL_PARAM(1);
488 }
489
490 OP(set_T0_z32)
491 {
492     uint32_t arg = get_op(PARAM1);
493     T0 = (arg == 0);
494     FORCE_RET();
495 }
496
497 OP(set_T0_nz32)
498 {
499     uint32_t arg = get_op(PARAM1);
500     T0 = (arg != 0);
501     FORCE_RET();
502 }
503
504 OP(set_T0_s32)
505 {
506     int32_t arg = get_op(PARAM1);
507     T0 = (arg > 0);
508     FORCE_RET();
509 }
510
511 OP(set_T0_ns32)
512 {
513     int32_t arg = get_op(PARAM1);
514     T0 = (arg >= 0);
515     FORCE_RET();
516 }
517
518 OP(jmp_T0)
519 {
520     if (T0)
521         GOTO_LABEL_PARAM(1);
522     FORCE_RET();
523 }
524
525 /* Floating point.  */
526 OP(f64_to_i32)
527 {
528     set_op(PARAM1, float64_to_int32(get_opf64(PARAM2), &CPU_FP_STATUS));
529     FORCE_RET();
530 }
531
532 OP(f64_to_f32)
533 {
534     union {
535         float32 f;
536         uint32_t i;
537     } u;
538     u.f = float64_to_float32(get_opf64(PARAM2), &CPU_FP_STATUS);
539     set_op(PARAM1, u.i);
540     FORCE_RET();
541 }
542
543 OP(i32_to_f64)
544 {
545     set_opf64(PARAM1, int32_to_float64(get_op(PARAM2), &CPU_FP_STATUS));
546     FORCE_RET();
547 }
548
549 OP(f32_to_f64)
550 {
551     union {
552         float32 f;
553         uint32_t i;
554     } u;
555     u.i = get_op(PARAM2);
556     set_opf64(PARAM1, float32_to_float64(u.f, &CPU_FP_STATUS));
557     FORCE_RET();
558 }
559
560 OP(absf64)
561 {
562     float64 op0 = get_opf64(PARAM2);
563     set_opf64(PARAM1, float64_abs(op0));
564     FORCE_RET();
565 }
566
567 OP(chsf64)
568 {
569     float64 op0 = get_opf64(PARAM2);
570     set_opf64(PARAM1, float64_chs(op0));
571     FORCE_RET();
572 }
573
574 OP(sqrtf64)
575 {
576     float64 op0 = get_opf64(PARAM2);
577     set_opf64(PARAM1, float64_sqrt(op0, &CPU_FP_STATUS));
578     FORCE_RET();
579 }
580
581 OP(addf64)
582 {
583     float64 op0 = get_opf64(PARAM2);
584     float64 op1 = get_opf64(PARAM3);
585     set_opf64(PARAM1, float64_add(op0, op1, &CPU_FP_STATUS));
586     FORCE_RET();
587 }
588
589 OP(subf64)
590 {
591     float64 op0 = get_opf64(PARAM2);
592     float64 op1 = get_opf64(PARAM3);
593     set_opf64(PARAM1, float64_sub(op0, op1, &CPU_FP_STATUS));
594     FORCE_RET();
595 }
596
597 OP(mulf64)
598 {
599     float64 op0 = get_opf64(PARAM2);
600     float64 op1 = get_opf64(PARAM3);
601     set_opf64(PARAM1, float64_mul(op0, op1, &CPU_FP_STATUS));
602     FORCE_RET();
603 }
604
605 OP(divf64)
606 {
607     float64 op0 = get_opf64(PARAM2);
608     float64 op1 = get_opf64(PARAM3);
609     set_opf64(PARAM1, float64_div(op0, op1, &CPU_FP_STATUS));
610     FORCE_RET();
611 }
612
613 OP(iround_f64)
614 {
615     float64 op0 = get_opf64(PARAM2);
616     set_opf64(PARAM1, float64_round_to_int(op0, &CPU_FP_STATUS));
617     FORCE_RET();
618 }
619
620 OP(itrunc_f64)
621 {
622     float64 op0 = get_opf64(PARAM2);
623     set_opf64(PARAM1, float64_trunc_to_int(op0, &CPU_FP_STATUS));
624     FORCE_RET();
625 }
626
627 OP(compare_quietf64)
628 {
629     float64 op0 = get_opf64(PARAM2);
630     float64 op1 = get_opf64(PARAM3);
631     set_op(PARAM1, float64_compare_quiet(op0, op1, &CPU_FP_STATUS));
632     FORCE_RET();
633 }
634
635 OP(movec)
636 {
637     int op1 = get_op(PARAM1);
638     uint32_t op2 = get_op(PARAM2);
639     helper_movec(env, op1, op2);
640 }
641
642 /* Memory access.  */
643
644 #define MEMSUFFIX _raw
645 #include "op_mem.h"
646
647 #if !defined(CONFIG_USER_ONLY)
648 #define MEMSUFFIX _user
649 #include "op_mem.h"
650 #define MEMSUFFIX _kernel
651 #include "op_mem.h"
652 #endif
653
654 /* MAC unit.  */
655 /* TODO: The MAC instructions use 64-bit arithmetic fairly extensively.
656    This results in fairly large ops (and sometimes other issues) on 32-bit
657    hosts.  Maybe move most of them into helpers.  */
658 OP(macmuls)
659 {
660     uint32_t op1 = get_op(PARAM1);
661     uint32_t op2 = get_op(PARAM2);
662     int64_t product;
663     int64_t res;
664
665     product = (uint64_t)op1 * op2;
666     res = (product << 24) >> 24;
667     if (res != product) {
668         env->macsr |= MACSR_V;
669         if (env->macsr & MACSR_OMC) {
670             /* Make sure the accumulate operation overflows.  */
671             if (product < 0)
672                 res = ~(1ll << 50);
673             else
674                 res = 1ll << 50;
675         }
676     }
677     env->mactmp = res;
678     FORCE_RET();
679 }
680
681 OP(macmulu)
682 {
683     uint32_t op1 = get_op(PARAM1);
684     uint32_t op2 = get_op(PARAM2);
685     uint64_t product;
686
687     product = (uint64_t)op1 * op2;
688     if (product & (0xffffffull << 40)) {
689         env->macsr |= MACSR_V;
690         if (env->macsr & MACSR_OMC) {
691             /* Make sure the accumulate operation overflows.  */
692             product = 1ll << 50;
693         } else {
694             product &= ((1ull << 40) - 1);
695         }
696     }
697     env->mactmp = product;
698     FORCE_RET();
699 }
700
701 OP(macmulf)
702 {
703     int32_t op1 = get_op(PARAM1);
704     int32_t op2 = get_op(PARAM2);
705     uint64_t product;
706     uint32_t remainder;
707
708     product = (uint64_t)op1 * op2;
709     if (env->macsr & MACSR_RT) {
710         remainder = product & 0xffffff;
711         product >>= 24;
712         if (remainder > 0x800000)
713             product++;
714         else if (remainder == 0x800000)
715             product += (product & 1);
716     } else {
717         product >>= 24;
718     }
719     env->mactmp = product;
720     FORCE_RET();
721 }
722
723 OP(macshl)
724 {
725     env->mactmp <<= 1;
726 }
727
728 OP(macshr)
729 {
730     env->mactmp >>= 1;
731 }
732
733 OP(macadd)
734 {
735     int acc = PARAM1;
736     env->macc[acc] += env->mactmp;
737     FORCE_RET();
738 }
739
740 OP(macsub)
741 {
742     int acc = PARAM1;
743     env->macc[acc] -= env->mactmp;
744     FORCE_RET();
745 }
746
747 OP(macsats)
748 {
749     int acc = PARAM1;
750     int64_t sum;
751     int64_t result;
752
753     sum = env->macc[acc];
754     result = (sum << 16) >> 16;
755     if (result != sum) {
756         env->macsr |= MACSR_V;
757     }
758     if (env->macsr & MACSR_V) {
759         env->macsr |= MACSR_PAV0 << acc;
760         if (env->macsr & MACSR_OMC) {
761             /* The result is saturated to 32 bits, despite overflow occuring
762                at 48 bits.  Seems weird, but that's what the hardware docs
763                say.  */
764             result = (result >> 63) ^ 0x7fffffff;
765         }
766     }
767     env->macc[acc] = result;
768     FORCE_RET();
769 }
770
771 OP(macsatu)
772 {
773     int acc = PARAM1;
774     uint64_t sum;
775
776     sum = env->macc[acc];
777     if (sum & (0xffffull << 48)) {
778         env->macsr |= MACSR_V;
779     }
780     if (env->macsr & MACSR_V) {
781         env->macsr |= MACSR_PAV0 << acc;
782         if (env->macsr & MACSR_OMC) {
783             if (sum > (1ull << 53))
784                 sum = 0;
785             else
786                 sum = (1ull << 48) - 1;
787         } else {
788             sum &= ((1ull << 48) - 1);
789         }
790     }
791     FORCE_RET();
792 }
793
794 OP(macsatf)
795 {
796     int acc = PARAM1;
797     int64_t sum;
798     int64_t result;
799
800     sum = env->macc[acc];
801     result = (sum << 16) >> 16;
802     if (result != sum) {
803         env->macsr |= MACSR_V;
804     }
805     if (env->macsr & MACSR_V) {
806         env->macsr |= MACSR_PAV0 << acc;
807         if (env->macsr & MACSR_OMC) {
808             result = (result >> 63) ^ 0x7fffffffffffll;
809         }
810     }
811     env->macc[acc] = result;
812     FORCE_RET();
813 }
814
815 OP(mac_clear_flags)
816 {
817     env->macsr &= ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV);
818 }
819
820 OP(mac_set_flags)
821 {
822     int acc = PARAM1;
823     uint64_t val;
824     val = env->macc[acc];
825     if (val == 0)
826         env->macsr |= MACSR_Z;
827     else if (val & (1ull << 47));
828         env->macsr |= MACSR_N;
829     if (env->macsr & (MACSR_PAV0 << acc)) {
830         env->macsr |= MACSR_V;
831     }
832     if (env->macsr & MACSR_FI) {
833         val = ((int64_t)val) >> 40;
834         if (val != 0 && val != -1)
835             env->macsr |= MACSR_EV;
836     } else if (env->macsr & MACSR_SU) {
837         val = ((int64_t)val) >> 32;
838         if (val != 0 && val != -1)
839             env->macsr |= MACSR_EV;
840     } else {
841         if ((val >> 32) != 0)
842             env->macsr |= MACSR_EV;
843     }
844     FORCE_RET();
845 }
846
847 OP(get_macf)
848 {
849     int acc = PARAM2;
850     int64_t val;
851     int rem;
852     uint32_t result;
853
854     val = env->macc[acc];
855     if (env->macsr & MACSR_SU) {
856         /* 16-bit rounding.  */
857         rem = val & 0xffffff;
858         val = (val >> 24) & 0xffffu;
859         if (rem > 0x800000)
860             val++;
861         else if (rem == 0x800000)
862             val += (val & 1);
863     } else if (env->macsr & MACSR_RT) {
864         /* 32-bit rounding.  */
865         rem = val & 0xff;
866         val >>= 8;
867         if (rem > 0x80)
868             val++;
869         else if (rem == 0x80)
870             val += (val & 1);
871     } else {
872         /* No rounding.  */
873         val >>= 8;
874     }
875     if (env->macsr & MACSR_OMC) {
876         /* Saturate.  */
877         if (env->macsr & MACSR_SU) {
878             if (val != (uint16_t) val) {
879                 result = ((val >> 63) ^ 0x7fff) & 0xffff;
880             } else {
881                 result = val & 0xffff;
882             }
883         } else {
884             if (val != (uint32_t)val) {
885                 result = ((uint32_t)(val >> 63) & 0x7fffffff);
886             } else {
887                 result = (uint32_t)val;
888             }
889         }
890     } else {
891         /* No saturation.  */
892         if (env->macsr & MACSR_SU) {
893             result = val & 0xffff;
894         } else {
895             result = (uint32_t)val;
896         }
897     }
898     set_op(PARAM1, result);
899     FORCE_RET();
900 }
901
902 OP(get_maci)
903 {
904     int acc = PARAM2;
905     set_op(PARAM1, (uint32_t)env->macc[acc]);
906     FORCE_RET();
907 }
908
909 OP(get_macs)
910 {
911     int acc = PARAM2;
912     int64_t val = env->macc[acc];
913     uint32_t result;
914     if (val == (int32_t)val) {
915         result = (int32_t)val;
916     } else {
917         result = (val >> 61) ^ 0x7fffffff;
918     }
919     set_op(PARAM1, result);
920     FORCE_RET();
921 }
922
923 OP(get_macu)
924 {
925     int acc = PARAM2;
926     uint64_t val = env->macc[acc];
927     uint32_t result;
928     if ((val >> 32) == 0) {
929         result = (uint32_t)val;
930     } else {
931         result = 0xffffffffu;
932     }
933     set_op(PARAM1, result);
934     FORCE_RET();
935 }
936
937 OP(clear_mac)
938 {
939     int acc = PARAM1;
940
941     env->macc[acc] = 0;
942     env->macsr &= ~(MACSR_PAV0 << acc);
943     FORCE_RET();
944 }
945
946 OP(move_mac)
947 {
948     int dest = PARAM1;
949     int src = PARAM2;
950     uint32_t mask;
951     env->macc[dest] = env->macc[src];
952     mask = MACSR_PAV0 << dest;
953     if (env->macsr & (MACSR_PAV0 << src))
954         env->macsr |= mask;
955     else
956         env->macsr &= ~mask;
957     FORCE_RET();
958 }
959
960 OP(get_mac_extf)
961 {
962     uint32_t val;
963     int acc = PARAM2;
964     val = env->macc[acc] & 0x00ff;
965     val = (env->macc[acc] >> 32) & 0xff00;
966     val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
967     val |= (env->macc[acc + 1] >> 16) & 0xff000000;
968     set_op(PARAM1, val);
969     FORCE_RET();
970 }
971
972 OP(get_mac_exti)
973 {
974     uint32_t val;
975     int acc = PARAM2;
976     val = (env->macc[acc] >> 32) & 0xffff;
977     val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
978     set_op(PARAM1, val);
979     FORCE_RET();
980 }
981
982 OP(set_macf)
983 {
984     int acc = PARAM2;
985     int32_t val = get_op(PARAM1);
986     env->macc[acc] = ((int64_t)val) << 8;
987     env->macsr &= ~(MACSR_PAV0 << acc);
988     FORCE_RET();
989 }
990
991 OP(set_macs)
992 {
993     int acc = PARAM2;
994     int32_t val = get_op(PARAM1);
995     env->macc[acc] = val;
996     env->macsr &= ~(MACSR_PAV0 << acc);
997     FORCE_RET();
998 }
999
1000 OP(set_macu)
1001 {
1002     int acc = PARAM2;
1003     uint32_t val = get_op(PARAM1);
1004     env->macc[acc] = val;
1005     env->macsr &= ~(MACSR_PAV0 << acc);
1006     FORCE_RET();
1007 }
1008
1009 OP(set_mac_extf)
1010 {
1011     int acc = PARAM2;
1012     int32_t val = get_op(PARAM1);
1013     int64_t res;
1014     int32_t tmp;
1015     res = env->macc[acc] & 0xffffffff00ull;
1016     tmp = (int16_t)(val & 0xff00);
1017     res |= ((int64_t)tmp) << 32;
1018     res |= val & 0xff;
1019     env->macc[acc] = res;
1020     res = env->macc[acc + 1] & 0xffffffff00ull;
1021     tmp = (val & 0xff000000);
1022     res |= ((int64_t)tmp) << 16;
1023     res |= (val >> 16) & 0xff;
1024     env->macc[acc + 1] = res;
1025 }
1026
1027 OP(set_mac_exts)
1028 {
1029     int acc = PARAM2;
1030     int32_t val = get_op(PARAM1);
1031     int64_t res;
1032     int32_t tmp;
1033     res = (uint32_t)env->macc[acc];
1034     tmp = (int16_t)val;
1035     res |= ((int64_t)tmp) << 32;
1036     env->macc[acc] = res;
1037     res = (uint32_t)env->macc[acc + 1];
1038     tmp = val & 0xffff0000;
1039     res |= (int64_t)tmp << 16;
1040     env->macc[acc + 1] = res;
1041 }
1042
1043 OP(set_mac_extu)
1044 {
1045     int acc = PARAM2;
1046     int32_t val = get_op(PARAM1);
1047     uint64_t res;
1048     res = (uint32_t)env->macc[acc];
1049     res |= ((uint64_t)(val & 0xffff)) << 32;
1050     env->macc[acc] = res;
1051     res = (uint32_t)env->macc[acc + 1];
1052     res |= (uint64_t)(val & 0xffff0000) << 16;
1053     env->macc[acc + 1] = res;
1054 }
1055
1056 OP(set_macsr)
1057 {
1058     m68k_set_macsr(env, get_op(PARAM1));
1059 }