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