cpu: Introduce CPUListState struct
[qemu/agraf.git] / target-m68k / helper.c
blob875a71af217570dbab58faf43456d50cfd32d0fd
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 "cpu.h"
22 #include "gdbstub.h"
24 #include "helpers.h"
26 #define SIGNBIT (1u << 31)
28 /* Sort alphabetically, except for "any". */
29 static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b)
31 ObjectClass *class_a = (ObjectClass *)a;
32 ObjectClass *class_b = (ObjectClass *)b;
33 const char *name_a, *name_b;
35 name_a = object_class_get_name(class_a);
36 name_b = object_class_get_name(class_b);
37 if (strcmp(name_a, "any") == 0) {
38 return 1;
39 } else if (strcmp(name_b, "any") == 0) {
40 return -1;
41 } else {
42 return strcasecmp(name_a, name_b);
46 static void m68k_cpu_list_entry(gpointer data, gpointer user_data)
48 ObjectClass *c = data;
49 CPUListState *s = user_data;
51 (*s->cpu_fprintf)(s->file, "%s\n",
52 object_class_get_name(c));
55 void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
57 CPUListState s = {
58 .file = f,
59 .cpu_fprintf = cpu_fprintf,
61 GSList *list;
63 list = object_class_get_list(TYPE_M68K_CPU, false);
64 list = g_slist_sort(list, m68k_cpu_list_compare);
65 g_slist_foreach(list, m68k_cpu_list_entry, &s);
66 g_slist_free(list);
69 static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
71 if (n < 8) {
72 stfq_p(mem_buf, env->fregs[n]);
73 return 8;
75 if (n < 11) {
76 /* FP control registers (not implemented) */
77 memset(mem_buf, 0, 4);
78 return 4;
80 return 0;
83 static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
85 if (n < 8) {
86 env->fregs[n] = ldfq_p(mem_buf);
87 return 8;
89 if (n < 11) {
90 /* FP control registers (not implemented) */
91 return 4;
93 return 0;
96 CPUM68KState *cpu_m68k_init(const char *cpu_model)
98 M68kCPU *cpu;
99 CPUM68KState *env;
100 static int inited;
102 if (object_class_by_name(cpu_model) == NULL) {
103 return NULL;
105 cpu = M68K_CPU(object_new(cpu_model));
106 env = &cpu->env;
108 if (!inited) {
109 inited = 1;
110 m68k_tcg_init();
113 env->cpu_model_str = cpu_model;
115 register_m68k_insns(env);
116 if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
117 gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg,
118 11, "cf-fp.xml", 18);
120 /* TODO: Add [E]MAC registers. */
122 cpu_reset(ENV_GET_CPU(env));
123 qemu_init_vcpu(env);
124 return env;
127 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
129 int flags;
130 uint32_t src;
131 uint32_t dest;
132 uint32_t tmp;
134 #define HIGHBIT 0x80000000u
136 #define SET_NZ(x) do { \
137 if ((x) == 0) \
138 flags |= CCF_Z; \
139 else if ((int32_t)(x) < 0) \
140 flags |= CCF_N; \
141 } while (0)
143 #define SET_FLAGS_SUB(type, utype) do { \
144 SET_NZ((type)dest); \
145 tmp = dest + src; \
146 if ((utype) tmp < (utype) src) \
147 flags |= CCF_C; \
148 if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \
149 flags |= CCF_V; \
150 } while (0)
152 flags = 0;
153 src = env->cc_src;
154 dest = env->cc_dest;
155 switch (cc_op) {
156 case CC_OP_FLAGS:
157 flags = dest;
158 break;
159 case CC_OP_LOGIC:
160 SET_NZ(dest);
161 break;
162 case CC_OP_ADD:
163 SET_NZ(dest);
164 if (dest < src)
165 flags |= CCF_C;
166 tmp = dest - src;
167 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
168 flags |= CCF_V;
169 break;
170 case CC_OP_SUB:
171 SET_FLAGS_SUB(int32_t, uint32_t);
172 break;
173 case CC_OP_CMPB:
174 SET_FLAGS_SUB(int8_t, uint8_t);
175 break;
176 case CC_OP_CMPW:
177 SET_FLAGS_SUB(int16_t, uint16_t);
178 break;
179 case CC_OP_ADDX:
180 SET_NZ(dest);
181 if (dest <= src)
182 flags |= CCF_C;
183 tmp = dest - src - 1;
184 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
185 flags |= CCF_V;
186 break;
187 case CC_OP_SUBX:
188 SET_NZ(dest);
189 tmp = dest + src + 1;
190 if (tmp <= src)
191 flags |= CCF_C;
192 if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
193 flags |= CCF_V;
194 break;
195 case CC_OP_SHIFT:
196 SET_NZ(dest);
197 if (src)
198 flags |= CCF_C;
199 break;
200 default:
201 cpu_abort(env, "Bad CC_OP %d", cc_op);
203 env->cc_op = CC_OP_FLAGS;
204 env->cc_dest = flags;
207 void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
209 switch (reg) {
210 case 0x02: /* CACR */
211 env->cacr = val;
212 m68k_switch_sp(env);
213 break;
214 case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
215 /* TODO: Implement Access Control Registers. */
216 break;
217 case 0x801: /* VBR */
218 env->vbr = val;
219 break;
220 /* TODO: Implement control registers. */
221 default:
222 cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n",
223 reg, val);
227 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
229 uint32_t acc;
230 int8_t exthigh;
231 uint8_t extlow;
232 uint64_t regval;
233 int i;
234 if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
235 for (i = 0; i < 4; i++) {
236 regval = env->macc[i];
237 exthigh = regval >> 40;
238 if (env->macsr & MACSR_FI) {
239 acc = regval >> 8;
240 extlow = regval;
241 } else {
242 acc = regval;
243 extlow = regval >> 32;
245 if (env->macsr & MACSR_FI) {
246 regval = (((uint64_t)acc) << 8) | extlow;
247 regval |= ((int64_t)exthigh) << 40;
248 } else if (env->macsr & MACSR_SU) {
249 regval = acc | (((int64_t)extlow) << 32);
250 regval |= ((int64_t)exthigh) << 40;
251 } else {
252 regval = acc | (((uint64_t)extlow) << 32);
253 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
255 env->macc[i] = regval;
258 env->macsr = val;
261 void m68k_switch_sp(CPUM68KState *env)
263 int new_sp;
265 env->sp[env->current_sp] = env->aregs[7];
266 new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
267 ? M68K_SSP : M68K_USP;
268 env->aregs[7] = env->sp[new_sp];
269 env->current_sp = new_sp;
272 #if defined(CONFIG_USER_ONLY)
274 int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
275 int mmu_idx)
277 env->exception_index = EXCP_ACCESS;
278 env->mmu.ar = address;
279 return 1;
282 #else
284 /* MMU */
286 /* TODO: This will need fixing once the MMU is implemented. */
287 hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr)
289 return addr;
292 int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
293 int mmu_idx)
295 int prot;
297 address &= TARGET_PAGE_MASK;
298 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
299 tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
300 return 0;
303 /* Notify CPU of a pending interrupt. Prioritization and vectoring should
304 be handled by the interrupt controller. Real hardware only requests
305 the vector when the interrupt is acknowledged by the CPU. For
306 simplicitly we calculate it when the interrupt is signalled. */
307 void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector)
309 env->pending_level = level;
310 env->pending_vector = vector;
311 if (level)
312 cpu_interrupt(env, CPU_INTERRUPT_HARD);
313 else
314 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
317 #endif
319 uint32_t HELPER(bitrev)(uint32_t x)
321 x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
322 x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
323 x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
324 return bswap32(x);
327 uint32_t HELPER(ff1)(uint32_t x)
329 int n;
330 for (n = 32; x; n--)
331 x >>= 1;
332 return n;
335 uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
337 /* The result has the opposite sign to the original value. */
338 if (ccr & CCF_V)
339 val = (((int32_t)val) >> 31) ^ SIGNBIT;
340 return val;
343 uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
345 uint32_t res;
346 uint32_t old_flags;
348 old_flags = env->cc_dest;
349 if (env->cc_x) {
350 env->cc_x = (op1 <= op2);
351 env->cc_op = CC_OP_SUBX;
352 res = op1 - (op2 + 1);
353 } else {
354 env->cc_x = (op1 < op2);
355 env->cc_op = CC_OP_SUB;
356 res = op1 - op2;
358 env->cc_dest = res;
359 env->cc_src = op2;
360 cpu_m68k_flush_flags(env, env->cc_op);
361 /* !Z is sticky. */
362 env->cc_dest &= (old_flags | ~CCF_Z);
363 return res;
366 uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
368 uint32_t res;
369 uint32_t old_flags;
371 old_flags = env->cc_dest;
372 if (env->cc_x) {
373 res = op1 + op2 + 1;
374 env->cc_x = (res <= op2);
375 env->cc_op = CC_OP_ADDX;
376 } else {
377 res = op1 + op2;
378 env->cc_x = (res < op2);
379 env->cc_op = CC_OP_ADD;
381 env->cc_dest = res;
382 env->cc_src = op2;
383 cpu_m68k_flush_flags(env, env->cc_op);
384 /* !Z is sticky. */
385 env->cc_dest &= (old_flags | ~CCF_Z);
386 return res;
389 uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
391 return a < b;
394 void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
396 env->sr = val & 0xffff;
397 m68k_switch_sp(env);
400 uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
402 uint32_t result;
403 uint32_t cf;
405 shift &= 63;
406 if (shift == 0) {
407 result = val;
408 cf = env->cc_src & CCF_C;
409 } else if (shift < 32) {
410 result = val << shift;
411 cf = (val >> (32 - shift)) & 1;
412 } else if (shift == 32) {
413 result = 0;
414 cf = val & 1;
415 } else /* shift > 32 */ {
416 result = 0;
417 cf = 0;
419 env->cc_src = cf;
420 env->cc_x = (cf != 0);
421 env->cc_dest = result;
422 return result;
425 uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
427 uint32_t result;
428 uint32_t cf;
430 shift &= 63;
431 if (shift == 0) {
432 result = val;
433 cf = env->cc_src & CCF_C;
434 } else if (shift < 32) {
435 result = val >> shift;
436 cf = (val >> (shift - 1)) & 1;
437 } else if (shift == 32) {
438 result = 0;
439 cf = val >> 31;
440 } else /* shift > 32 */ {
441 result = 0;
442 cf = 0;
444 env->cc_src = cf;
445 env->cc_x = (cf != 0);
446 env->cc_dest = result;
447 return result;
450 uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
452 uint32_t result;
453 uint32_t cf;
455 shift &= 63;
456 if (shift == 0) {
457 result = val;
458 cf = (env->cc_src & CCF_C) != 0;
459 } else if (shift < 32) {
460 result = (int32_t)val >> shift;
461 cf = (val >> (shift - 1)) & 1;
462 } else /* shift >= 32 */ {
463 result = (int32_t)val >> 31;
464 cf = val >> 31;
466 env->cc_src = cf;
467 env->cc_x = cf;
468 env->cc_dest = result;
469 return result;
472 /* FPU helpers. */
473 uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val)
475 return float64_to_int32(val, &env->fp_status);
478 float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val)
480 return float64_to_float32(val, &env->fp_status);
483 float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val)
485 return int32_to_float64(val, &env->fp_status);
488 float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val)
490 return float32_to_float64(val, &env->fp_status);
493 float64 HELPER(iround_f64)(CPUM68KState *env, float64 val)
495 return float64_round_to_int(val, &env->fp_status);
498 float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val)
500 return float64_trunc_to_int(val, &env->fp_status);
503 float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val)
505 return float64_sqrt(val, &env->fp_status);
508 float64 HELPER(abs_f64)(float64 val)
510 return float64_abs(val);
513 float64 HELPER(chs_f64)(float64 val)
515 return float64_chs(val);
518 float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b)
520 return float64_add(a, b, &env->fp_status);
523 float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b)
525 return float64_sub(a, b, &env->fp_status);
528 float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b)
530 return float64_mul(a, b, &env->fp_status);
533 float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b)
535 return float64_div(a, b, &env->fp_status);
538 float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
540 /* ??? This may incorrectly raise exceptions. */
541 /* ??? Should flush denormals to zero. */
542 float64 res;
543 res = float64_sub(a, b, &env->fp_status);
544 if (float64_is_quiet_nan(res)) {
545 /* +/-inf compares equal against itself, but sub returns nan. */
546 if (!float64_is_quiet_nan(a)
547 && !float64_is_quiet_nan(b)) {
548 res = float64_zero;
549 if (float64_lt_quiet(a, res, &env->fp_status))
550 res = float64_chs(res);
553 return res;
556 uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val)
558 return float64_compare_quiet(val, float64_zero, &env->fp_status);
561 /* MAC unit. */
562 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
563 take values, others take register numbers and manipulate the contents
564 in-place. */
565 void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
567 uint32_t mask;
568 env->macc[dest] = env->macc[src];
569 mask = MACSR_PAV0 << dest;
570 if (env->macsr & (MACSR_PAV0 << src))
571 env->macsr |= mask;
572 else
573 env->macsr &= ~mask;
576 uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
578 int64_t product;
579 int64_t res;
581 product = (uint64_t)op1 * op2;
582 res = (product << 24) >> 24;
583 if (res != product) {
584 env->macsr |= MACSR_V;
585 if (env->macsr & MACSR_OMC) {
586 /* Make sure the accumulate operation overflows. */
587 if (product < 0)
588 res = ~(1ll << 50);
589 else
590 res = 1ll << 50;
593 return res;
596 uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
598 uint64_t product;
600 product = (uint64_t)op1 * op2;
601 if (product & (0xffffffull << 40)) {
602 env->macsr |= MACSR_V;
603 if (env->macsr & MACSR_OMC) {
604 /* Make sure the accumulate operation overflows. */
605 product = 1ll << 50;
606 } else {
607 product &= ((1ull << 40) - 1);
610 return product;
613 uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
615 uint64_t product;
616 uint32_t remainder;
618 product = (uint64_t)op1 * op2;
619 if (env->macsr & MACSR_RT) {
620 remainder = product & 0xffffff;
621 product >>= 24;
622 if (remainder > 0x800000)
623 product++;
624 else if (remainder == 0x800000)
625 product += (product & 1);
626 } else {
627 product >>= 24;
629 return product;
632 void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
634 int64_t tmp;
635 int64_t result;
636 tmp = env->macc[acc];
637 result = ((tmp << 16) >> 16);
638 if (result != tmp) {
639 env->macsr |= MACSR_V;
641 if (env->macsr & MACSR_V) {
642 env->macsr |= MACSR_PAV0 << acc;
643 if (env->macsr & MACSR_OMC) {
644 /* The result is saturated to 32 bits, despite overflow occurring
645 at 48 bits. Seems weird, but that's what the hardware docs
646 say. */
647 result = (result >> 63) ^ 0x7fffffff;
650 env->macc[acc] = result;
653 void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
655 uint64_t val;
657 val = env->macc[acc];
658 if (val & (0xffffull << 48)) {
659 env->macsr |= MACSR_V;
661 if (env->macsr & MACSR_V) {
662 env->macsr |= MACSR_PAV0 << acc;
663 if (env->macsr & MACSR_OMC) {
664 if (val > (1ull << 53))
665 val = 0;
666 else
667 val = (1ull << 48) - 1;
668 } else {
669 val &= ((1ull << 48) - 1);
672 env->macc[acc] = val;
675 void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
677 int64_t sum;
678 int64_t result;
680 sum = env->macc[acc];
681 result = (sum << 16) >> 16;
682 if (result != sum) {
683 env->macsr |= MACSR_V;
685 if (env->macsr & MACSR_V) {
686 env->macsr |= MACSR_PAV0 << acc;
687 if (env->macsr & MACSR_OMC) {
688 result = (result >> 63) ^ 0x7fffffffffffll;
691 env->macc[acc] = result;
694 void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
696 uint64_t val;
697 val = env->macc[acc];
698 if (val == 0) {
699 env->macsr |= MACSR_Z;
700 } else if (val & (1ull << 47)) {
701 env->macsr |= MACSR_N;
703 if (env->macsr & (MACSR_PAV0 << acc)) {
704 env->macsr |= MACSR_V;
706 if (env->macsr & MACSR_FI) {
707 val = ((int64_t)val) >> 40;
708 if (val != 0 && val != -1)
709 env->macsr |= MACSR_EV;
710 } else if (env->macsr & MACSR_SU) {
711 val = ((int64_t)val) >> 32;
712 if (val != 0 && val != -1)
713 env->macsr |= MACSR_EV;
714 } else {
715 if ((val >> 32) != 0)
716 env->macsr |= MACSR_EV;
720 void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
722 cpu_m68k_flush_flags(env, cc_op);
725 uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
727 int rem;
728 uint32_t result;
730 if (env->macsr & MACSR_SU) {
731 /* 16-bit rounding. */
732 rem = val & 0xffffff;
733 val = (val >> 24) & 0xffffu;
734 if (rem > 0x800000)
735 val++;
736 else if (rem == 0x800000)
737 val += (val & 1);
738 } else if (env->macsr & MACSR_RT) {
739 /* 32-bit rounding. */
740 rem = val & 0xff;
741 val >>= 8;
742 if (rem > 0x80)
743 val++;
744 else if (rem == 0x80)
745 val += (val & 1);
746 } else {
747 /* No rounding. */
748 val >>= 8;
750 if (env->macsr & MACSR_OMC) {
751 /* Saturate. */
752 if (env->macsr & MACSR_SU) {
753 if (val != (uint16_t) val) {
754 result = ((val >> 63) ^ 0x7fff) & 0xffff;
755 } else {
756 result = val & 0xffff;
758 } else {
759 if (val != (uint32_t)val) {
760 result = ((uint32_t)(val >> 63) & 0x7fffffff);
761 } else {
762 result = (uint32_t)val;
765 } else {
766 /* No saturation. */
767 if (env->macsr & MACSR_SU) {
768 result = val & 0xffff;
769 } else {
770 result = (uint32_t)val;
773 return result;
776 uint32_t HELPER(get_macs)(uint64_t val)
778 if (val == (int32_t)val) {
779 return (int32_t)val;
780 } else {
781 return (val >> 61) ^ ~SIGNBIT;
785 uint32_t HELPER(get_macu)(uint64_t val)
787 if ((val >> 32) == 0) {
788 return (uint32_t)val;
789 } else {
790 return 0xffffffffu;
794 uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
796 uint32_t val;
797 val = env->macc[acc] & 0x00ff;
798 val = (env->macc[acc] >> 32) & 0xff00;
799 val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
800 val |= (env->macc[acc + 1] >> 16) & 0xff000000;
801 return val;
804 uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
806 uint32_t val;
807 val = (env->macc[acc] >> 32) & 0xffff;
808 val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
809 return val;
812 void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
814 int64_t res;
815 int32_t tmp;
816 res = env->macc[acc] & 0xffffffff00ull;
817 tmp = (int16_t)(val & 0xff00);
818 res |= ((int64_t)tmp) << 32;
819 res |= val & 0xff;
820 env->macc[acc] = res;
821 res = env->macc[acc + 1] & 0xffffffff00ull;
822 tmp = (val & 0xff000000);
823 res |= ((int64_t)tmp) << 16;
824 res |= (val >> 16) & 0xff;
825 env->macc[acc + 1] = res;
828 void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
830 int64_t res;
831 int32_t tmp;
832 res = (uint32_t)env->macc[acc];
833 tmp = (int16_t)val;
834 res |= ((int64_t)tmp) << 32;
835 env->macc[acc] = res;
836 res = (uint32_t)env->macc[acc + 1];
837 tmp = val & 0xffff0000;
838 res |= (int64_t)tmp << 16;
839 env->macc[acc + 1] = res;
842 void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
844 uint64_t res;
845 res = (uint32_t)env->macc[acc];
846 res |= ((uint64_t)(val & 0xffff)) << 32;
847 env->macc[acc] = res;
848 res = (uint32_t)env->macc[acc + 1];
849 res |= (uint64_t)(val & 0xffff0000) << 16;
850 env->macc[acc + 1] = res;