iotests.py: Allow concurrent qemu instances
[qemu/ar7.git] / target-m68k / helper.c
blob094a7e59a9f6d689cd1998765db58f47863bc6a5
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 uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
282 uint32_t res, new_x;
284 if (env->cc_x) {
285 new_x = (op1 <= op2);
286 res = op1 - (op2 + 1);
287 } else {
288 new_x = (op1 < op2);
289 res = op1 - op2;
291 env->cc_x = new_x;
292 env->cc_c = new_x;
293 env->cc_n = res;
294 env->cc_z |= res; /* !Z is sticky */
295 env->cc_v = (res ^ op1) & (op1 ^ op2);
297 return res;
300 uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
302 uint32_t res, new_x;
304 if (env->cc_x) {
305 res = op1 + op2 + 1;
306 new_x = (res <= op2);
307 } else {
308 res = op1 + op2;
309 new_x = (res < op2);
311 env->cc_x = new_x;
312 env->cc_c = new_x;
313 env->cc_n = res;
314 env->cc_z |= res; /* !Z is sticky. */
315 env->cc_v = (res ^ op1) & ~(op1 ^ op2);
317 return res;
320 void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
322 env->sr = val & 0xffe0;
323 cpu_m68k_set_ccr(env, val);
324 m68k_switch_sp(env);
327 uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
329 uint64_t result;
331 shift &= 63;
332 result = (uint64_t)val << shift;
334 env->cc_c = (result >> 32) & 1;
335 env->cc_n = result;
336 env->cc_z = result;
337 env->cc_v = 0;
338 env->cc_x = shift ? env->cc_c : env->cc_x;
340 return result;
343 uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
345 uint64_t temp;
346 uint32_t result;
348 shift &= 63;
349 temp = (uint64_t)val << 32 >> shift;
350 result = temp >> 32;
352 env->cc_c = (temp >> 31) & 1;
353 env->cc_n = result;
354 env->cc_z = result;
355 env->cc_v = 0;
356 env->cc_x = shift ? env->cc_c : env->cc_x;
358 return result;
361 uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
363 uint64_t temp;
364 uint32_t result;
366 shift &= 63;
367 temp = (int64_t)val << 32 >> shift;
368 result = temp >> 32;
370 env->cc_c = (temp >> 31) & 1;
371 env->cc_n = result;
372 env->cc_z = result;
373 env->cc_v = result ^ val;
374 env->cc_x = shift ? env->cc_c : env->cc_x;
376 return result;
379 /* FPU helpers. */
380 uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val)
382 return float64_to_int32(val, &env->fp_status);
385 float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val)
387 return float64_to_float32(val, &env->fp_status);
390 float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val)
392 return int32_to_float64(val, &env->fp_status);
395 float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val)
397 return float32_to_float64(val, &env->fp_status);
400 float64 HELPER(iround_f64)(CPUM68KState *env, float64 val)
402 return float64_round_to_int(val, &env->fp_status);
405 float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val)
407 return float64_trunc_to_int(val, &env->fp_status);
410 float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val)
412 return float64_sqrt(val, &env->fp_status);
415 float64 HELPER(abs_f64)(float64 val)
417 return float64_abs(val);
420 float64 HELPER(chs_f64)(float64 val)
422 return float64_chs(val);
425 float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b)
427 return float64_add(a, b, &env->fp_status);
430 float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b)
432 return float64_sub(a, b, &env->fp_status);
435 float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b)
437 return float64_mul(a, b, &env->fp_status);
440 float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b)
442 return float64_div(a, b, &env->fp_status);
445 float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
447 /* ??? This may incorrectly raise exceptions. */
448 /* ??? Should flush denormals to zero. */
449 float64 res;
450 res = float64_sub(a, b, &env->fp_status);
451 if (float64_is_quiet_nan(res, &env->fp_status)) {
452 /* +/-inf compares equal against itself, but sub returns nan. */
453 if (!float64_is_quiet_nan(a, &env->fp_status)
454 && !float64_is_quiet_nan(b, &env->fp_status)) {
455 res = float64_zero;
456 if (float64_lt_quiet(a, res, &env->fp_status))
457 res = float64_chs(res);
460 return res;
463 uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val)
465 return float64_compare_quiet(val, float64_zero, &env->fp_status);
468 /* MAC unit. */
469 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
470 take values, others take register numbers and manipulate the contents
471 in-place. */
472 void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
474 uint32_t mask;
475 env->macc[dest] = env->macc[src];
476 mask = MACSR_PAV0 << dest;
477 if (env->macsr & (MACSR_PAV0 << src))
478 env->macsr |= mask;
479 else
480 env->macsr &= ~mask;
483 uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
485 int64_t product;
486 int64_t res;
488 product = (uint64_t)op1 * op2;
489 res = (product << 24) >> 24;
490 if (res != product) {
491 env->macsr |= MACSR_V;
492 if (env->macsr & MACSR_OMC) {
493 /* Make sure the accumulate operation overflows. */
494 if (product < 0)
495 res = ~(1ll << 50);
496 else
497 res = 1ll << 50;
500 return res;
503 uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
505 uint64_t product;
507 product = (uint64_t)op1 * op2;
508 if (product & (0xffffffull << 40)) {
509 env->macsr |= MACSR_V;
510 if (env->macsr & MACSR_OMC) {
511 /* Make sure the accumulate operation overflows. */
512 product = 1ll << 50;
513 } else {
514 product &= ((1ull << 40) - 1);
517 return product;
520 uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
522 uint64_t product;
523 uint32_t remainder;
525 product = (uint64_t)op1 * op2;
526 if (env->macsr & MACSR_RT) {
527 remainder = product & 0xffffff;
528 product >>= 24;
529 if (remainder > 0x800000)
530 product++;
531 else if (remainder == 0x800000)
532 product += (product & 1);
533 } else {
534 product >>= 24;
536 return product;
539 void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
541 int64_t tmp;
542 int64_t result;
543 tmp = env->macc[acc];
544 result = ((tmp << 16) >> 16);
545 if (result != tmp) {
546 env->macsr |= MACSR_V;
548 if (env->macsr & MACSR_V) {
549 env->macsr |= MACSR_PAV0 << acc;
550 if (env->macsr & MACSR_OMC) {
551 /* The result is saturated to 32 bits, despite overflow occurring
552 at 48 bits. Seems weird, but that's what the hardware docs
553 say. */
554 result = (result >> 63) ^ 0x7fffffff;
557 env->macc[acc] = result;
560 void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
562 uint64_t val;
564 val = env->macc[acc];
565 if (val & (0xffffull << 48)) {
566 env->macsr |= MACSR_V;
568 if (env->macsr & MACSR_V) {
569 env->macsr |= MACSR_PAV0 << acc;
570 if (env->macsr & MACSR_OMC) {
571 if (val > (1ull << 53))
572 val = 0;
573 else
574 val = (1ull << 48) - 1;
575 } else {
576 val &= ((1ull << 48) - 1);
579 env->macc[acc] = val;
582 void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
584 int64_t sum;
585 int64_t result;
587 sum = env->macc[acc];
588 result = (sum << 16) >> 16;
589 if (result != sum) {
590 env->macsr |= MACSR_V;
592 if (env->macsr & MACSR_V) {
593 env->macsr |= MACSR_PAV0 << acc;
594 if (env->macsr & MACSR_OMC) {
595 result = (result >> 63) ^ 0x7fffffffffffll;
598 env->macc[acc] = result;
601 void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
603 uint64_t val;
604 val = env->macc[acc];
605 if (val == 0) {
606 env->macsr |= MACSR_Z;
607 } else if (val & (1ull << 47)) {
608 env->macsr |= MACSR_N;
610 if (env->macsr & (MACSR_PAV0 << acc)) {
611 env->macsr |= MACSR_V;
613 if (env->macsr & MACSR_FI) {
614 val = ((int64_t)val) >> 40;
615 if (val != 0 && val != -1)
616 env->macsr |= MACSR_EV;
617 } else if (env->macsr & MACSR_SU) {
618 val = ((int64_t)val) >> 32;
619 if (val != 0 && val != -1)
620 env->macsr |= MACSR_EV;
621 } else {
622 if ((val >> 32) != 0)
623 env->macsr |= MACSR_EV;
628 #define COMPUTE_CCR(op, x, n, z, v, c) { \
629 switch (op) { \
630 case CC_OP_FLAGS: \
631 /* Everything in place. */ \
632 break; \
633 case CC_OP_ADD: \
634 res = n; \
635 src2 = v; \
636 src1 = res - src2; \
637 c = x; \
638 z = n; \
639 v = (res ^ src1) & ~(src1 ^ src2); \
640 break; \
641 case CC_OP_SUB: \
642 res = n; \
643 src2 = v; \
644 src1 = res + src2; \
645 c = x; \
646 z = n; \
647 v = (res ^ src1) & (src1 ^ src2); \
648 break; \
649 case CC_OP_CMP: \
650 src1 = n; \
651 src2 = v; \
652 res = src1 - src2; \
653 n = res; \
654 z = res; \
655 c = src1 < src2; \
656 v = (res ^ src1) & (src1 ^ src2); \
657 break; \
658 case CC_OP_LOGIC: \
659 c = v = 0; \
660 z = n; \
661 break; \
662 default: \
663 cpu_abort(CPU(m68k_env_get_cpu(env)), "Bad CC_OP %d", op); \
665 } while (0)
667 uint32_t cpu_m68k_get_ccr(CPUM68KState *env)
669 uint32_t x, c, n, z, v;
670 uint32_t res, src1, src2;
672 x = env->cc_x;
673 c = env->cc_c;
674 n = env->cc_n;
675 z = env->cc_z;
676 v = env->cc_v;
678 COMPUTE_CCR(env->cc_op, x, n, z, v, c);
680 n = n >> 31;
681 v = v >> 31;
682 z = (z == 0);
684 return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C;
687 uint32_t HELPER(get_ccr)(CPUM68KState *env)
689 return cpu_m68k_get_ccr(env);
692 void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t ccr)
694 env->cc_x = (ccr & CCF_X ? 1 : 0);
695 env->cc_n = (ccr & CCF_N ? -1 : 0);
696 env->cc_z = (ccr & CCF_Z ? 0 : 1);
697 env->cc_v = (ccr & CCF_V ? -1 : 0);
698 env->cc_c = (ccr & CCF_C ? 1 : 0);
699 env->cc_op = CC_OP_FLAGS;
702 void HELPER(set_ccr)(CPUM68KState *env, uint32_t ccr)
704 cpu_m68k_set_ccr(env, ccr);
707 void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
709 uint32_t res, src1, src2;
711 COMPUTE_CCR(cc_op, env->cc_x, env->cc_n, env->cc_z, env->cc_v, env->cc_c);
712 env->cc_op = CC_OP_FLAGS;
715 uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
717 int rem;
718 uint32_t result;
720 if (env->macsr & MACSR_SU) {
721 /* 16-bit rounding. */
722 rem = val & 0xffffff;
723 val = (val >> 24) & 0xffffu;
724 if (rem > 0x800000)
725 val++;
726 else if (rem == 0x800000)
727 val += (val & 1);
728 } else if (env->macsr & MACSR_RT) {
729 /* 32-bit rounding. */
730 rem = val & 0xff;
731 val >>= 8;
732 if (rem > 0x80)
733 val++;
734 else if (rem == 0x80)
735 val += (val & 1);
736 } else {
737 /* No rounding. */
738 val >>= 8;
740 if (env->macsr & MACSR_OMC) {
741 /* Saturate. */
742 if (env->macsr & MACSR_SU) {
743 if (val != (uint16_t) val) {
744 result = ((val >> 63) ^ 0x7fff) & 0xffff;
745 } else {
746 result = val & 0xffff;
748 } else {
749 if (val != (uint32_t)val) {
750 result = ((uint32_t)(val >> 63) & 0x7fffffff);
751 } else {
752 result = (uint32_t)val;
755 } else {
756 /* No saturation. */
757 if (env->macsr & MACSR_SU) {
758 result = val & 0xffff;
759 } else {
760 result = (uint32_t)val;
763 return result;
766 uint32_t HELPER(get_macs)(uint64_t val)
768 if (val == (int32_t)val) {
769 return (int32_t)val;
770 } else {
771 return (val >> 61) ^ ~SIGNBIT;
775 uint32_t HELPER(get_macu)(uint64_t val)
777 if ((val >> 32) == 0) {
778 return (uint32_t)val;
779 } else {
780 return 0xffffffffu;
784 uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
786 uint32_t val;
787 val = env->macc[acc] & 0x00ff;
788 val |= (env->macc[acc] >> 32) & 0xff00;
789 val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
790 val |= (env->macc[acc + 1] >> 16) & 0xff000000;
791 return val;
794 uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
796 uint32_t val;
797 val = (env->macc[acc] >> 32) & 0xffff;
798 val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
799 return val;
802 void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
804 int64_t res;
805 int32_t tmp;
806 res = env->macc[acc] & 0xffffffff00ull;
807 tmp = (int16_t)(val & 0xff00);
808 res |= ((int64_t)tmp) << 32;
809 res |= val & 0xff;
810 env->macc[acc] = res;
811 res = env->macc[acc + 1] & 0xffffffff00ull;
812 tmp = (val & 0xff000000);
813 res |= ((int64_t)tmp) << 16;
814 res |= (val >> 16) & 0xff;
815 env->macc[acc + 1] = res;
818 void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
820 int64_t res;
821 int32_t tmp;
822 res = (uint32_t)env->macc[acc];
823 tmp = (int16_t)val;
824 res |= ((int64_t)tmp) << 32;
825 env->macc[acc] = res;
826 res = (uint32_t)env->macc[acc + 1];
827 tmp = val & 0xffff0000;
828 res |= (int64_t)tmp << 16;
829 env->macc[acc + 1] = res;
832 void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
834 uint64_t res;
835 res = (uint32_t)env->macc[acc];
836 res |= ((uint64_t)(val & 0xffff)) << 32;
837 env->macc[acc] = res;
838 res = (uint32_t)env->macc[acc + 1];
839 res |= (uint64_t)(val & 0xffff0000) << 16;
840 env->macc[acc + 1] = res;