Fix swapped mvz/mvs instructions.
[qemu] / target-m68k / helper.c
1 /*
2  *  m68k op helpers
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 <stdio.h>
23 #include <string.h>
24
25 #include "config.h"
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "qemu-common.h"
29
30 #include "helpers.h"
31
32 #define SIGNBIT (1u << 31)
33
34 enum m68k_cpuid {
35     M68K_CPUID_M5206,
36     M68K_CPUID_M5208,
37     M68K_CPUID_CFV4E,
38     M68K_CPUID_ANY,
39 };
40
41 typedef struct m68k_def_t m68k_def_t;
42
43 struct m68k_def_t {
44     const char * name;
45     enum m68k_cpuid id;
46 };
47
48 static m68k_def_t m68k_cpu_defs[] = {
49     {"m5206", M68K_CPUID_M5206},
50     {"m5208", M68K_CPUID_M5208},
51     {"cfv4e", M68K_CPUID_CFV4E},
52     {"any", M68K_CPUID_ANY},
53     {NULL, 0},
54 };
55
56 static void m68k_set_feature(CPUM68KState *env, int feature)
57 {
58     env->features |= (1u << feature);
59 }
60
61 static int cpu_m68k_set_model(CPUM68KState *env, const char *name)
62 {
63     m68k_def_t *def;
64
65     for (def = m68k_cpu_defs; def->name; def++) {
66         if (strcmp(def->name, name) == 0)
67             break;
68     }
69     if (!def->name)
70         return -1;
71
72     switch (def->id) {
73     case M68K_CPUID_M5206:
74         m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
75         break;
76     case M68K_CPUID_M5208:
77         m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
78         m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
79         m68k_set_feature(env, M68K_FEATURE_BRAL);
80         m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
81         m68k_set_feature(env, M68K_FEATURE_USP);
82         break;
83     case M68K_CPUID_CFV4E:
84         m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
85         m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
86         m68k_set_feature(env, M68K_FEATURE_BRAL);
87         m68k_set_feature(env, M68K_FEATURE_CF_FPU);
88         m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
89         m68k_set_feature(env, M68K_FEATURE_USP);
90         break;
91     case M68K_CPUID_ANY:
92         m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
93         m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
94         m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
95         m68k_set_feature(env, M68K_FEATURE_BRAL);
96         m68k_set_feature(env, M68K_FEATURE_CF_FPU);
97         /* MAC and EMAC are mututally exclusive, so pick EMAC.
98            It's mostly backwards compatible.  */
99         m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
100         m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
101         m68k_set_feature(env, M68K_FEATURE_USP);
102         m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
103         m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
104         break;
105     }
106
107     register_m68k_insns(env);
108     return 0;
109 }
110
111 void cpu_reset(CPUM68KState *env)
112 {
113     memset(env, 0, offsetof(CPUM68KState, breakpoints));
114 #if !defined (CONFIG_USER_ONLY)
115     env->sr = 0x2700;
116 #endif
117     m68k_switch_sp(env);
118     /* ??? FP regs should be initialized to NaN.  */
119     env->cc_op = CC_OP_FLAGS;
120     /* TODO: We should set PC from the interrupt vector.  */
121     env->pc = 0;
122     tlb_flush(env, 1);
123 }
124
125 CPUM68KState *cpu_m68k_init(const char *cpu_model)
126 {
127     CPUM68KState *env;
128     static int inited;
129
130     env = malloc(sizeof(CPUM68KState));
131     if (!env)
132         return NULL;
133     cpu_exec_init(env);
134     if (!inited) {
135         inited = 1;
136         m68k_tcg_init();
137     }
138
139     env->cpu_model_str = cpu_model;
140
141     if (cpu_m68k_set_model(env, cpu_model) < 0) {
142         cpu_m68k_close(env);
143         return NULL;
144     }
145
146     cpu_reset(env);
147     return env;
148 }
149
150 void cpu_m68k_close(CPUM68KState *env)
151 {
152     qemu_free(env);
153 }
154
155 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
156 {
157     int flags;
158     uint32_t src;
159     uint32_t dest;
160     uint32_t tmp;
161
162 #define HIGHBIT 0x80000000u
163
164 #define SET_NZ(x) do { \
165     if ((x) == 0) \
166         flags |= CCF_Z; \
167     else if ((int32_t)(x) < 0) \
168         flags |= CCF_N; \
169     } while (0)
170
171 #define SET_FLAGS_SUB(type, utype) do { \
172     SET_NZ((type)dest); \
173     tmp = dest + src; \
174     if ((utype) tmp < (utype) src) \
175         flags |= CCF_C; \
176     if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \
177         flags |= CCF_V; \
178     } while (0)
179
180     flags = 0;
181     src = env->cc_src;
182     dest = env->cc_dest;
183     switch (cc_op) {
184     case CC_OP_FLAGS:
185         flags = dest;
186         break;
187     case CC_OP_LOGIC:
188         SET_NZ(dest);
189         break;
190     case CC_OP_ADD:
191         SET_NZ(dest);
192         if (dest < src)
193             flags |= CCF_C;
194         tmp = dest - src;
195         if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
196             flags |= CCF_V;
197         break;
198     case CC_OP_SUB:
199         SET_FLAGS_SUB(int32_t, uint32_t);
200         break;
201     case CC_OP_CMPB:
202         SET_FLAGS_SUB(int8_t, uint8_t);
203         break;
204     case CC_OP_CMPW:
205         SET_FLAGS_SUB(int16_t, uint16_t);
206         break;
207     case CC_OP_ADDX:
208         SET_NZ(dest);
209         if (dest <= src)
210             flags |= CCF_C;
211         tmp = dest - src - 1;
212         if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
213             flags |= CCF_V;
214         break;
215     case CC_OP_SUBX:
216         SET_NZ(dest);
217         tmp = dest + src + 1;
218         if (tmp <= src)
219             flags |= CCF_C;
220         if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
221             flags |= CCF_V;
222         break;
223     case CC_OP_SHIFT:
224         SET_NZ(dest);
225         if (src)
226             flags |= CCF_C;
227         break;
228     default:
229         cpu_abort(env, "Bad CC_OP %d", cc_op);
230     }
231     env->cc_op = CC_OP_FLAGS;
232     env->cc_dest = flags;
233 }
234
235 void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
236 {
237     switch (reg) {
238     case 0x02: /* CACR */
239         env->cacr = val;
240         m68k_switch_sp(env);
241         break;
242     case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
243         /* TODO: Implement Access Control Registers.  */
244         break;
245     case 0x801: /* VBR */
246         env->vbr = val;
247         break;
248     /* TODO: Implement control registers.  */
249     default:
250         cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n",
251                   reg, val);
252     }
253 }
254
255 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
256 {
257     uint32_t acc;
258     int8_t exthigh;
259     uint8_t extlow;
260     uint64_t regval;
261     int i;
262     if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
263         for (i = 0; i < 4; i++) {
264             regval = env->macc[i];
265             exthigh = regval >> 40;
266             if (env->macsr & MACSR_FI) {
267                 acc = regval >> 8;
268                 extlow = regval;
269             } else {
270                 acc = regval;
271                 extlow = regval >> 32;
272             }
273             if (env->macsr & MACSR_FI) {
274                 regval = (((uint64_t)acc) << 8) | extlow;
275                 regval |= ((int64_t)exthigh) << 40;
276             } else if (env->macsr & MACSR_SU) {
277                 regval = acc | (((int64_t)extlow) << 32);
278                 regval |= ((int64_t)exthigh) << 40;
279             } else {
280                 regval = acc | (((uint64_t)extlow) << 32);
281                 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
282             }
283             env->macc[i] = regval;
284         }
285     }
286     env->macsr = val;
287 }
288
289 void m68k_switch_sp(CPUM68KState *env)
290 {
291     int new_sp;
292
293     env->sp[env->current_sp] = env->aregs[7];
294     new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
295              ? M68K_SSP : M68K_USP;
296     env->aregs[7] = env->sp[new_sp];
297     env->current_sp = new_sp;
298 }
299
300 /* MMU */
301
302 /* TODO: This will need fixing once the MMU is implemented.  */
303 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
304 {
305     return addr;
306 }
307
308 #if defined(CONFIG_USER_ONLY)
309
310 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
311                                int mmu_idx, int is_softmmu)
312 {
313     env->exception_index = EXCP_ACCESS;
314     env->mmu.ar = address;
315     return 1;
316 }
317
318 #else
319
320 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
321                                int mmu_idx, int is_softmmu)
322 {
323     int prot;
324
325     address &= TARGET_PAGE_MASK;
326     prot = PAGE_READ | PAGE_WRITE;
327     return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);
328 }
329
330 /* Notify CPU of a pending interrupt.  Prioritization and vectoring should
331    be handled by the interrupt controller.  Real hardware only requests
332    the vector when the interrupt is acknowledged by the CPU.  For
333    simplicitly we calculate it when the interrupt is signalled.  */
334 void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector)
335 {
336     env->pending_level = level;
337     env->pending_vector = vector;
338     if (level)
339         cpu_interrupt(env, CPU_INTERRUPT_HARD);
340     else
341         cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
342 }
343
344 #endif
345
346 uint32_t HELPER(bitrev)(uint32_t x)
347 {
348     x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
349     x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
350     x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
351     return bswap32(x);
352 }
353
354 uint32_t HELPER(ff1)(uint32_t x)
355 {
356     int n;
357     for (n = 32; x; n--)
358         x >>= 1;
359     return n;
360 }
361
362 uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
363 {
364     /* The result has the opposite sign to the original value.  */
365     if (ccr & CCF_V)
366         val = (((int32_t)val) >> 31) ^ SIGNBIT;
367     return val;
368 }
369
370 uint32_t HELPER(subx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
371 {
372     uint32_t res;
373     uint32_t old_flags;
374
375     old_flags = env->cc_dest;
376     if (env->cc_x) {
377         env->cc_x = (op1 <= op2);
378         env->cc_op = CC_OP_SUBX;
379         res = op1 - (op2 + 1);
380     } else {
381         env->cc_x = (op1 < op2);
382         env->cc_op = CC_OP_SUB;
383         res = op1 - op2;
384     }
385     env->cc_dest = res;
386     env->cc_src = op2;
387     cpu_m68k_flush_flags(env, env->cc_op);
388     /* !Z is sticky.  */
389     env->cc_dest &= (old_flags | ~CCF_Z);
390     return res;
391 }
392
393 uint32_t HELPER(addx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
394 {
395     uint32_t res;
396     uint32_t old_flags;
397
398     old_flags = env->cc_dest;
399     if (env->cc_x) {
400         res = op1 + op2 + 1;
401         env->cc_x = (res <= op2);
402         env->cc_op = CC_OP_ADDX;
403     } else {
404         res = op1 + op2;
405         env->cc_x = (res < op2);
406         env->cc_op = CC_OP_ADD;
407     }
408     env->cc_dest = res;
409     env->cc_src = op2;
410     cpu_m68k_flush_flags(env, env->cc_op);
411     /* !Z is sticky.  */
412     env->cc_dest &= (old_flags | ~CCF_Z);
413     return res;
414 }
415
416 uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
417 {
418     return a < b;
419 }
420
421 uint32_t HELPER(btest)(uint32_t x)
422 {
423     return x != 0;
424 }
425
426 void HELPER(set_sr)(CPUState *env, uint32_t val)
427 {
428     env->sr = val & 0xffff;
429     m68k_switch_sp(env);
430 }
431
432 uint32_t HELPER(shl_cc)(CPUState *env, uint32_t val, uint32_t shift)
433 {
434     uint32_t result;
435     uint32_t cf;
436
437     shift &= 63;
438     if (shift == 0) {
439         result = val;
440         cf = env->cc_src & CCF_C;
441     } else if (shift < 32) {
442         result = val << shift;
443         cf = (val >> (32 - shift)) & 1;
444     } else if (shift == 32) {
445         result = 0;
446         cf = val & 1;
447     } else /* shift > 32 */ {
448         result = 0;
449         cf = 0;
450     }
451     env->cc_src = cf;
452     env->cc_x = (cf != 0);
453     env->cc_dest = result;
454     return result;
455 }
456
457 uint32_t HELPER(shr_cc)(CPUState *env, uint32_t val, uint32_t shift)
458 {
459     uint32_t result;
460     uint32_t cf;
461
462     shift &= 63;
463     if (shift == 0) {
464         result = val;
465         cf = env->cc_src & CCF_C;
466     } else if (shift < 32) {
467         result = val >> shift;
468         cf = (val >> (shift - 1)) & 1;
469     } else if (shift == 32) {
470         result = 0;
471         cf = val >> 31;
472     } else /* shift > 32 */ {
473         result = 0;
474         cf = 0;
475     }
476     env->cc_src = cf;
477     env->cc_x = (cf != 0);
478     env->cc_dest = result;
479     return result;
480 }
481
482 uint32_t HELPER(sar_cc)(CPUState *env, uint32_t val, uint32_t shift)
483 {
484     uint32_t result;
485     uint32_t cf;
486
487     shift &= 63;
488     if (shift == 0) {
489         result = val;
490         cf = (env->cc_src & CCF_C) != 0;
491     } else if (shift < 32) {
492         result = (int32_t)val >> shift;
493         cf = (val >> (shift - 1)) & 1;
494     } else /* shift >= 32 */ {
495         result = (int32_t)val >> 31;
496         cf = val >> 31;
497     }
498     env->cc_src = cf;
499     env->cc_x = cf;
500     env->cc_dest = result;
501     return result;
502 }
503
504 /* FPU helpers.  */
505 uint32_t HELPER(f64_to_i32)(CPUState *env, float64 val)
506 {
507     return float64_to_int32(val, &env->fp_status);
508 }
509
510 float32 HELPER(f64_to_f32)(CPUState *env, float64 val)
511 {
512     return float64_to_float32(val, &env->fp_status);
513 }
514
515 float64 HELPER(i32_to_f64)(CPUState *env, uint32_t val)
516 {
517     return int32_to_float64(val, &env->fp_status);
518 }
519
520 float64 HELPER(f32_to_f64)(CPUState *env, float32 val)
521 {
522     return float32_to_float64(val, &env->fp_status);
523 }
524
525 float64 HELPER(iround_f64)(CPUState *env, float64 val)
526 {
527     return float64_round_to_int(val, &env->fp_status);
528 }
529
530 float64 HELPER(itrunc_f64)(CPUState *env, float64 val)
531 {
532     return float64_trunc_to_int(val, &env->fp_status);
533 }
534
535 float64 HELPER(sqrt_f64)(CPUState *env, float64 val)
536 {
537     return float64_sqrt(val, &env->fp_status);
538 }
539
540 float64 HELPER(abs_f64)(float64 val)
541 {
542     return float64_abs(val);
543 }
544
545 float64 HELPER(chs_f64)(float64 val)
546 {
547     return float64_chs(val);
548 }
549
550 float64 HELPER(add_f64)(CPUState *env, float64 a, float64 b)
551 {
552     return float64_add(a, b, &env->fp_status);
553 }
554
555 float64 HELPER(sub_f64)(CPUState *env, float64 a, float64 b)
556 {
557     return float64_sub(a, b, &env->fp_status);
558 }
559
560 float64 HELPER(mul_f64)(CPUState *env, float64 a, float64 b)
561 {
562     return float64_mul(a, b, &env->fp_status);
563 }
564
565 float64 HELPER(div_f64)(CPUState *env, float64 a, float64 b)
566 {
567     return float64_div(a, b, &env->fp_status);
568 }
569
570 float64 HELPER(sub_cmp_f64)(CPUState *env, float64 a, float64 b)
571 {
572     /* ??? This may incorrectly raise exceptions.  */
573     /* ??? Should flush denormals to zero.  */
574     float64 res;
575     res = float64_sub(a, b, &env->fp_status);
576     if (float64_is_nan(res)) {
577         /* +/-inf compares equal against itself, but sub returns nan.  */
578         if (!float64_is_nan(a)
579             && !float64_is_nan(b)) {
580             res = float64_zero;
581             if (float64_lt_quiet(a, res, &env->fp_status))
582                 res = float64_chs(res);
583         }
584     }
585     return res;
586 }
587
588 uint32_t HELPER(compare_f64)(CPUState *env, float64 val)
589 {
590     return float64_compare_quiet(val, float64_zero, &env->fp_status);
591 }
592
593 /* MAC unit.  */
594 /* FIXME: The MAC unit implementation is a bit of a mess.  Some helpers
595    take values,  others take register numbers and manipulate the contents
596    in-place.  */
597 void HELPER(mac_move)(CPUState *env, uint32_t dest, uint32_t src)
598 {
599     uint32_t mask;
600     env->macc[dest] = env->macc[src];
601     mask = MACSR_PAV0 << dest;
602     if (env->macsr & (MACSR_PAV0 << src))
603         env->macsr |= mask;
604     else
605         env->macsr &= ~mask;
606 }
607
608 uint64_t HELPER(macmuls)(CPUState *env, uint32_t op1, uint32_t op2)
609 {
610     int64_t product;
611     int64_t res;
612
613     product = (uint64_t)op1 * op2;
614     res = (product << 24) >> 24;
615     if (res != product) {
616         env->macsr |= MACSR_V;
617         if (env->macsr & MACSR_OMC) {
618             /* Make sure the accumulate operation overflows.  */
619             if (product < 0)
620                 res = ~(1ll << 50);
621             else
622                 res = 1ll << 50;
623         }
624     }
625     return res;
626 }
627
628 uint64_t HELPER(macmulu)(CPUState *env, uint32_t op1, uint32_t op2)
629 {
630     uint64_t product;
631
632     product = (uint64_t)op1 * op2;
633     if (product & (0xffffffull << 40)) {
634         env->macsr |= MACSR_V;
635         if (env->macsr & MACSR_OMC) {
636             /* Make sure the accumulate operation overflows.  */
637             product = 1ll << 50;
638         } else {
639             product &= ((1ull << 40) - 1);
640         }
641     }
642     return product;
643 }
644
645 uint64_t HELPER(macmulf)(CPUState *env, uint32_t op1, uint32_t op2)
646 {
647     uint64_t product;
648     uint32_t remainder;
649
650     product = (uint64_t)op1 * op2;
651     if (env->macsr & MACSR_RT) {
652         remainder = product & 0xffffff;
653         product >>= 24;
654         if (remainder > 0x800000)
655             product++;
656         else if (remainder == 0x800000)
657             product += (product & 1);
658     } else {
659         product >>= 24;
660     }
661     return product;
662 }
663
664 void HELPER(macsats)(CPUState *env, uint32_t acc)
665 {
666     int64_t tmp;
667     int64_t result;
668     tmp = env->macc[acc];
669     result = ((tmp << 16) >> 16);
670     if (result != tmp) {
671         env->macsr |= MACSR_V;
672     }
673     if (env->macsr & MACSR_V) {
674         env->macsr |= MACSR_PAV0 << acc;
675         if (env->macsr & MACSR_OMC) {
676             /* The result is saturated to 32 bits, despite overflow occuring
677                at 48 bits.  Seems weird, but that's what the hardware docs
678                say.  */
679             result = (result >> 63) ^ 0x7fffffff;
680         }
681     }
682     env->macc[acc] = result;
683 }
684
685 void HELPER(macsatu)(CPUState *env, uint32_t acc)
686 {
687     uint64_t val;
688
689     val = env->macc[acc];
690     if (val & (0xffffull << 48)) {
691         env->macsr |= MACSR_V;
692     }
693     if (env->macsr & MACSR_V) {
694         env->macsr |= MACSR_PAV0 << acc;
695         if (env->macsr & MACSR_OMC) {
696             if (val > (1ull << 53))
697                 val = 0;
698             else
699                 val = (1ull << 48) - 1;
700         } else {
701             val &= ((1ull << 48) - 1);
702         }
703     }
704     env->macc[acc] = val;
705 }
706
707 void HELPER(macsatf)(CPUState *env, uint32_t acc)
708 {
709     int64_t sum;
710     int64_t result;
711
712     sum = env->macc[acc];
713     result = (sum << 16) >> 16;
714     if (result != sum) {
715         env->macsr |= MACSR_V;
716     }
717     if (env->macsr & MACSR_V) {
718         env->macsr |= MACSR_PAV0 << acc;
719         if (env->macsr & MACSR_OMC) {
720             result = (result >> 63) ^ 0x7fffffffffffll;
721         }
722     }
723     env->macc[acc] = result;
724 }
725
726 void HELPER(mac_set_flags)(CPUState *env, uint32_t acc)
727 {
728     uint64_t val;
729     val = env->macc[acc];
730     if (val == 0)
731         env->macsr |= MACSR_Z;
732     else if (val & (1ull << 47));
733         env->macsr |= MACSR_N;
734     if (env->macsr & (MACSR_PAV0 << acc)) {
735         env->macsr |= MACSR_V;
736     }
737     if (env->macsr & MACSR_FI) {
738         val = ((int64_t)val) >> 40;
739         if (val != 0 && val != -1)
740             env->macsr |= MACSR_EV;
741     } else if (env->macsr & MACSR_SU) {
742         val = ((int64_t)val) >> 32;
743         if (val != 0 && val != -1)
744             env->macsr |= MACSR_EV;
745     } else {
746         if ((val >> 32) != 0)
747             env->macsr |= MACSR_EV;
748     }
749 }
750
751 void HELPER(flush_flags)(CPUState *env, uint32_t cc_op)
752 {
753     cpu_m68k_flush_flags(env, cc_op);
754 }
755
756 uint32_t HELPER(get_macf)(CPUState *env, uint64_t val)
757 {
758     int rem;
759     uint32_t result;
760
761     if (env->macsr & MACSR_SU) {
762         /* 16-bit rounding.  */
763         rem = val & 0xffffff;
764         val = (val >> 24) & 0xffffu;
765         if (rem > 0x800000)
766             val++;
767         else if (rem == 0x800000)
768             val += (val & 1);
769     } else if (env->macsr & MACSR_RT) {
770         /* 32-bit rounding.  */
771         rem = val & 0xff;
772         val >>= 8;
773         if (rem > 0x80)
774             val++;
775         else if (rem == 0x80)
776             val += (val & 1);
777     } else {
778         /* No rounding.  */
779         val >>= 8;
780     }
781     if (env->macsr & MACSR_OMC) {
782         /* Saturate.  */
783         if (env->macsr & MACSR_SU) {
784             if (val != (uint16_t) val) {
785                 result = ((val >> 63) ^ 0x7fff) & 0xffff;
786             } else {
787                 result = val & 0xffff;
788             }
789         } else {
790             if (val != (uint32_t)val) {
791                 result = ((uint32_t)(val >> 63) & 0x7fffffff);
792             } else {
793                 result = (uint32_t)val;
794             }
795         }
796     } else {
797         /* No saturation.  */
798         if (env->macsr & MACSR_SU) {
799             result = val & 0xffff;
800         } else {
801             result = (uint32_t)val;
802         }
803     }
804     return result;
805 }
806
807 uint32_t HELPER(get_macs)(uint64_t val)
808 {
809     if (val == (int32_t)val) {
810         return (int32_t)val;
811     } else {
812         return (val >> 61) ^ ~SIGNBIT;
813     }
814 }
815
816 uint32_t HELPER(get_macu)(uint64_t val)
817 {
818     if ((val >> 32) == 0) {
819         return (uint32_t)val;
820     } else {
821         return 0xffffffffu;
822     }
823 }
824
825 uint32_t HELPER(get_mac_extf)(CPUState *env, uint32_t acc)
826 {
827     uint32_t val;
828     val = env->macc[acc] & 0x00ff;
829     val = (env->macc[acc] >> 32) & 0xff00;
830     val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
831     val |= (env->macc[acc + 1] >> 16) & 0xff000000;
832     return val;
833 }
834
835 uint32_t HELPER(get_mac_exti)(CPUState *env, uint32_t acc)
836 {
837     uint32_t val;
838     val = (env->macc[acc] >> 32) & 0xffff;
839     val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
840     return val;
841 }
842
843 void HELPER(set_mac_extf)(CPUState *env, uint32_t val, uint32_t acc)
844 {
845     int64_t res;
846     int32_t tmp;
847     res = env->macc[acc] & 0xffffffff00ull;
848     tmp = (int16_t)(val & 0xff00);
849     res |= ((int64_t)tmp) << 32;
850     res |= val & 0xff;
851     env->macc[acc] = res;
852     res = env->macc[acc + 1] & 0xffffffff00ull;
853     tmp = (val & 0xff000000);
854     res |= ((int64_t)tmp) << 16;
855     res |= (val >> 16) & 0xff;
856     env->macc[acc + 1] = res;
857 }
858
859 void HELPER(set_mac_exts)(CPUState *env, uint32_t val, uint32_t acc)
860 {
861     int64_t res;
862     int32_t tmp;
863     res = (uint32_t)env->macc[acc];
864     tmp = (int16_t)val;
865     res |= ((int64_t)tmp) << 32;
866     env->macc[acc] = res;
867     res = (uint32_t)env->macc[acc + 1];
868     tmp = val & 0xffff0000;
869     res |= (int64_t)tmp << 16;
870     env->macc[acc + 1] = res;
871 }
872
873 void HELPER(set_mac_extu)(CPUState *env, uint32_t val, uint32_t acc)
874 {
875     uint64_t res;
876     res = (uint32_t)env->macc[acc];
877     res |= ((uint64_t)(val & 0xffff)) << 32;
878     env->macc[acc] = res;
879     res = (uint32_t)env->macc[acc + 1];
880     res |= (uint64_t)(val & 0xffff0000) << 16;
881     env->macc[acc + 1] = res;
882 }