s390x/kvm: fix run_on_cpu sigp conversions
[qemu.git] / target-m68k / helper.c
blob7aed9ffd2f43b725ae05c934ddfb43e084c664d8
1 /*
2 * m68k op helpers
4 * Copyright (c) 2006-2007 CodeSourcery
5 * Written by Paul Brook
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.
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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "cpu.h"
23 #include "exec/exec-all.h"
24 #include "exec/gdbstub.h"
26 #include "exec/helper-proto.h"
28 #define SIGNBIT (1u << 31)
30 /* Sort alphabetically, except for "any". */
31 static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b)
33 ObjectClass *class_a = (ObjectClass *)a;
34 ObjectClass *class_b = (ObjectClass *)b;
35 const char *name_a, *name_b;
37 name_a = object_class_get_name(class_a);
38 name_b = object_class_get_name(class_b);
39 if (strcmp(name_a, "any-" TYPE_M68K_CPU) == 0) {
40 return 1;
41 } else if (strcmp(name_b, "any-" TYPE_M68K_CPU) == 0) {
42 return -1;
43 } else {
44 return strcasecmp(name_a, name_b);
48 static void m68k_cpu_list_entry(gpointer data, gpointer user_data)
50 ObjectClass *c = data;
51 CPUListState *s = user_data;
52 const char *typename;
53 char *name;
55 typename = object_class_get_name(c);
56 name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_M68K_CPU));
57 (*s->cpu_fprintf)(s->file, "%s\n",
58 name);
59 g_free(name);
62 void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
64 CPUListState s = {
65 .file = f,
66 .cpu_fprintf = cpu_fprintf,
68 GSList *list;
70 list = object_class_get_list(TYPE_M68K_CPU, false);
71 list = g_slist_sort(list, m68k_cpu_list_compare);
72 g_slist_foreach(list, m68k_cpu_list_entry, &s);
73 g_slist_free(list);
76 static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
78 if (n < 8) {
79 stfq_p(mem_buf, env->fregs[n]);
80 return 8;
82 if (n < 11) {
83 /* FP control registers (not implemented) */
84 memset(mem_buf, 0, 4);
85 return 4;
87 return 0;
90 static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
92 if (n < 8) {
93 env->fregs[n] = ldfq_p(mem_buf);
94 return 8;
96 if (n < 11) {
97 /* FP control registers (not implemented) */
98 return 4;
100 return 0;
103 M68kCPU *cpu_m68k_init(const char *cpu_model)
105 M68kCPU *cpu;
106 CPUM68KState *env;
107 ObjectClass *oc;
109 oc = cpu_class_by_name(TYPE_M68K_CPU, cpu_model);
110 if (oc == NULL) {
111 return NULL;
113 cpu = M68K_CPU(object_new(object_class_get_name(oc)));
114 env = &cpu->env;
116 register_m68k_insns(env);
118 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
120 return cpu;
123 void m68k_cpu_init_gdb(M68kCPU *cpu)
125 CPUState *cs = CPU(cpu);
126 CPUM68KState *env = &cpu->env;
128 if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
129 gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg,
130 11, "cf-fp.xml", 18);
132 /* TODO: Add [E]MAC registers. */
135 void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
137 M68kCPU *cpu = m68k_env_get_cpu(env);
139 switch (reg) {
140 case 0x02: /* CACR */
141 env->cacr = val;
142 m68k_switch_sp(env);
143 break;
144 case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
145 /* TODO: Implement Access Control Registers. */
146 break;
147 case 0x801: /* VBR */
148 env->vbr = val;
149 break;
150 /* TODO: Implement control registers. */
151 default:
152 cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x = 0x%x\n",
153 reg, val);
157 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
159 uint32_t acc;
160 int8_t exthigh;
161 uint8_t extlow;
162 uint64_t regval;
163 int i;
164 if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
165 for (i = 0; i < 4; i++) {
166 regval = env->macc[i];
167 exthigh = regval >> 40;
168 if (env->macsr & MACSR_FI) {
169 acc = regval >> 8;
170 extlow = regval;
171 } else {
172 acc = regval;
173 extlow = regval >> 32;
175 if (env->macsr & MACSR_FI) {
176 regval = (((uint64_t)acc) << 8) | extlow;
177 regval |= ((int64_t)exthigh) << 40;
178 } else if (env->macsr & MACSR_SU) {
179 regval = acc | (((int64_t)extlow) << 32);
180 regval |= ((int64_t)exthigh) << 40;
181 } else {
182 regval = acc | (((uint64_t)extlow) << 32);
183 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
185 env->macc[i] = regval;
188 env->macsr = val;
191 void m68k_switch_sp(CPUM68KState *env)
193 int new_sp;
195 env->sp[env->current_sp] = env->aregs[7];
196 new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
197 ? M68K_SSP : M68K_USP;
198 env->aregs[7] = env->sp[new_sp];
199 env->current_sp = new_sp;
202 #if defined(CONFIG_USER_ONLY)
204 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
205 int mmu_idx)
207 M68kCPU *cpu = M68K_CPU(cs);
209 cs->exception_index = EXCP_ACCESS;
210 cpu->env.mmu.ar = address;
211 return 1;
214 #else
216 /* MMU */
218 /* TODO: This will need fixing once the MMU is implemented. */
219 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
221 return addr;
224 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
225 int mmu_idx)
227 int prot;
229 address &= TARGET_PAGE_MASK;
230 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
231 tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
232 return 0;
235 /* Notify CPU of a pending interrupt. Prioritization and vectoring should
236 be handled by the interrupt controller. Real hardware only requests
237 the vector when the interrupt is acknowledged by the CPU. For
238 simplicitly we calculate it when the interrupt is signalled. */
239 void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
241 CPUState *cs = CPU(cpu);
242 CPUM68KState *env = &cpu->env;
244 env->pending_level = level;
245 env->pending_vector = vector;
246 if (level) {
247 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
248 } else {
249 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
253 #endif
255 uint32_t HELPER(bitrev)(uint32_t x)
257 x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
258 x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
259 x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
260 return bswap32(x);
263 uint32_t HELPER(ff1)(uint32_t x)
265 int n;
266 for (n = 32; x; n--)
267 x >>= 1;
268 return n;
271 uint32_t HELPER(sats)(uint32_t val, uint32_t v)
273 /* The result has the opposite sign to the original value. */
274 if ((int32_t)v < 0) {
275 val = (((int32_t)val) >> 31) ^ SIGNBIT;
277 return val;
280 void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
282 env->sr = val & 0xffe0;
283 cpu_m68k_set_ccr(env, val);
284 m68k_switch_sp(env);
287 uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
289 uint64_t result;
291 shift &= 63;
292 result = (uint64_t)val << shift;
294 env->cc_c = (result >> 32) & 1;
295 env->cc_n = result;
296 env->cc_z = result;
297 env->cc_v = 0;
298 env->cc_x = shift ? env->cc_c : env->cc_x;
300 return result;
303 uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
305 uint64_t temp;
306 uint32_t result;
308 shift &= 63;
309 temp = (uint64_t)val << 32 >> shift;
310 result = temp >> 32;
312 env->cc_c = (temp >> 31) & 1;
313 env->cc_n = result;
314 env->cc_z = result;
315 env->cc_v = 0;
316 env->cc_x = shift ? env->cc_c : env->cc_x;
318 return result;
321 uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
323 uint64_t temp;
324 uint32_t result;
326 shift &= 63;
327 temp = (int64_t)val << 32 >> shift;
328 result = temp >> 32;
330 env->cc_c = (temp >> 31) & 1;
331 env->cc_n = result;
332 env->cc_z = result;
333 env->cc_v = result ^ val;
334 env->cc_x = shift ? env->cc_c : env->cc_x;
336 return result;
339 /* FPU helpers. */
340 uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val)
342 return float64_to_int32(val, &env->fp_status);
345 float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val)
347 return float64_to_float32(val, &env->fp_status);
350 float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val)
352 return int32_to_float64(val, &env->fp_status);
355 float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val)
357 return float32_to_float64(val, &env->fp_status);
360 float64 HELPER(iround_f64)(CPUM68KState *env, float64 val)
362 return float64_round_to_int(val, &env->fp_status);
365 float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val)
367 return float64_trunc_to_int(val, &env->fp_status);
370 float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val)
372 return float64_sqrt(val, &env->fp_status);
375 float64 HELPER(abs_f64)(float64 val)
377 return float64_abs(val);
380 float64 HELPER(chs_f64)(float64 val)
382 return float64_chs(val);
385 float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b)
387 return float64_add(a, b, &env->fp_status);
390 float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b)
392 return float64_sub(a, b, &env->fp_status);
395 float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b)
397 return float64_mul(a, b, &env->fp_status);
400 float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b)
402 return float64_div(a, b, &env->fp_status);
405 float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
407 /* ??? This may incorrectly raise exceptions. */
408 /* ??? Should flush denormals to zero. */
409 float64 res;
410 res = float64_sub(a, b, &env->fp_status);
411 if (float64_is_quiet_nan(res, &env->fp_status)) {
412 /* +/-inf compares equal against itself, but sub returns nan. */
413 if (!float64_is_quiet_nan(a, &env->fp_status)
414 && !float64_is_quiet_nan(b, &env->fp_status)) {
415 res = float64_zero;
416 if (float64_lt_quiet(a, res, &env->fp_status))
417 res = float64_chs(res);
420 return res;
423 uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val)
425 return float64_compare_quiet(val, float64_zero, &env->fp_status);
428 /* MAC unit. */
429 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
430 take values, others take register numbers and manipulate the contents
431 in-place. */
432 void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
434 uint32_t mask;
435 env->macc[dest] = env->macc[src];
436 mask = MACSR_PAV0 << dest;
437 if (env->macsr & (MACSR_PAV0 << src))
438 env->macsr |= mask;
439 else
440 env->macsr &= ~mask;
443 uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
445 int64_t product;
446 int64_t res;
448 product = (uint64_t)op1 * op2;
449 res = (product << 24) >> 24;
450 if (res != product) {
451 env->macsr |= MACSR_V;
452 if (env->macsr & MACSR_OMC) {
453 /* Make sure the accumulate operation overflows. */
454 if (product < 0)
455 res = ~(1ll << 50);
456 else
457 res = 1ll << 50;
460 return res;
463 uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
465 uint64_t product;
467 product = (uint64_t)op1 * op2;
468 if (product & (0xffffffull << 40)) {
469 env->macsr |= MACSR_V;
470 if (env->macsr & MACSR_OMC) {
471 /* Make sure the accumulate operation overflows. */
472 product = 1ll << 50;
473 } else {
474 product &= ((1ull << 40) - 1);
477 return product;
480 uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
482 uint64_t product;
483 uint32_t remainder;
485 product = (uint64_t)op1 * op2;
486 if (env->macsr & MACSR_RT) {
487 remainder = product & 0xffffff;
488 product >>= 24;
489 if (remainder > 0x800000)
490 product++;
491 else if (remainder == 0x800000)
492 product += (product & 1);
493 } else {
494 product >>= 24;
496 return product;
499 void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
501 int64_t tmp;
502 int64_t result;
503 tmp = env->macc[acc];
504 result = ((tmp << 16) >> 16);
505 if (result != tmp) {
506 env->macsr |= MACSR_V;
508 if (env->macsr & MACSR_V) {
509 env->macsr |= MACSR_PAV0 << acc;
510 if (env->macsr & MACSR_OMC) {
511 /* The result is saturated to 32 bits, despite overflow occurring
512 at 48 bits. Seems weird, but that's what the hardware docs
513 say. */
514 result = (result >> 63) ^ 0x7fffffff;
517 env->macc[acc] = result;
520 void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
522 uint64_t val;
524 val = env->macc[acc];
525 if (val & (0xffffull << 48)) {
526 env->macsr |= MACSR_V;
528 if (env->macsr & MACSR_V) {
529 env->macsr |= MACSR_PAV0 << acc;
530 if (env->macsr & MACSR_OMC) {
531 if (val > (1ull << 53))
532 val = 0;
533 else
534 val = (1ull << 48) - 1;
535 } else {
536 val &= ((1ull << 48) - 1);
539 env->macc[acc] = val;
542 void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
544 int64_t sum;
545 int64_t result;
547 sum = env->macc[acc];
548 result = (sum << 16) >> 16;
549 if (result != sum) {
550 env->macsr |= MACSR_V;
552 if (env->macsr & MACSR_V) {
553 env->macsr |= MACSR_PAV0 << acc;
554 if (env->macsr & MACSR_OMC) {
555 result = (result >> 63) ^ 0x7fffffffffffll;
558 env->macc[acc] = result;
561 void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
563 uint64_t val;
564 val = env->macc[acc];
565 if (val == 0) {
566 env->macsr |= MACSR_Z;
567 } else if (val & (1ull << 47)) {
568 env->macsr |= MACSR_N;
570 if (env->macsr & (MACSR_PAV0 << acc)) {
571 env->macsr |= MACSR_V;
573 if (env->macsr & MACSR_FI) {
574 val = ((int64_t)val) >> 40;
575 if (val != 0 && val != -1)
576 env->macsr |= MACSR_EV;
577 } else if (env->macsr & MACSR_SU) {
578 val = ((int64_t)val) >> 32;
579 if (val != 0 && val != -1)
580 env->macsr |= MACSR_EV;
581 } else {
582 if ((val >> 32) != 0)
583 env->macsr |= MACSR_EV;
587 #define EXTSIGN(val, index) ( \
588 (index == 0) ? (int8_t)(val) : ((index == 1) ? (int16_t)(val) : (val)) \
591 #define COMPUTE_CCR(op, x, n, z, v, c) { \
592 switch (op) { \
593 case CC_OP_FLAGS: \
594 /* Everything in place. */ \
595 break; \
596 case CC_OP_ADDB: \
597 case CC_OP_ADDW: \
598 case CC_OP_ADDL: \
599 res = n; \
600 src2 = v; \
601 src1 = EXTSIGN(res - src2, op - CC_OP_ADDB); \
602 c = x; \
603 z = n; \
604 v = (res ^ src1) & ~(src1 ^ src2); \
605 break; \
606 case CC_OP_SUBB: \
607 case CC_OP_SUBW: \
608 case CC_OP_SUBL: \
609 res = n; \
610 src2 = v; \
611 src1 = EXTSIGN(res + src2, op - CC_OP_SUBB); \
612 c = x; \
613 z = n; \
614 v = (res ^ src1) & (src1 ^ src2); \
615 break; \
616 case CC_OP_CMPB: \
617 case CC_OP_CMPW: \
618 case CC_OP_CMPL: \
619 src1 = n; \
620 src2 = v; \
621 res = EXTSIGN(src1 - src2, op - CC_OP_CMPB); \
622 n = res; \
623 z = res; \
624 c = src1 < src2; \
625 v = (res ^ src1) & (src1 ^ src2); \
626 break; \
627 case CC_OP_LOGIC: \
628 c = v = 0; \
629 z = n; \
630 break; \
631 default: \
632 cpu_abort(CPU(m68k_env_get_cpu(env)), "Bad CC_OP %d", op); \
634 } while (0)
636 uint32_t cpu_m68k_get_ccr(CPUM68KState *env)
638 uint32_t x, c, n, z, v;
639 uint32_t res, src1, src2;
641 x = env->cc_x;
642 n = env->cc_n;
643 z = env->cc_z;
644 v = env->cc_v;
645 c = env->cc_c;
647 COMPUTE_CCR(env->cc_op, x, n, z, v, c);
649 n = n >> 31;
650 z = (z == 0);
651 v = v >> 31;
653 return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C;
656 uint32_t HELPER(get_ccr)(CPUM68KState *env)
658 return cpu_m68k_get_ccr(env);
661 void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t ccr)
663 env->cc_x = (ccr & CCF_X ? 1 : 0);
664 env->cc_n = (ccr & CCF_N ? -1 : 0);
665 env->cc_z = (ccr & CCF_Z ? 0 : 1);
666 env->cc_v = (ccr & CCF_V ? -1 : 0);
667 env->cc_c = (ccr & CCF_C ? 1 : 0);
668 env->cc_op = CC_OP_FLAGS;
671 void HELPER(set_ccr)(CPUM68KState *env, uint32_t ccr)
673 cpu_m68k_set_ccr(env, ccr);
676 void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
678 uint32_t res, src1, src2;
680 COMPUTE_CCR(cc_op, env->cc_x, env->cc_n, env->cc_z, env->cc_v, env->cc_c);
681 env->cc_op = CC_OP_FLAGS;
684 uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
686 int rem;
687 uint32_t result;
689 if (env->macsr & MACSR_SU) {
690 /* 16-bit rounding. */
691 rem = val & 0xffffff;
692 val = (val >> 24) & 0xffffu;
693 if (rem > 0x800000)
694 val++;
695 else if (rem == 0x800000)
696 val += (val & 1);
697 } else if (env->macsr & MACSR_RT) {
698 /* 32-bit rounding. */
699 rem = val & 0xff;
700 val >>= 8;
701 if (rem > 0x80)
702 val++;
703 else if (rem == 0x80)
704 val += (val & 1);
705 } else {
706 /* No rounding. */
707 val >>= 8;
709 if (env->macsr & MACSR_OMC) {
710 /* Saturate. */
711 if (env->macsr & MACSR_SU) {
712 if (val != (uint16_t) val) {
713 result = ((val >> 63) ^ 0x7fff) & 0xffff;
714 } else {
715 result = val & 0xffff;
717 } else {
718 if (val != (uint32_t)val) {
719 result = ((uint32_t)(val >> 63) & 0x7fffffff);
720 } else {
721 result = (uint32_t)val;
724 } else {
725 /* No saturation. */
726 if (env->macsr & MACSR_SU) {
727 result = val & 0xffff;
728 } else {
729 result = (uint32_t)val;
732 return result;
735 uint32_t HELPER(get_macs)(uint64_t val)
737 if (val == (int32_t)val) {
738 return (int32_t)val;
739 } else {
740 return (val >> 61) ^ ~SIGNBIT;
744 uint32_t HELPER(get_macu)(uint64_t val)
746 if ((val >> 32) == 0) {
747 return (uint32_t)val;
748 } else {
749 return 0xffffffffu;
753 uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
755 uint32_t val;
756 val = env->macc[acc] & 0x00ff;
757 val |= (env->macc[acc] >> 32) & 0xff00;
758 val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
759 val |= (env->macc[acc + 1] >> 16) & 0xff000000;
760 return val;
763 uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
765 uint32_t val;
766 val = (env->macc[acc] >> 32) & 0xffff;
767 val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
768 return val;
771 void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
773 int64_t res;
774 int32_t tmp;
775 res = env->macc[acc] & 0xffffffff00ull;
776 tmp = (int16_t)(val & 0xff00);
777 res |= ((int64_t)tmp) << 32;
778 res |= val & 0xff;
779 env->macc[acc] = res;
780 res = env->macc[acc + 1] & 0xffffffff00ull;
781 tmp = (val & 0xff000000);
782 res |= ((int64_t)tmp) << 16;
783 res |= (val >> 16) & 0xff;
784 env->macc[acc + 1] = res;
787 void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
789 int64_t res;
790 int32_t tmp;
791 res = (uint32_t)env->macc[acc];
792 tmp = (int16_t)val;
793 res |= ((int64_t)tmp) << 32;
794 env->macc[acc] = res;
795 res = (uint32_t)env->macc[acc + 1];
796 tmp = val & 0xffff0000;
797 res |= (int64_t)tmp << 16;
798 env->macc[acc + 1] = res;
801 void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
803 uint64_t res;
804 res = (uint32_t)env->macc[acc];
805 res |= ((uint64_t)(val & 0xffff)) << 32;
806 env->macc[acc] = res;
807 res = (uint32_t)env->macc[acc + 1];
808 res |= (uint64_t)(val & 0xffff0000) << 16;
809 env->macc[acc + 1] = res;