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