configure: Undefine _FORTIFY_SOURCE prior using it
[qemu/ar7.git] / target-m68k / helper.c
blob00a7a08e830658f357c9f2240b52a03b93938395
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 "exec/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-" TYPE_M68K_CPU) == 0) {
38 return 1;
39 } else if (strcmp(name_b, "any-" TYPE_M68K_CPU) == 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;
50 const char *typename;
51 char *name;
53 typename = object_class_get_name(c);
54 name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_M68K_CPU));
55 (*s->cpu_fprintf)(s->file, "%s\n",
56 name);
57 g_free(name);
60 void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
62 CPUListState s = {
63 .file = f,
64 .cpu_fprintf = cpu_fprintf,
66 GSList *list;
68 list = object_class_get_list(TYPE_M68K_CPU, false);
69 list = g_slist_sort(list, m68k_cpu_list_compare);
70 g_slist_foreach(list, m68k_cpu_list_entry, &s);
71 g_slist_free(list);
74 static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
76 if (n < 8) {
77 stfq_p(mem_buf, env->fregs[n]);
78 return 8;
80 if (n < 11) {
81 /* FP control registers (not implemented) */
82 memset(mem_buf, 0, 4);
83 return 4;
85 return 0;
88 static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
90 if (n < 8) {
91 env->fregs[n] = ldfq_p(mem_buf);
92 return 8;
94 if (n < 11) {
95 /* FP control registers (not implemented) */
96 return 4;
98 return 0;
101 M68kCPU *cpu_m68k_init(const char *cpu_model)
103 M68kCPU *cpu;
104 CPUM68KState *env;
105 ObjectClass *oc;
107 oc = cpu_class_by_name(TYPE_M68K_CPU, cpu_model);
108 if (oc == NULL) {
109 return NULL;
111 cpu = M68K_CPU(object_new(object_class_get_name(oc)));
112 env = &cpu->env;
113 env->cpu_model_str = cpu_model;
115 register_m68k_insns(env);
117 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
119 return cpu;
122 void m68k_cpu_init_gdb(M68kCPU *cpu)
124 CPUState *cs = CPU(cpu);
125 CPUM68KState *env = &cpu->env;
127 if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
128 gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg,
129 11, "cf-fp.xml", 18);
131 /* TODO: Add [E]MAC registers. */
134 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
136 int flags;
137 uint32_t src;
138 uint32_t dest;
139 uint32_t tmp;
141 #define HIGHBIT 0x80000000u
143 #define SET_NZ(x) do { \
144 if ((x) == 0) \
145 flags |= CCF_Z; \
146 else if ((int32_t)(x) < 0) \
147 flags |= CCF_N; \
148 } while (0)
150 #define SET_FLAGS_SUB(type, utype) do { \
151 SET_NZ((type)dest); \
152 tmp = dest + src; \
153 if ((utype) tmp < (utype) src) \
154 flags |= CCF_C; \
155 if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \
156 flags |= CCF_V; \
157 } while (0)
159 flags = 0;
160 src = env->cc_src;
161 dest = env->cc_dest;
162 switch (cc_op) {
163 case CC_OP_FLAGS:
164 flags = dest;
165 break;
166 case CC_OP_LOGIC:
167 SET_NZ(dest);
168 break;
169 case CC_OP_ADD:
170 SET_NZ(dest);
171 if (dest < src)
172 flags |= CCF_C;
173 tmp = dest - src;
174 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
175 flags |= CCF_V;
176 break;
177 case CC_OP_SUB:
178 SET_FLAGS_SUB(int32_t, uint32_t);
179 break;
180 case CC_OP_CMPB:
181 SET_FLAGS_SUB(int8_t, uint8_t);
182 break;
183 case CC_OP_CMPW:
184 SET_FLAGS_SUB(int16_t, uint16_t);
185 break;
186 case CC_OP_ADDX:
187 SET_NZ(dest);
188 if (dest <= src)
189 flags |= CCF_C;
190 tmp = dest - src - 1;
191 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
192 flags |= CCF_V;
193 break;
194 case CC_OP_SUBX:
195 SET_NZ(dest);
196 tmp = dest + src + 1;
197 if (tmp <= src)
198 flags |= CCF_C;
199 if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
200 flags |= CCF_V;
201 break;
202 case CC_OP_SHIFT:
203 SET_NZ(dest);
204 if (src)
205 flags |= CCF_C;
206 break;
207 default:
208 cpu_abort(env, "Bad CC_OP %d", cc_op);
210 env->cc_op = CC_OP_FLAGS;
211 env->cc_dest = flags;
214 void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
216 switch (reg) {
217 case 0x02: /* CACR */
218 env->cacr = val;
219 m68k_switch_sp(env);
220 break;
221 case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
222 /* TODO: Implement Access Control Registers. */
223 break;
224 case 0x801: /* VBR */
225 env->vbr = val;
226 break;
227 /* TODO: Implement control registers. */
228 default:
229 cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n",
230 reg, val);
234 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
236 uint32_t acc;
237 int8_t exthigh;
238 uint8_t extlow;
239 uint64_t regval;
240 int i;
241 if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
242 for (i = 0; i < 4; i++) {
243 regval = env->macc[i];
244 exthigh = regval >> 40;
245 if (env->macsr & MACSR_FI) {
246 acc = regval >> 8;
247 extlow = regval;
248 } else {
249 acc = regval;
250 extlow = regval >> 32;
252 if (env->macsr & MACSR_FI) {
253 regval = (((uint64_t)acc) << 8) | extlow;
254 regval |= ((int64_t)exthigh) << 40;
255 } else if (env->macsr & MACSR_SU) {
256 regval = acc | (((int64_t)extlow) << 32);
257 regval |= ((int64_t)exthigh) << 40;
258 } else {
259 regval = acc | (((uint64_t)extlow) << 32);
260 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
262 env->macc[i] = regval;
265 env->macsr = val;
268 void m68k_switch_sp(CPUM68KState *env)
270 int new_sp;
272 env->sp[env->current_sp] = env->aregs[7];
273 new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
274 ? M68K_SSP : M68K_USP;
275 env->aregs[7] = env->sp[new_sp];
276 env->current_sp = new_sp;
279 #if defined(CONFIG_USER_ONLY)
281 int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
282 int mmu_idx)
284 env->exception_index = EXCP_ACCESS;
285 env->mmu.ar = address;
286 return 1;
289 #else
291 /* MMU */
293 /* TODO: This will need fixing once the MMU is implemented. */
294 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
296 return addr;
299 int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
300 int mmu_idx)
302 int prot;
304 address &= TARGET_PAGE_MASK;
305 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
306 tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
307 return 0;
310 /* Notify CPU of a pending interrupt. Prioritization and vectoring should
311 be handled by the interrupt controller. Real hardware only requests
312 the vector when the interrupt is acknowledged by the CPU. For
313 simplicitly we calculate it when the interrupt is signalled. */
314 void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
316 CPUState *cs = CPU(cpu);
317 CPUM68KState *env = &cpu->env;
319 env->pending_level = level;
320 env->pending_vector = vector;
321 if (level) {
322 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
323 } else {
324 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
328 #endif
330 uint32_t HELPER(bitrev)(uint32_t x)
332 x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
333 x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
334 x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
335 return bswap32(x);
338 uint32_t HELPER(ff1)(uint32_t x)
340 int n;
341 for (n = 32; x; n--)
342 x >>= 1;
343 return n;
346 uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
348 /* The result has the opposite sign to the original value. */
349 if (ccr & CCF_V)
350 val = (((int32_t)val) >> 31) ^ SIGNBIT;
351 return val;
354 uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
356 uint32_t res;
357 uint32_t old_flags;
359 old_flags = env->cc_dest;
360 if (env->cc_x) {
361 env->cc_x = (op1 <= op2);
362 env->cc_op = CC_OP_SUBX;
363 res = op1 - (op2 + 1);
364 } else {
365 env->cc_x = (op1 < op2);
366 env->cc_op = CC_OP_SUB;
367 res = op1 - op2;
369 env->cc_dest = res;
370 env->cc_src = op2;
371 cpu_m68k_flush_flags(env, env->cc_op);
372 /* !Z is sticky. */
373 env->cc_dest &= (old_flags | ~CCF_Z);
374 return res;
377 uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
379 uint32_t res;
380 uint32_t old_flags;
382 old_flags = env->cc_dest;
383 if (env->cc_x) {
384 res = op1 + op2 + 1;
385 env->cc_x = (res <= op2);
386 env->cc_op = CC_OP_ADDX;
387 } else {
388 res = op1 + op2;
389 env->cc_x = (res < op2);
390 env->cc_op = CC_OP_ADD;
392 env->cc_dest = res;
393 env->cc_src = op2;
394 cpu_m68k_flush_flags(env, env->cc_op);
395 /* !Z is sticky. */
396 env->cc_dest &= (old_flags | ~CCF_Z);
397 return res;
400 uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
402 return a < b;
405 void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
407 env->sr = val & 0xffff;
408 m68k_switch_sp(env);
411 uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
413 uint32_t result;
414 uint32_t cf;
416 shift &= 63;
417 if (shift == 0) {
418 result = val;
419 cf = env->cc_src & CCF_C;
420 } else if (shift < 32) {
421 result = val << shift;
422 cf = (val >> (32 - shift)) & 1;
423 } else if (shift == 32) {
424 result = 0;
425 cf = val & 1;
426 } else /* shift > 32 */ {
427 result = 0;
428 cf = 0;
430 env->cc_src = cf;
431 env->cc_x = (cf != 0);
432 env->cc_dest = result;
433 return result;
436 uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
438 uint32_t result;
439 uint32_t cf;
441 shift &= 63;
442 if (shift == 0) {
443 result = val;
444 cf = env->cc_src & CCF_C;
445 } else if (shift < 32) {
446 result = val >> shift;
447 cf = (val >> (shift - 1)) & 1;
448 } else if (shift == 32) {
449 result = 0;
450 cf = val >> 31;
451 } else /* shift > 32 */ {
452 result = 0;
453 cf = 0;
455 env->cc_src = cf;
456 env->cc_x = (cf != 0);
457 env->cc_dest = result;
458 return result;
461 uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
463 uint32_t result;
464 uint32_t cf;
466 shift &= 63;
467 if (shift == 0) {
468 result = val;
469 cf = (env->cc_src & CCF_C) != 0;
470 } else if (shift < 32) {
471 result = (int32_t)val >> shift;
472 cf = (val >> (shift - 1)) & 1;
473 } else /* shift >= 32 */ {
474 result = (int32_t)val >> 31;
475 cf = val >> 31;
477 env->cc_src = cf;
478 env->cc_x = cf;
479 env->cc_dest = result;
480 return result;
483 /* FPU helpers. */
484 uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val)
486 return float64_to_int32(val, &env->fp_status);
489 float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val)
491 return float64_to_float32(val, &env->fp_status);
494 float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val)
496 return int32_to_float64(val, &env->fp_status);
499 float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val)
501 return float32_to_float64(val, &env->fp_status);
504 float64 HELPER(iround_f64)(CPUM68KState *env, float64 val)
506 return float64_round_to_int(val, &env->fp_status);
509 float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val)
511 return float64_trunc_to_int(val, &env->fp_status);
514 float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val)
516 return float64_sqrt(val, &env->fp_status);
519 float64 HELPER(abs_f64)(float64 val)
521 return float64_abs(val);
524 float64 HELPER(chs_f64)(float64 val)
526 return float64_chs(val);
529 float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b)
531 return float64_add(a, b, &env->fp_status);
534 float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b)
536 return float64_sub(a, b, &env->fp_status);
539 float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b)
541 return float64_mul(a, b, &env->fp_status);
544 float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b)
546 return float64_div(a, b, &env->fp_status);
549 float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
551 /* ??? This may incorrectly raise exceptions. */
552 /* ??? Should flush denormals to zero. */
553 float64 res;
554 res = float64_sub(a, b, &env->fp_status);
555 if (float64_is_quiet_nan(res)) {
556 /* +/-inf compares equal against itself, but sub returns nan. */
557 if (!float64_is_quiet_nan(a)
558 && !float64_is_quiet_nan(b)) {
559 res = float64_zero;
560 if (float64_lt_quiet(a, res, &env->fp_status))
561 res = float64_chs(res);
564 return res;
567 uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val)
569 return float64_compare_quiet(val, float64_zero, &env->fp_status);
572 /* MAC unit. */
573 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
574 take values, others take register numbers and manipulate the contents
575 in-place. */
576 void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
578 uint32_t mask;
579 env->macc[dest] = env->macc[src];
580 mask = MACSR_PAV0 << dest;
581 if (env->macsr & (MACSR_PAV0 << src))
582 env->macsr |= mask;
583 else
584 env->macsr &= ~mask;
587 uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
589 int64_t product;
590 int64_t res;
592 product = (uint64_t)op1 * op2;
593 res = (product << 24) >> 24;
594 if (res != product) {
595 env->macsr |= MACSR_V;
596 if (env->macsr & MACSR_OMC) {
597 /* Make sure the accumulate operation overflows. */
598 if (product < 0)
599 res = ~(1ll << 50);
600 else
601 res = 1ll << 50;
604 return res;
607 uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
609 uint64_t product;
611 product = (uint64_t)op1 * op2;
612 if (product & (0xffffffull << 40)) {
613 env->macsr |= MACSR_V;
614 if (env->macsr & MACSR_OMC) {
615 /* Make sure the accumulate operation overflows. */
616 product = 1ll << 50;
617 } else {
618 product &= ((1ull << 40) - 1);
621 return product;
624 uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
626 uint64_t product;
627 uint32_t remainder;
629 product = (uint64_t)op1 * op2;
630 if (env->macsr & MACSR_RT) {
631 remainder = product & 0xffffff;
632 product >>= 24;
633 if (remainder > 0x800000)
634 product++;
635 else if (remainder == 0x800000)
636 product += (product & 1);
637 } else {
638 product >>= 24;
640 return product;
643 void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
645 int64_t tmp;
646 int64_t result;
647 tmp = env->macc[acc];
648 result = ((tmp << 16) >> 16);
649 if (result != tmp) {
650 env->macsr |= MACSR_V;
652 if (env->macsr & MACSR_V) {
653 env->macsr |= MACSR_PAV0 << acc;
654 if (env->macsr & MACSR_OMC) {
655 /* The result is saturated to 32 bits, despite overflow occurring
656 at 48 bits. Seems weird, but that's what the hardware docs
657 say. */
658 result = (result >> 63) ^ 0x7fffffff;
661 env->macc[acc] = result;
664 void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
666 uint64_t val;
668 val = env->macc[acc];
669 if (val & (0xffffull << 48)) {
670 env->macsr |= MACSR_V;
672 if (env->macsr & MACSR_V) {
673 env->macsr |= MACSR_PAV0 << acc;
674 if (env->macsr & MACSR_OMC) {
675 if (val > (1ull << 53))
676 val = 0;
677 else
678 val = (1ull << 48) - 1;
679 } else {
680 val &= ((1ull << 48) - 1);
683 env->macc[acc] = val;
686 void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
688 int64_t sum;
689 int64_t result;
691 sum = env->macc[acc];
692 result = (sum << 16) >> 16;
693 if (result != sum) {
694 env->macsr |= MACSR_V;
696 if (env->macsr & MACSR_V) {
697 env->macsr |= MACSR_PAV0 << acc;
698 if (env->macsr & MACSR_OMC) {
699 result = (result >> 63) ^ 0x7fffffffffffll;
702 env->macc[acc] = result;
705 void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
707 uint64_t val;
708 val = env->macc[acc];
709 if (val == 0) {
710 env->macsr |= MACSR_Z;
711 } else if (val & (1ull << 47)) {
712 env->macsr |= MACSR_N;
714 if (env->macsr & (MACSR_PAV0 << acc)) {
715 env->macsr |= MACSR_V;
717 if (env->macsr & MACSR_FI) {
718 val = ((int64_t)val) >> 40;
719 if (val != 0 && val != -1)
720 env->macsr |= MACSR_EV;
721 } else if (env->macsr & MACSR_SU) {
722 val = ((int64_t)val) >> 32;
723 if (val != 0 && val != -1)
724 env->macsr |= MACSR_EV;
725 } else {
726 if ((val >> 32) != 0)
727 env->macsr |= MACSR_EV;
731 void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
733 cpu_m68k_flush_flags(env, cc_op);
736 uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
738 int rem;
739 uint32_t result;
741 if (env->macsr & MACSR_SU) {
742 /* 16-bit rounding. */
743 rem = val & 0xffffff;
744 val = (val >> 24) & 0xffffu;
745 if (rem > 0x800000)
746 val++;
747 else if (rem == 0x800000)
748 val += (val & 1);
749 } else if (env->macsr & MACSR_RT) {
750 /* 32-bit rounding. */
751 rem = val & 0xff;
752 val >>= 8;
753 if (rem > 0x80)
754 val++;
755 else if (rem == 0x80)
756 val += (val & 1);
757 } else {
758 /* No rounding. */
759 val >>= 8;
761 if (env->macsr & MACSR_OMC) {
762 /* Saturate. */
763 if (env->macsr & MACSR_SU) {
764 if (val != (uint16_t) val) {
765 result = ((val >> 63) ^ 0x7fff) & 0xffff;
766 } else {
767 result = val & 0xffff;
769 } else {
770 if (val != (uint32_t)val) {
771 result = ((uint32_t)(val >> 63) & 0x7fffffff);
772 } else {
773 result = (uint32_t)val;
776 } else {
777 /* No saturation. */
778 if (env->macsr & MACSR_SU) {
779 result = val & 0xffff;
780 } else {
781 result = (uint32_t)val;
784 return result;
787 uint32_t HELPER(get_macs)(uint64_t val)
789 if (val == (int32_t)val) {
790 return (int32_t)val;
791 } else {
792 return (val >> 61) ^ ~SIGNBIT;
796 uint32_t HELPER(get_macu)(uint64_t val)
798 if ((val >> 32) == 0) {
799 return (uint32_t)val;
800 } else {
801 return 0xffffffffu;
805 uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
807 uint32_t val;
808 val = env->macc[acc] & 0x00ff;
809 val = (env->macc[acc] >> 32) & 0xff00;
810 val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
811 val |= (env->macc[acc + 1] >> 16) & 0xff000000;
812 return val;
815 uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
817 uint32_t val;
818 val = (env->macc[acc] >> 32) & 0xffff;
819 val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
820 return val;
823 void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
825 int64_t res;
826 int32_t tmp;
827 res = env->macc[acc] & 0xffffffff00ull;
828 tmp = (int16_t)(val & 0xff00);
829 res |= ((int64_t)tmp) << 32;
830 res |= val & 0xff;
831 env->macc[acc] = res;
832 res = env->macc[acc + 1] & 0xffffffff00ull;
833 tmp = (val & 0xff000000);
834 res |= ((int64_t)tmp) << 16;
835 res |= (val >> 16) & 0xff;
836 env->macc[acc + 1] = res;
839 void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
841 int64_t res;
842 int32_t tmp;
843 res = (uint32_t)env->macc[acc];
844 tmp = (int16_t)val;
845 res |= ((int64_t)tmp) << 32;
846 env->macc[acc] = res;
847 res = (uint32_t)env->macc[acc + 1];
848 tmp = val & 0xffff0000;
849 res |= (int64_t)tmp << 16;
850 env->macc[acc + 1] = res;
853 void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
855 uint64_t res;
856 res = (uint32_t)env->macc[acc];
857 res |= ((uint64_t)(val & 0xffff)) << 32;
858 env->macc[acc] = res;
859 res = (uint32_t)env->macc[acc + 1];
860 res |= (uint64_t)(val & 0xffff0000) << 16;
861 env->macc[acc + 1] = res;