hw: Add support for LSI SAS1068 (mptsas) device
[qemu/ar7.git] / target-m68k / helper.c
bloba8f6d9d6a626094bff9ebcb49537014136106fb9
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/gdbstub.h"
25 #include "exec/helper-proto.h"
27 #define SIGNBIT (1u << 31)
29 /* Sort alphabetically, except for "any". */
30 static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b)
32 ObjectClass *class_a = (ObjectClass *)a;
33 ObjectClass *class_b = (ObjectClass *)b;
34 const char *name_a, *name_b;
36 name_a = object_class_get_name(class_a);
37 name_b = object_class_get_name(class_b);
38 if (strcmp(name_a, "any-" TYPE_M68K_CPU) == 0) {
39 return 1;
40 } else if (strcmp(name_b, "any-" TYPE_M68K_CPU) == 0) {
41 return -1;
42 } else {
43 return strcasecmp(name_a, name_b);
47 static void m68k_cpu_list_entry(gpointer data, gpointer user_data)
49 ObjectClass *c = data;
50 CPUListState *s = user_data;
51 const char *typename;
52 char *name;
54 typename = object_class_get_name(c);
55 name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_M68K_CPU));
56 (*s->cpu_fprintf)(s->file, "%s\n",
57 name);
58 g_free(name);
61 void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
63 CPUListState s = {
64 .file = f,
65 .cpu_fprintf = cpu_fprintf,
67 GSList *list;
69 list = object_class_get_list(TYPE_M68K_CPU, false);
70 list = g_slist_sort(list, m68k_cpu_list_compare);
71 g_slist_foreach(list, m68k_cpu_list_entry, &s);
72 g_slist_free(list);
75 static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
77 if (n < 8) {
78 stfq_p(mem_buf, env->fregs[n]);
79 return 8;
81 if (n < 11) {
82 /* FP control registers (not implemented) */
83 memset(mem_buf, 0, 4);
84 return 4;
86 return 0;
89 static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
91 if (n < 8) {
92 env->fregs[n] = ldfq_p(mem_buf);
93 return 8;
95 if (n < 11) {
96 /* FP control registers (not implemented) */
97 return 4;
99 return 0;
102 M68kCPU *cpu_m68k_init(const char *cpu_model)
104 M68kCPU *cpu;
105 CPUM68KState *env;
106 ObjectClass *oc;
108 oc = cpu_class_by_name(TYPE_M68K_CPU, cpu_model);
109 if (oc == NULL) {
110 return NULL;
112 cpu = M68K_CPU(object_new(object_class_get_name(oc)));
113 env = &cpu->env;
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 M68kCPU *cpu = m68k_env_get_cpu(env);
137 int flags;
138 uint32_t src;
139 uint32_t dest;
140 uint32_t tmp;
142 #define HIGHBIT 0x80000000u
144 #define SET_NZ(x) do { \
145 if ((x) == 0) \
146 flags |= CCF_Z; \
147 else if ((int32_t)(x) < 0) \
148 flags |= CCF_N; \
149 } while (0)
151 #define SET_FLAGS_SUB(type, utype) do { \
152 SET_NZ((type)dest); \
153 tmp = dest + src; \
154 if ((utype) tmp < (utype) src) \
155 flags |= CCF_C; \
156 if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \
157 flags |= CCF_V; \
158 } while (0)
160 flags = 0;
161 src = env->cc_src;
162 dest = env->cc_dest;
163 switch (cc_op) {
164 case CC_OP_FLAGS:
165 flags = dest;
166 break;
167 case CC_OP_LOGIC:
168 SET_NZ(dest);
169 break;
170 case CC_OP_ADD:
171 SET_NZ(dest);
172 if (dest < src)
173 flags |= CCF_C;
174 tmp = dest - src;
175 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
176 flags |= CCF_V;
177 break;
178 case CC_OP_SUB:
179 SET_FLAGS_SUB(int32_t, uint32_t);
180 break;
181 case CC_OP_CMPB:
182 SET_FLAGS_SUB(int8_t, uint8_t);
183 break;
184 case CC_OP_CMPW:
185 SET_FLAGS_SUB(int16_t, uint16_t);
186 break;
187 case CC_OP_ADDX:
188 SET_NZ(dest);
189 if (dest <= src)
190 flags |= CCF_C;
191 tmp = dest - src - 1;
192 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
193 flags |= CCF_V;
194 break;
195 case CC_OP_SUBX:
196 SET_NZ(dest);
197 tmp = dest + src + 1;
198 if (tmp <= src)
199 flags |= CCF_C;
200 if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
201 flags |= CCF_V;
202 break;
203 case CC_OP_SHIFT:
204 SET_NZ(dest);
205 if (src)
206 flags |= CCF_C;
207 break;
208 default:
209 cpu_abort(CPU(cpu), "Bad CC_OP %d", cc_op);
211 env->cc_op = CC_OP_FLAGS;
212 env->cc_dest = flags;
215 void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
217 M68kCPU *cpu = m68k_env_get_cpu(env);
219 switch (reg) {
220 case 0x02: /* CACR */
221 env->cacr = val;
222 m68k_switch_sp(env);
223 break;
224 case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
225 /* TODO: Implement Access Control Registers. */
226 break;
227 case 0x801: /* VBR */
228 env->vbr = val;
229 break;
230 /* TODO: Implement control registers. */
231 default:
232 cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x = 0x%x\n",
233 reg, val);
237 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
239 uint32_t acc;
240 int8_t exthigh;
241 uint8_t extlow;
242 uint64_t regval;
243 int i;
244 if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
245 for (i = 0; i < 4; i++) {
246 regval = env->macc[i];
247 exthigh = regval >> 40;
248 if (env->macsr & MACSR_FI) {
249 acc = regval >> 8;
250 extlow = regval;
251 } else {
252 acc = regval;
253 extlow = regval >> 32;
255 if (env->macsr & MACSR_FI) {
256 regval = (((uint64_t)acc) << 8) | extlow;
257 regval |= ((int64_t)exthigh) << 40;
258 } else if (env->macsr & MACSR_SU) {
259 regval = acc | (((int64_t)extlow) << 32);
260 regval |= ((int64_t)exthigh) << 40;
261 } else {
262 regval = acc | (((uint64_t)extlow) << 32);
263 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
265 env->macc[i] = regval;
268 env->macsr = val;
271 void m68k_switch_sp(CPUM68KState *env)
273 int new_sp;
275 env->sp[env->current_sp] = env->aregs[7];
276 new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
277 ? M68K_SSP : M68K_USP;
278 env->aregs[7] = env->sp[new_sp];
279 env->current_sp = new_sp;
282 #if defined(CONFIG_USER_ONLY)
284 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
285 int mmu_idx)
287 M68kCPU *cpu = M68K_CPU(cs);
289 cs->exception_index = EXCP_ACCESS;
290 cpu->env.mmu.ar = address;
291 return 1;
294 #else
296 /* MMU */
298 /* TODO: This will need fixing once the MMU is implemented. */
299 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
301 return addr;
304 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
305 int mmu_idx)
307 int prot;
309 address &= TARGET_PAGE_MASK;
310 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
311 tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
312 return 0;
315 /* Notify CPU of a pending interrupt. Prioritization and vectoring should
316 be handled by the interrupt controller. Real hardware only requests
317 the vector when the interrupt is acknowledged by the CPU. For
318 simplicitly we calculate it when the interrupt is signalled. */
319 void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
321 CPUState *cs = CPU(cpu);
322 CPUM68KState *env = &cpu->env;
324 env->pending_level = level;
325 env->pending_vector = vector;
326 if (level) {
327 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
328 } else {
329 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
333 #endif
335 uint32_t HELPER(bitrev)(uint32_t x)
337 x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
338 x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
339 x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
340 return bswap32(x);
343 uint32_t HELPER(ff1)(uint32_t x)
345 int n;
346 for (n = 32; x; n--)
347 x >>= 1;
348 return n;
351 uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
353 /* The result has the opposite sign to the original value. */
354 if (ccr & CCF_V)
355 val = (((int32_t)val) >> 31) ^ SIGNBIT;
356 return val;
359 uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
361 uint32_t res;
362 uint32_t old_flags;
364 old_flags = env->cc_dest;
365 if (env->cc_x) {
366 env->cc_x = (op1 <= op2);
367 env->cc_op = CC_OP_SUBX;
368 res = op1 - (op2 + 1);
369 } else {
370 env->cc_x = (op1 < op2);
371 env->cc_op = CC_OP_SUB;
372 res = op1 - op2;
374 env->cc_dest = res;
375 env->cc_src = op2;
376 cpu_m68k_flush_flags(env, env->cc_op);
377 /* !Z is sticky. */
378 env->cc_dest &= (old_flags | ~CCF_Z);
379 return res;
382 uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
384 uint32_t res;
385 uint32_t old_flags;
387 old_flags = env->cc_dest;
388 if (env->cc_x) {
389 res = op1 + op2 + 1;
390 env->cc_x = (res <= op2);
391 env->cc_op = CC_OP_ADDX;
392 } else {
393 res = op1 + op2;
394 env->cc_x = (res < op2);
395 env->cc_op = CC_OP_ADD;
397 env->cc_dest = res;
398 env->cc_src = op2;
399 cpu_m68k_flush_flags(env, env->cc_op);
400 /* !Z is sticky. */
401 env->cc_dest &= (old_flags | ~CCF_Z);
402 return res;
405 uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
407 return a < b;
410 void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
412 env->sr = val & 0xffff;
413 m68k_switch_sp(env);
416 uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
418 uint32_t result;
419 uint32_t cf;
421 shift &= 63;
422 if (shift == 0) {
423 result = val;
424 cf = env->cc_src & CCF_C;
425 } else if (shift < 32) {
426 result = val << shift;
427 cf = (val >> (32 - shift)) & 1;
428 } else if (shift == 32) {
429 result = 0;
430 cf = val & 1;
431 } else /* shift > 32 */ {
432 result = 0;
433 cf = 0;
435 env->cc_src = cf;
436 env->cc_x = (cf != 0);
437 env->cc_dest = result;
438 return result;
441 uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
443 uint32_t result;
444 uint32_t cf;
446 shift &= 63;
447 if (shift == 0) {
448 result = val;
449 cf = env->cc_src & CCF_C;
450 } else if (shift < 32) {
451 result = val >> shift;
452 cf = (val >> (shift - 1)) & 1;
453 } else if (shift == 32) {
454 result = 0;
455 cf = val >> 31;
456 } else /* shift > 32 */ {
457 result = 0;
458 cf = 0;
460 env->cc_src = cf;
461 env->cc_x = (cf != 0);
462 env->cc_dest = result;
463 return result;
466 uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
468 uint32_t result;
469 uint32_t cf;
471 shift &= 63;
472 if (shift == 0) {
473 result = val;
474 cf = (env->cc_src & CCF_C) != 0;
475 } else if (shift < 32) {
476 result = (int32_t)val >> shift;
477 cf = (val >> (shift - 1)) & 1;
478 } else /* shift >= 32 */ {
479 result = (int32_t)val >> 31;
480 cf = val >> 31;
482 env->cc_src = cf;
483 env->cc_x = cf;
484 env->cc_dest = result;
485 return result;
488 /* FPU helpers. */
489 uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val)
491 return float64_to_int32(val, &env->fp_status);
494 float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val)
496 return float64_to_float32(val, &env->fp_status);
499 float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val)
501 return int32_to_float64(val, &env->fp_status);
504 float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val)
506 return float32_to_float64(val, &env->fp_status);
509 float64 HELPER(iround_f64)(CPUM68KState *env, float64 val)
511 return float64_round_to_int(val, &env->fp_status);
514 float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val)
516 return float64_trunc_to_int(val, &env->fp_status);
519 float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val)
521 return float64_sqrt(val, &env->fp_status);
524 float64 HELPER(abs_f64)(float64 val)
526 return float64_abs(val);
529 float64 HELPER(chs_f64)(float64 val)
531 return float64_chs(val);
534 float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b)
536 return float64_add(a, b, &env->fp_status);
539 float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b)
541 return float64_sub(a, b, &env->fp_status);
544 float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b)
546 return float64_mul(a, b, &env->fp_status);
549 float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b)
551 return float64_div(a, b, &env->fp_status);
554 float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b)
556 /* ??? This may incorrectly raise exceptions. */
557 /* ??? Should flush denormals to zero. */
558 float64 res;
559 res = float64_sub(a, b, &env->fp_status);
560 if (float64_is_quiet_nan(res)) {
561 /* +/-inf compares equal against itself, but sub returns nan. */
562 if (!float64_is_quiet_nan(a)
563 && !float64_is_quiet_nan(b)) {
564 res = float64_zero;
565 if (float64_lt_quiet(a, res, &env->fp_status))
566 res = float64_chs(res);
569 return res;
572 uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val)
574 return float64_compare_quiet(val, float64_zero, &env->fp_status);
577 /* MAC unit. */
578 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
579 take values, others take register numbers and manipulate the contents
580 in-place. */
581 void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
583 uint32_t mask;
584 env->macc[dest] = env->macc[src];
585 mask = MACSR_PAV0 << dest;
586 if (env->macsr & (MACSR_PAV0 << src))
587 env->macsr |= mask;
588 else
589 env->macsr &= ~mask;
592 uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
594 int64_t product;
595 int64_t res;
597 product = (uint64_t)op1 * op2;
598 res = (product << 24) >> 24;
599 if (res != product) {
600 env->macsr |= MACSR_V;
601 if (env->macsr & MACSR_OMC) {
602 /* Make sure the accumulate operation overflows. */
603 if (product < 0)
604 res = ~(1ll << 50);
605 else
606 res = 1ll << 50;
609 return res;
612 uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
614 uint64_t product;
616 product = (uint64_t)op1 * op2;
617 if (product & (0xffffffull << 40)) {
618 env->macsr |= MACSR_V;
619 if (env->macsr & MACSR_OMC) {
620 /* Make sure the accumulate operation overflows. */
621 product = 1ll << 50;
622 } else {
623 product &= ((1ull << 40) - 1);
626 return product;
629 uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
631 uint64_t product;
632 uint32_t remainder;
634 product = (uint64_t)op1 * op2;
635 if (env->macsr & MACSR_RT) {
636 remainder = product & 0xffffff;
637 product >>= 24;
638 if (remainder > 0x800000)
639 product++;
640 else if (remainder == 0x800000)
641 product += (product & 1);
642 } else {
643 product >>= 24;
645 return product;
648 void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
650 int64_t tmp;
651 int64_t result;
652 tmp = env->macc[acc];
653 result = ((tmp << 16) >> 16);
654 if (result != tmp) {
655 env->macsr |= MACSR_V;
657 if (env->macsr & MACSR_V) {
658 env->macsr |= MACSR_PAV0 << acc;
659 if (env->macsr & MACSR_OMC) {
660 /* The result is saturated to 32 bits, despite overflow occurring
661 at 48 bits. Seems weird, but that's what the hardware docs
662 say. */
663 result = (result >> 63) ^ 0x7fffffff;
666 env->macc[acc] = result;
669 void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
671 uint64_t val;
673 val = env->macc[acc];
674 if (val & (0xffffull << 48)) {
675 env->macsr |= MACSR_V;
677 if (env->macsr & MACSR_V) {
678 env->macsr |= MACSR_PAV0 << acc;
679 if (env->macsr & MACSR_OMC) {
680 if (val > (1ull << 53))
681 val = 0;
682 else
683 val = (1ull << 48) - 1;
684 } else {
685 val &= ((1ull << 48) - 1);
688 env->macc[acc] = val;
691 void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
693 int64_t sum;
694 int64_t result;
696 sum = env->macc[acc];
697 result = (sum << 16) >> 16;
698 if (result != sum) {
699 env->macsr |= MACSR_V;
701 if (env->macsr & MACSR_V) {
702 env->macsr |= MACSR_PAV0 << acc;
703 if (env->macsr & MACSR_OMC) {
704 result = (result >> 63) ^ 0x7fffffffffffll;
707 env->macc[acc] = result;
710 void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
712 uint64_t val;
713 val = env->macc[acc];
714 if (val == 0) {
715 env->macsr |= MACSR_Z;
716 } else if (val & (1ull << 47)) {
717 env->macsr |= MACSR_N;
719 if (env->macsr & (MACSR_PAV0 << acc)) {
720 env->macsr |= MACSR_V;
722 if (env->macsr & MACSR_FI) {
723 val = ((int64_t)val) >> 40;
724 if (val != 0 && val != -1)
725 env->macsr |= MACSR_EV;
726 } else if (env->macsr & MACSR_SU) {
727 val = ((int64_t)val) >> 32;
728 if (val != 0 && val != -1)
729 env->macsr |= MACSR_EV;
730 } else {
731 if ((val >> 32) != 0)
732 env->macsr |= MACSR_EV;
736 void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
738 cpu_m68k_flush_flags(env, cc_op);
741 uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
743 int rem;
744 uint32_t result;
746 if (env->macsr & MACSR_SU) {
747 /* 16-bit rounding. */
748 rem = val & 0xffffff;
749 val = (val >> 24) & 0xffffu;
750 if (rem > 0x800000)
751 val++;
752 else if (rem == 0x800000)
753 val += (val & 1);
754 } else if (env->macsr & MACSR_RT) {
755 /* 32-bit rounding. */
756 rem = val & 0xff;
757 val >>= 8;
758 if (rem > 0x80)
759 val++;
760 else if (rem == 0x80)
761 val += (val & 1);
762 } else {
763 /* No rounding. */
764 val >>= 8;
766 if (env->macsr & MACSR_OMC) {
767 /* Saturate. */
768 if (env->macsr & MACSR_SU) {
769 if (val != (uint16_t) val) {
770 result = ((val >> 63) ^ 0x7fff) & 0xffff;
771 } else {
772 result = val & 0xffff;
774 } else {
775 if (val != (uint32_t)val) {
776 result = ((uint32_t)(val >> 63) & 0x7fffffff);
777 } else {
778 result = (uint32_t)val;
781 } else {
782 /* No saturation. */
783 if (env->macsr & MACSR_SU) {
784 result = val & 0xffff;
785 } else {
786 result = (uint32_t)val;
789 return result;
792 uint32_t HELPER(get_macs)(uint64_t val)
794 if (val == (int32_t)val) {
795 return (int32_t)val;
796 } else {
797 return (val >> 61) ^ ~SIGNBIT;
801 uint32_t HELPER(get_macu)(uint64_t val)
803 if ((val >> 32) == 0) {
804 return (uint32_t)val;
805 } else {
806 return 0xffffffffu;
810 uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
812 uint32_t val;
813 val = env->macc[acc] & 0x00ff;
814 val = (env->macc[acc] >> 32) & 0xff00;
815 val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
816 val |= (env->macc[acc + 1] >> 16) & 0xff000000;
817 return val;
820 uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
822 uint32_t val;
823 val = (env->macc[acc] >> 32) & 0xffff;
824 val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
825 return val;
828 void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
830 int64_t res;
831 int32_t tmp;
832 res = env->macc[acc] & 0xffffffff00ull;
833 tmp = (int16_t)(val & 0xff00);
834 res |= ((int64_t)tmp) << 32;
835 res |= val & 0xff;
836 env->macc[acc] = res;
837 res = env->macc[acc + 1] & 0xffffffff00ull;
838 tmp = (val & 0xff000000);
839 res |= ((int64_t)tmp) << 16;
840 res |= (val >> 16) & 0xff;
841 env->macc[acc + 1] = res;
844 void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
846 int64_t res;
847 int32_t tmp;
848 res = (uint32_t)env->macc[acc];
849 tmp = (int16_t)val;
850 res |= ((int64_t)tmp) << 32;
851 env->macc[acc] = res;
852 res = (uint32_t)env->macc[acc + 1];
853 tmp = val & 0xffff0000;
854 res |= (int64_t)tmp << 16;
855 env->macc[acc + 1] = res;
858 void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
860 uint64_t res;
861 res = (uint32_t)env->macc[acc];
862 res |= ((uint64_t)(val & 0xffff)) << 32;
863 env->macc[acc] = res;
864 res = (uint32_t)env->macc[acc + 1];
865 res |= (uint64_t)(val & 0xffff0000) << 16;
866 env->macc[acc + 1] = res;
869 void m68k_cpu_exec_enter(CPUState *cs)
871 M68kCPU *cpu = M68K_CPU(cs);
872 CPUM68KState *env = &cpu->env;
874 env->cc_op = CC_OP_FLAGS;
875 env->cc_dest = env->sr & 0xf;
876 env->cc_x = (env->sr >> 4) & 1;
879 void m68k_cpu_exec_exit(CPUState *cs)
881 M68kCPU *cpu = M68K_CPU(cs);
882 CPUM68KState *env = &cpu->env;
884 cpu_m68k_flush_flags(env, env->cc_op);
885 env->cc_op = CC_OP_FLAGS;
886 env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);