Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
[qemu/ar7.git] / target-m68k / helper.c
blob77225a20051ec7187cef2562a4d959ccf901c8f1
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 "exec/helper-proto.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;
114 register_m68k_insns(env);
116 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
118 return cpu;
121 void m68k_cpu_init_gdb(M68kCPU *cpu)
123 CPUState *cs = CPU(cpu);
124 CPUM68KState *env = &cpu->env;
126 if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
127 gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg,
128 11, "cf-fp.xml", 18);
130 /* TODO: Add [E]MAC registers. */
133 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
135 M68kCPU *cpu = m68k_env_get_cpu(env);
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(CPU(cpu), "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 M68kCPU *cpu = m68k_env_get_cpu(env);
218 switch (reg) {
219 case 0x02: /* CACR */
220 env->cacr = val;
221 m68k_switch_sp(env);
222 break;
223 case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
224 /* TODO: Implement Access Control Registers. */
225 break;
226 case 0x801: /* VBR */
227 env->vbr = val;
228 break;
229 /* TODO: Implement control registers. */
230 default:
231 cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x = 0x%x\n",
232 reg, val);
236 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
238 uint32_t acc;
239 int8_t exthigh;
240 uint8_t extlow;
241 uint64_t regval;
242 int i;
243 if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
244 for (i = 0; i < 4; i++) {
245 regval = env->macc[i];
246 exthigh = regval >> 40;
247 if (env->macsr & MACSR_FI) {
248 acc = regval >> 8;
249 extlow = regval;
250 } else {
251 acc = regval;
252 extlow = regval >> 32;
254 if (env->macsr & MACSR_FI) {
255 regval = (((uint64_t)acc) << 8) | extlow;
256 regval |= ((int64_t)exthigh) << 40;
257 } else if (env->macsr & MACSR_SU) {
258 regval = acc | (((int64_t)extlow) << 32);
259 regval |= ((int64_t)exthigh) << 40;
260 } else {
261 regval = acc | (((uint64_t)extlow) << 32);
262 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
264 env->macc[i] = regval;
267 env->macsr = val;
270 void m68k_switch_sp(CPUM68KState *env)
272 int new_sp;
274 env->sp[env->current_sp] = env->aregs[7];
275 new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
276 ? M68K_SSP : M68K_USP;
277 env->aregs[7] = env->sp[new_sp];
278 env->current_sp = new_sp;
281 #if defined(CONFIG_USER_ONLY)
283 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
284 int mmu_idx)
286 M68kCPU *cpu = M68K_CPU(cs);
288 cs->exception_index = EXCP_ACCESS;
289 cpu->env.mmu.ar = address;
290 return 1;
293 #else
295 /* MMU */
297 /* TODO: This will need fixing once the MMU is implemented. */
298 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
300 return addr;
303 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
304 int mmu_idx)
306 int prot;
308 address &= TARGET_PAGE_MASK;
309 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
310 tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
311 return 0;
314 /* Notify CPU of a pending interrupt. Prioritization and vectoring should
315 be handled by the interrupt controller. Real hardware only requests
316 the vector when the interrupt is acknowledged by the CPU. For
317 simplicitly we calculate it when the interrupt is signalled. */
318 void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
320 CPUState *cs = CPU(cpu);
321 CPUM68KState *env = &cpu->env;
323 env->pending_level = level;
324 env->pending_vector = vector;
325 if (level) {
326 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
327 } else {
328 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
332 #endif
334 uint32_t HELPER(bitrev)(uint32_t x)
336 x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
337 x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
338 x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
339 return bswap32(x);
342 uint32_t HELPER(ff1)(uint32_t x)
344 int n;
345 for (n = 32; x; n--)
346 x >>= 1;
347 return n;
350 uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
352 /* The result has the opposite sign to the original value. */
353 if (ccr & CCF_V)
354 val = (((int32_t)val) >> 31) ^ SIGNBIT;
355 return val;
358 uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
360 uint32_t res;
361 uint32_t old_flags;
363 old_flags = env->cc_dest;
364 if (env->cc_x) {
365 env->cc_x = (op1 <= op2);
366 env->cc_op = CC_OP_SUBX;
367 res = op1 - (op2 + 1);
368 } else {
369 env->cc_x = (op1 < op2);
370 env->cc_op = CC_OP_SUB;
371 res = op1 - op2;
373 env->cc_dest = res;
374 env->cc_src = op2;
375 cpu_m68k_flush_flags(env, env->cc_op);
376 /* !Z is sticky. */
377 env->cc_dest &= (old_flags | ~CCF_Z);
378 return res;
381 uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
383 uint32_t res;
384 uint32_t old_flags;
386 old_flags = env->cc_dest;
387 if (env->cc_x) {
388 res = op1 + op2 + 1;
389 env->cc_x = (res <= op2);
390 env->cc_op = CC_OP_ADDX;
391 } else {
392 res = op1 + op2;
393 env->cc_x = (res < op2);
394 env->cc_op = CC_OP_ADD;
396 env->cc_dest = res;
397 env->cc_src = op2;
398 cpu_m68k_flush_flags(env, env->cc_op);
399 /* !Z is sticky. */
400 env->cc_dest &= (old_flags | ~CCF_Z);
401 return res;
404 uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
406 return a < b;
409 void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
411 env->sr = val & 0xffff;
412 m68k_switch_sp(env);
415 uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
417 uint32_t result;
418 uint32_t cf;
420 shift &= 63;
421 if (shift == 0) {
422 result = val;
423 cf = env->cc_src & CCF_C;
424 } else if (shift < 32) {
425 result = val << shift;
426 cf = (val >> (32 - shift)) & 1;
427 } else if (shift == 32) {
428 result = 0;
429 cf = val & 1;
430 } else /* shift > 32 */ {
431 result = 0;
432 cf = 0;
434 env->cc_src = cf;
435 env->cc_x = (cf != 0);
436 env->cc_dest = result;
437 return result;
440 uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
442 uint32_t result;
443 uint32_t cf;
445 shift &= 63;
446 if (shift == 0) {
447 result = val;
448 cf = env->cc_src & CCF_C;
449 } else if (shift < 32) {
450 result = val >> shift;
451 cf = (val >> (shift - 1)) & 1;
452 } else if (shift == 32) {
453 result = 0;
454 cf = val >> 31;
455 } else /* shift > 32 */ {
456 result = 0;
457 cf = 0;
459 env->cc_src = cf;
460 env->cc_x = (cf != 0);
461 env->cc_dest = result;
462 return result;
465 uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
467 uint32_t result;
468 uint32_t cf;
470 shift &= 63;
471 if (shift == 0) {
472 result = val;
473 cf = (env->cc_src & CCF_C) != 0;
474 } else if (shift < 32) {
475 result = (int32_t)val >> shift;
476 cf = (val >> (shift - 1)) & 1;
477 } else /* shift >= 32 */ {
478 result = (int32_t)val >> 31;
479 cf = val >> 31;
481 env->cc_src = cf;
482 env->cc_x = cf;
483 env->cc_dest = result;
484 return result;
487 /* FPU helpers. */
488 uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val)
490 return float64_to_int32(val, &env->fp_status);
493 float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val)
495 return float64_to_float32(val, &env->fp_status);
498 float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val)
500 return int32_to_float64(val, &env->fp_status);
503 float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val)
505 return float32_to_float64(val, &env->fp_status);
508 float64 HELPER(iround_f64)(CPUM68KState *env, float64 val)
510 return float64_round_to_int(val, &env->fp_status);
513 float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val)
515 return float64_trunc_to_int(val, &env->fp_status);
518 float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val)
520 return float64_sqrt(val, &env->fp_status);
523 float64 HELPER(abs_f64)(float64 val)
525 return float64_abs(val);
528 float64 HELPER(chs_f64)(float64 val)
530 return float64_chs(val);
533 float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b)
535 return float64_add(a, b, &env->fp_status);
538 float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b)
540 return float64_sub(a, b, &env->fp_status);
543 float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b)
545 return float64_mul(a, b, &env->fp_status);
548 float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b)
550 return float64_div(a, b, &env->fp_status);
553 float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
555 /* ??? This may incorrectly raise exceptions. */
556 /* ??? Should flush denormals to zero. */
557 float64 res;
558 res = float64_sub(a, b, &env->fp_status);
559 if (float64_is_quiet_nan(res)) {
560 /* +/-inf compares equal against itself, but sub returns nan. */
561 if (!float64_is_quiet_nan(a)
562 && !float64_is_quiet_nan(b)) {
563 res = float64_zero;
564 if (float64_lt_quiet(a, res, &env->fp_status))
565 res = float64_chs(res);
568 return res;
571 uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val)
573 return float64_compare_quiet(val, float64_zero, &env->fp_status);
576 /* MAC unit. */
577 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
578 take values, others take register numbers and manipulate the contents
579 in-place. */
580 void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
582 uint32_t mask;
583 env->macc[dest] = env->macc[src];
584 mask = MACSR_PAV0 << dest;
585 if (env->macsr & (MACSR_PAV0 << src))
586 env->macsr |= mask;
587 else
588 env->macsr &= ~mask;
591 uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
593 int64_t product;
594 int64_t res;
596 product = (uint64_t)op1 * op2;
597 res = (product << 24) >> 24;
598 if (res != product) {
599 env->macsr |= MACSR_V;
600 if (env->macsr & MACSR_OMC) {
601 /* Make sure the accumulate operation overflows. */
602 if (product < 0)
603 res = ~(1ll << 50);
604 else
605 res = 1ll << 50;
608 return res;
611 uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
613 uint64_t product;
615 product = (uint64_t)op1 * op2;
616 if (product & (0xffffffull << 40)) {
617 env->macsr |= MACSR_V;
618 if (env->macsr & MACSR_OMC) {
619 /* Make sure the accumulate operation overflows. */
620 product = 1ll << 50;
621 } else {
622 product &= ((1ull << 40) - 1);
625 return product;
628 uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
630 uint64_t product;
631 uint32_t remainder;
633 product = (uint64_t)op1 * op2;
634 if (env->macsr & MACSR_RT) {
635 remainder = product & 0xffffff;
636 product >>= 24;
637 if (remainder > 0x800000)
638 product++;
639 else if (remainder == 0x800000)
640 product += (product & 1);
641 } else {
642 product >>= 24;
644 return product;
647 void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
649 int64_t tmp;
650 int64_t result;
651 tmp = env->macc[acc];
652 result = ((tmp << 16) >> 16);
653 if (result != tmp) {
654 env->macsr |= MACSR_V;
656 if (env->macsr & MACSR_V) {
657 env->macsr |= MACSR_PAV0 << acc;
658 if (env->macsr & MACSR_OMC) {
659 /* The result is saturated to 32 bits, despite overflow occurring
660 at 48 bits. Seems weird, but that's what the hardware docs
661 say. */
662 result = (result >> 63) ^ 0x7fffffff;
665 env->macc[acc] = result;
668 void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
670 uint64_t val;
672 val = env->macc[acc];
673 if (val & (0xffffull << 48)) {
674 env->macsr |= MACSR_V;
676 if (env->macsr & MACSR_V) {
677 env->macsr |= MACSR_PAV0 << acc;
678 if (env->macsr & MACSR_OMC) {
679 if (val > (1ull << 53))
680 val = 0;
681 else
682 val = (1ull << 48) - 1;
683 } else {
684 val &= ((1ull << 48) - 1);
687 env->macc[acc] = val;
690 void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
692 int64_t sum;
693 int64_t result;
695 sum = env->macc[acc];
696 result = (sum << 16) >> 16;
697 if (result != sum) {
698 env->macsr |= MACSR_V;
700 if (env->macsr & MACSR_V) {
701 env->macsr |= MACSR_PAV0 << acc;
702 if (env->macsr & MACSR_OMC) {
703 result = (result >> 63) ^ 0x7fffffffffffll;
706 env->macc[acc] = result;
709 void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
711 uint64_t val;
712 val = env->macc[acc];
713 if (val == 0) {
714 env->macsr |= MACSR_Z;
715 } else if (val & (1ull << 47)) {
716 env->macsr |= MACSR_N;
718 if (env->macsr & (MACSR_PAV0 << acc)) {
719 env->macsr |= MACSR_V;
721 if (env->macsr & MACSR_FI) {
722 val = ((int64_t)val) >> 40;
723 if (val != 0 && val != -1)
724 env->macsr |= MACSR_EV;
725 } else if (env->macsr & MACSR_SU) {
726 val = ((int64_t)val) >> 32;
727 if (val != 0 && val != -1)
728 env->macsr |= MACSR_EV;
729 } else {
730 if ((val >> 32) != 0)
731 env->macsr |= MACSR_EV;
735 void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
737 cpu_m68k_flush_flags(env, cc_op);
740 uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
742 int rem;
743 uint32_t result;
745 if (env->macsr & MACSR_SU) {
746 /* 16-bit rounding. */
747 rem = val & 0xffffff;
748 val = (val >> 24) & 0xffffu;
749 if (rem > 0x800000)
750 val++;
751 else if (rem == 0x800000)
752 val += (val & 1);
753 } else if (env->macsr & MACSR_RT) {
754 /* 32-bit rounding. */
755 rem = val & 0xff;
756 val >>= 8;
757 if (rem > 0x80)
758 val++;
759 else if (rem == 0x80)
760 val += (val & 1);
761 } else {
762 /* No rounding. */
763 val >>= 8;
765 if (env->macsr & MACSR_OMC) {
766 /* Saturate. */
767 if (env->macsr & MACSR_SU) {
768 if (val != (uint16_t) val) {
769 result = ((val >> 63) ^ 0x7fff) & 0xffff;
770 } else {
771 result = val & 0xffff;
773 } else {
774 if (val != (uint32_t)val) {
775 result = ((uint32_t)(val >> 63) & 0x7fffffff);
776 } else {
777 result = (uint32_t)val;
780 } else {
781 /* No saturation. */
782 if (env->macsr & MACSR_SU) {
783 result = val & 0xffff;
784 } else {
785 result = (uint32_t)val;
788 return result;
791 uint32_t HELPER(get_macs)(uint64_t val)
793 if (val == (int32_t)val) {
794 return (int32_t)val;
795 } else {
796 return (val >> 61) ^ ~SIGNBIT;
800 uint32_t HELPER(get_macu)(uint64_t val)
802 if ((val >> 32) == 0) {
803 return (uint32_t)val;
804 } else {
805 return 0xffffffffu;
809 uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
811 uint32_t val;
812 val = env->macc[acc] & 0x00ff;
813 val = (env->macc[acc] >> 32) & 0xff00;
814 val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
815 val |= (env->macc[acc + 1] >> 16) & 0xff000000;
816 return val;
819 uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
821 uint32_t val;
822 val = (env->macc[acc] >> 32) & 0xffff;
823 val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
824 return val;
827 void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
829 int64_t res;
830 int32_t tmp;
831 res = env->macc[acc] & 0xffffffff00ull;
832 tmp = (int16_t)(val & 0xff00);
833 res |= ((int64_t)tmp) << 32;
834 res |= val & 0xff;
835 env->macc[acc] = res;
836 res = env->macc[acc + 1] & 0xffffffff00ull;
837 tmp = (val & 0xff000000);
838 res |= ((int64_t)tmp) << 16;
839 res |= (val >> 16) & 0xff;
840 env->macc[acc + 1] = res;
843 void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
845 int64_t res;
846 int32_t tmp;
847 res = (uint32_t)env->macc[acc];
848 tmp = (int16_t)val;
849 res |= ((int64_t)tmp) << 32;
850 env->macc[acc] = res;
851 res = (uint32_t)env->macc[acc + 1];
852 tmp = val & 0xffff0000;
853 res |= (int64_t)tmp << 16;
854 env->macc[acc + 1] = res;
857 void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
859 uint64_t res;
860 res = (uint32_t)env->macc[acc];
861 res |= ((uint64_t)(val & 0xffff)) << 32;
862 env->macc[acc] = res;
863 res = (uint32_t)env->macc[acc + 1];
864 res |= (uint64_t)(val & 0xffff0000) << 16;
865 env->macc[acc + 1] = res;
868 void m68k_cpu_exec_enter(CPUState *cs)
870 M68kCPU *cpu = M68K_CPU(cs);
871 CPUM68KState *env = &cpu->env;
873 env->cc_op = CC_OP_FLAGS;
874 env->cc_dest = env->sr & 0xf;
875 env->cc_x = (env->sr >> 4) & 1;
878 void m68k_cpu_exec_exit(CPUState *cs)
880 M68kCPU *cpu = M68K_CPU(cs);
881 CPUM68KState *env = &cpu->env;
883 cpu_m68k_flush_flags(env, env->cc_op);
884 env->cc_op = CC_OP_FLAGS;
885 env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);