Shuffle contents of tcg_target_reg_alloc_order
[qemu-kvm/fedora.git] / target-m68k / helper.c
blob7f0139237b3f5b106d140f757ac73fd8e1319894
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, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdio.h>
23 #include <string.h>
25 #include "config.h"
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "qemu-common.h"
30 #include "helpers.h"
32 #define SIGNBIT (1u << 31)
34 enum m68k_cpuid {
35 M68K_CPUID_M5206,
36 M68K_CPUID_M5208,
37 M68K_CPUID_CFV4E,
38 M68K_CPUID_ANY,
41 typedef struct m68k_def_t m68k_def_t;
43 struct m68k_def_t {
44 const char * name;
45 enum m68k_cpuid id;
48 static m68k_def_t m68k_cpu_defs[] = {
49 {"m5206", M68K_CPUID_M5206},
50 {"m5208", M68K_CPUID_M5208},
51 {"cfv4e", M68K_CPUID_CFV4E},
52 {"any", M68K_CPUID_ANY},
53 {NULL, 0},
56 static void m68k_set_feature(CPUM68KState *env, int feature)
58 env->features |= (1u << feature);
61 static int cpu_m68k_set_model(CPUM68KState *env, const char *name)
63 m68k_def_t *def;
65 for (def = m68k_cpu_defs; def->name; def++) {
66 if (strcmp(def->name, name) == 0)
67 break;
69 if (!def->name)
70 return -1;
72 switch (def->id) {
73 case M68K_CPUID_M5206:
74 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
75 break;
76 case M68K_CPUID_M5208:
77 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
78 m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
79 m68k_set_feature(env, M68K_FEATURE_BRAL);
80 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
81 m68k_set_feature(env, M68K_FEATURE_USP);
82 break;
83 case M68K_CPUID_CFV4E:
84 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
85 m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
86 m68k_set_feature(env, M68K_FEATURE_BRAL);
87 m68k_set_feature(env, M68K_FEATURE_CF_FPU);
88 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
89 m68k_set_feature(env, M68K_FEATURE_USP);
90 break;
91 case M68K_CPUID_ANY:
92 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
93 m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
94 m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
95 m68k_set_feature(env, M68K_FEATURE_BRAL);
96 m68k_set_feature(env, M68K_FEATURE_CF_FPU);
97 /* MAC and EMAC are mututally exclusive, so pick EMAC.
98 It's mostly backwards compatible. */
99 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
100 m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
101 m68k_set_feature(env, M68K_FEATURE_USP);
102 m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
103 m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
104 break;
107 register_m68k_insns(env);
108 return 0;
111 void cpu_reset(CPUM68KState *env)
113 memset(env, 0, offsetof(CPUM68KState, breakpoints));
114 #if !defined (CONFIG_USER_ONLY)
115 env->sr = 0x2700;
116 #endif
117 m68k_switch_sp(env);
118 /* ??? FP regs should be initialized to NaN. */
119 env->cc_op = CC_OP_FLAGS;
120 /* TODO: We should set PC from the interrupt vector. */
121 env->pc = 0;
122 tlb_flush(env, 1);
125 CPUM68KState *cpu_m68k_init(const char *cpu_model)
127 CPUM68KState *env;
128 static int inited;
130 env = malloc(sizeof(CPUM68KState));
131 if (!env)
132 return NULL;
133 cpu_exec_init(env);
134 if (!inited) {
135 inited = 1;
136 m68k_tcg_init();
139 env->cpu_model_str = cpu_model;
141 if (cpu_m68k_set_model(env, cpu_model) < 0) {
142 cpu_m68k_close(env);
143 return NULL;
146 cpu_reset(env);
147 return env;
150 void cpu_m68k_close(CPUM68KState *env)
152 qemu_free(env);
155 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
157 int flags;
158 uint32_t src;
159 uint32_t dest;
160 uint32_t tmp;
162 #define HIGHBIT 0x80000000u
164 #define SET_NZ(x) do { \
165 if ((x) == 0) \
166 flags |= CCF_Z; \
167 else if ((int32_t)(x) < 0) \
168 flags |= CCF_N; \
169 } while (0)
171 #define SET_FLAGS_SUB(type, utype) do { \
172 SET_NZ((type)dest); \
173 tmp = dest + src; \
174 if ((utype) tmp < (utype) src) \
175 flags |= CCF_C; \
176 if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \
177 flags |= CCF_V; \
178 } while (0)
180 flags = 0;
181 src = env->cc_src;
182 dest = env->cc_dest;
183 switch (cc_op) {
184 case CC_OP_FLAGS:
185 flags = dest;
186 break;
187 case CC_OP_LOGIC:
188 SET_NZ(dest);
189 break;
190 case CC_OP_ADD:
191 SET_NZ(dest);
192 if (dest < src)
193 flags |= CCF_C;
194 tmp = dest - src;
195 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
196 flags |= CCF_V;
197 break;
198 case CC_OP_SUB:
199 SET_FLAGS_SUB(int32_t, uint32_t);
200 break;
201 case CC_OP_CMPB:
202 SET_FLAGS_SUB(int8_t, uint8_t);
203 break;
204 case CC_OP_CMPW:
205 SET_FLAGS_SUB(int16_t, uint16_t);
206 break;
207 case CC_OP_ADDX:
208 SET_NZ(dest);
209 if (dest <= src)
210 flags |= CCF_C;
211 tmp = dest - src - 1;
212 if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
213 flags |= CCF_V;
214 break;
215 case CC_OP_SUBX:
216 SET_NZ(dest);
217 tmp = dest + src + 1;
218 if (tmp <= src)
219 flags |= CCF_C;
220 if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
221 flags |= CCF_V;
222 break;
223 case CC_OP_SHIFT:
224 SET_NZ(dest);
225 if (src)
226 flags |= CCF_C;
227 break;
228 default:
229 cpu_abort(env, "Bad CC_OP %d", cc_op);
231 env->cc_op = CC_OP_FLAGS;
232 env->cc_dest = flags;
235 void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
237 switch (reg) {
238 case 0x02: /* CACR */
239 env->cacr = val;
240 m68k_switch_sp(env);
241 break;
242 case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
243 /* TODO: Implement Access Control Registers. */
244 break;
245 case 0x801: /* VBR */
246 env->vbr = val;
247 break;
248 /* TODO: Implement control registers. */
249 default:
250 cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n",
251 reg, val);
255 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
257 uint32_t acc;
258 int8_t exthigh;
259 uint8_t extlow;
260 uint64_t regval;
261 int i;
262 if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
263 for (i = 0; i < 4; i++) {
264 regval = env->macc[i];
265 exthigh = regval >> 40;
266 if (env->macsr & MACSR_FI) {
267 acc = regval >> 8;
268 extlow = regval;
269 } else {
270 acc = regval;
271 extlow = regval >> 32;
273 if (env->macsr & MACSR_FI) {
274 regval = (((uint64_t)acc) << 8) | extlow;
275 regval |= ((int64_t)exthigh) << 40;
276 } else if (env->macsr & MACSR_SU) {
277 regval = acc | (((int64_t)extlow) << 32);
278 regval |= ((int64_t)exthigh) << 40;
279 } else {
280 regval = acc | (((uint64_t)extlow) << 32);
281 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
283 env->macc[i] = regval;
286 env->macsr = val;
289 void m68k_switch_sp(CPUM68KState *env)
291 int new_sp;
293 env->sp[env->current_sp] = env->aregs[7];
294 new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
295 ? M68K_SSP : M68K_USP;
296 env->aregs[7] = env->sp[new_sp];
297 env->current_sp = new_sp;
300 /* MMU */
302 /* TODO: This will need fixing once the MMU is implemented. */
303 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
305 return addr;
308 #if defined(CONFIG_USER_ONLY)
310 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
311 int mmu_idx, int is_softmmu)
313 env->exception_index = EXCP_ACCESS;
314 env->mmu.ar = address;
315 return 1;
318 #else
320 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
321 int mmu_idx, int is_softmmu)
323 int prot;
325 address &= TARGET_PAGE_MASK;
326 prot = PAGE_READ | PAGE_WRITE;
327 return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);
330 /* Notify CPU of a pending interrupt. Prioritization and vectoring should
331 be handled by the interrupt controller. Real hardware only requests
332 the vector when the interrupt is acknowledged by the CPU. For
333 simplicitly we calculate it when the interrupt is signalled. */
334 void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector)
336 env->pending_level = level;
337 env->pending_vector = vector;
338 if (level)
339 cpu_interrupt(env, CPU_INTERRUPT_HARD);
340 else
341 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
344 #endif
346 uint32_t HELPER(bitrev)(uint32_t x)
348 x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
349 x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
350 x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
351 return bswap32(x);
354 uint32_t HELPER(ff1)(uint32_t x)
356 int n;
357 for (n = 32; x; n--)
358 x >>= 1;
359 return n;
362 uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
364 /* The result has the opposite sign to the original value. */
365 if (ccr & CCF_V)
366 val = (((int32_t)val) >> 31) ^ SIGNBIT;
367 return val;
370 uint32_t HELPER(subx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
372 uint32_t res;
373 uint32_t old_flags;
375 old_flags = env->cc_dest;
376 if (env->cc_x) {
377 env->cc_x = (op1 <= op2);
378 env->cc_op = CC_OP_SUBX;
379 res = op1 - (op2 + 1);
380 } else {
381 env->cc_x = (op1 < op2);
382 env->cc_op = CC_OP_SUB;
383 res = op1 - op2;
385 env->cc_dest = res;
386 env->cc_src = op2;
387 cpu_m68k_flush_flags(env, env->cc_op);
388 /* !Z is sticky. */
389 env->cc_dest &= (old_flags | ~CCF_Z);
390 return res;
393 uint32_t HELPER(addx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
395 uint32_t res;
396 uint32_t old_flags;
398 old_flags = env->cc_dest;
399 if (env->cc_x) {
400 res = op1 + op2 + 1;
401 env->cc_x = (res <= op2);
402 env->cc_op = CC_OP_ADDX;
403 } else {
404 res = op1 + op2;
405 env->cc_x = (res < op2);
406 env->cc_op = CC_OP_ADD;
408 env->cc_dest = res;
409 env->cc_src = op2;
410 cpu_m68k_flush_flags(env, env->cc_op);
411 /* !Z is sticky. */
412 env->cc_dest &= (old_flags | ~CCF_Z);
413 return res;
416 uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
418 return a < b;
421 uint32_t HELPER(btest)(uint32_t x)
423 return x != 0;
426 void HELPER(set_sr)(CPUState *env, uint32_t val)
428 env->sr = val & 0xffff;
429 m68k_switch_sp(env);
432 uint32_t HELPER(shl_cc)(CPUState *env, uint32_t val, uint32_t shift)
434 uint32_t result;
435 uint32_t cf;
437 shift &= 63;
438 if (shift == 0) {
439 result = val;
440 cf = env->cc_src & CCF_C;
441 } else if (shift < 32) {
442 result = val << shift;
443 cf = (val >> (32 - shift)) & 1;
444 } else if (shift == 32) {
445 result = 0;
446 cf = val & 1;
447 } else /* shift > 32 */ {
448 result = 0;
449 cf = 0;
451 env->cc_src = cf;
452 env->cc_x = (cf != 0);
453 env->cc_dest = result;
454 return result;
457 uint32_t HELPER(shr_cc)(CPUState *env, uint32_t val, uint32_t shift)
459 uint32_t result;
460 uint32_t cf;
462 shift &= 63;
463 if (shift == 0) {
464 result = val;
465 cf = env->cc_src & CCF_C;
466 } else if (shift < 32) {
467 result = val >> shift;
468 cf = (val >> (shift - 1)) & 1;
469 } else if (shift == 32) {
470 result = 0;
471 cf = val >> 31;
472 } else /* shift > 32 */ {
473 result = 0;
474 cf = 0;
476 env->cc_src = cf;
477 env->cc_x = (cf != 0);
478 env->cc_dest = result;
479 return result;
482 uint32_t HELPER(sar_cc)(CPUState *env, uint32_t val, uint32_t shift)
484 uint32_t result;
485 uint32_t cf;
487 shift &= 63;
488 if (shift == 0) {
489 result = val;
490 cf = (env->cc_src & CCF_C) != 0;
491 } else if (shift < 32) {
492 result = (int32_t)val >> shift;
493 cf = (val >> (shift - 1)) & 1;
494 } else /* shift >= 32 */ {
495 result = (int32_t)val >> 31;
496 cf = val >> 31;
498 env->cc_src = cf;
499 env->cc_x = cf;
500 env->cc_dest = result;
501 return result;
504 /* FPU helpers. */
505 uint32_t HELPER(f64_to_i32)(CPUState *env, float64 val)
507 return float64_to_int32(val, &env->fp_status);
510 float32 HELPER(f64_to_f32)(CPUState *env, float64 val)
512 return float64_to_float32(val, &env->fp_status);
515 float64 HELPER(i32_to_f64)(CPUState *env, uint32_t val)
517 return int32_to_float64(val, &env->fp_status);
520 float64 HELPER(f32_to_f64)(CPUState *env, float32 val)
522 return float32_to_float64(val, &env->fp_status);
525 float64 HELPER(iround_f64)(CPUState *env, float64 val)
527 return float64_round_to_int(val, &env->fp_status);
530 float64 HELPER(itrunc_f64)(CPUState *env, float64 val)
532 return float64_trunc_to_int(val, &env->fp_status);
535 float64 HELPER(sqrt_f64)(CPUState *env, float64 val)
537 return float64_sqrt(val, &env->fp_status);
540 float64 HELPER(abs_f64)(float64 val)
542 return float64_abs(val);
545 float64 HELPER(chs_f64)(float64 val)
547 return float64_chs(val);
550 float64 HELPER(add_f64)(CPUState *env, float64 a, float64 b)
552 return float64_add(a, b, &env->fp_status);
555 float64 HELPER(sub_f64)(CPUState *env, float64 a, float64 b)
557 return float64_sub(a, b, &env->fp_status);
560 float64 HELPER(mul_f64)(CPUState *env, float64 a, float64 b)
562 return float64_mul(a, b, &env->fp_status);
565 float64 HELPER(div_f64)(CPUState *env, float64 a, float64 b)
567 return float64_div(a, b, &env->fp_status);
570 float64 HELPER(sub_cmp_f64)(CPUState *env, float64 a, float64 b)
572 /* ??? This may incorrectly raise exceptions. */
573 /* ??? Should flush denormals to zero. */
574 float64 res;
575 res = float64_sub(a, b, &env->fp_status);
576 if (float64_is_nan(res)) {
577 /* +/-inf compares equal against itself, but sub returns nan. */
578 if (!float64_is_nan(a)
579 && !float64_is_nan(b)) {
580 res = float64_zero;
581 if (float64_lt_quiet(a, res, &env->fp_status))
582 res = float64_chs(res);
585 return res;
588 uint32_t HELPER(compare_f64)(CPUState *env, float64 val)
590 return float64_compare_quiet(val, float64_zero, &env->fp_status);
593 /* MAC unit. */
594 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
595 take values, others take register numbers and manipulate the contents
596 in-place. */
597 void HELPER(mac_move)(CPUState *env, uint32_t dest, uint32_t src)
599 uint32_t mask;
600 env->macc[dest] = env->macc[src];
601 mask = MACSR_PAV0 << dest;
602 if (env->macsr & (MACSR_PAV0 << src))
603 env->macsr |= mask;
604 else
605 env->macsr &= ~mask;
608 uint64_t HELPER(macmuls)(CPUState *env, uint32_t op1, uint32_t op2)
610 int64_t product;
611 int64_t res;
613 product = (uint64_t)op1 * op2;
614 res = (product << 24) >> 24;
615 if (res != product) {
616 env->macsr |= MACSR_V;
617 if (env->macsr & MACSR_OMC) {
618 /* Make sure the accumulate operation overflows. */
619 if (product < 0)
620 res = ~(1ll << 50);
621 else
622 res = 1ll << 50;
625 return res;
628 uint64_t HELPER(macmulu)(CPUState *env, uint32_t op1, uint32_t op2)
630 uint64_t product;
632 product = (uint64_t)op1 * op2;
633 if (product & (0xffffffull << 40)) {
634 env->macsr |= MACSR_V;
635 if (env->macsr & MACSR_OMC) {
636 /* Make sure the accumulate operation overflows. */
637 product = 1ll << 50;
638 } else {
639 product &= ((1ull << 40) - 1);
642 return product;
645 uint64_t HELPER(macmulf)(CPUState *env, uint32_t op1, uint32_t op2)
647 uint64_t product;
648 uint32_t remainder;
650 product = (uint64_t)op1 * op2;
651 if (env->macsr & MACSR_RT) {
652 remainder = product & 0xffffff;
653 product >>= 24;
654 if (remainder > 0x800000)
655 product++;
656 else if (remainder == 0x800000)
657 product += (product & 1);
658 } else {
659 product >>= 24;
661 return product;
664 void HELPER(macsats)(CPUState *env, uint32_t acc)
666 int64_t tmp;
667 int64_t result;
668 tmp = env->macc[acc];
669 result = ((tmp << 16) >> 16);
670 if (result != tmp) {
671 env->macsr |= MACSR_V;
673 if (env->macsr & MACSR_V) {
674 env->macsr |= MACSR_PAV0 << acc;
675 if (env->macsr & MACSR_OMC) {
676 /* The result is saturated to 32 bits, despite overflow occuring
677 at 48 bits. Seems weird, but that's what the hardware docs
678 say. */
679 result = (result >> 63) ^ 0x7fffffff;
682 env->macc[acc] = result;
685 void HELPER(macsatu)(CPUState *env, uint32_t acc)
687 uint64_t val;
689 val = env->macc[acc];
690 if (val & (0xffffull << 48)) {
691 env->macsr |= MACSR_V;
693 if (env->macsr & MACSR_V) {
694 env->macsr |= MACSR_PAV0 << acc;
695 if (env->macsr & MACSR_OMC) {
696 if (val > (1ull << 53))
697 val = 0;
698 else
699 val = (1ull << 48) - 1;
700 } else {
701 val &= ((1ull << 48) - 1);
704 env->macc[acc] = val;
707 void HELPER(macsatf)(CPUState *env, uint32_t acc)
709 int64_t sum;
710 int64_t result;
712 sum = env->macc[acc];
713 result = (sum << 16) >> 16;
714 if (result != sum) {
715 env->macsr |= MACSR_V;
717 if (env->macsr & MACSR_V) {
718 env->macsr |= MACSR_PAV0 << acc;
719 if (env->macsr & MACSR_OMC) {
720 result = (result >> 63) ^ 0x7fffffffffffll;
723 env->macc[acc] = result;
726 void HELPER(mac_set_flags)(CPUState *env, uint32_t acc)
728 uint64_t val;
729 val = env->macc[acc];
730 if (val == 0)
731 env->macsr |= MACSR_Z;
732 else if (val & (1ull << 47));
733 env->macsr |= MACSR_N;
734 if (env->macsr & (MACSR_PAV0 << acc)) {
735 env->macsr |= MACSR_V;
737 if (env->macsr & MACSR_FI) {
738 val = ((int64_t)val) >> 40;
739 if (val != 0 && val != -1)
740 env->macsr |= MACSR_EV;
741 } else if (env->macsr & MACSR_SU) {
742 val = ((int64_t)val) >> 32;
743 if (val != 0 && val != -1)
744 env->macsr |= MACSR_EV;
745 } else {
746 if ((val >> 32) != 0)
747 env->macsr |= MACSR_EV;
751 void HELPER(flush_flags)(CPUState *env, uint32_t cc_op)
753 cpu_m68k_flush_flags(env, cc_op);
756 uint32_t HELPER(get_macf)(CPUState *env, uint64_t val)
758 int rem;
759 uint32_t result;
761 if (env->macsr & MACSR_SU) {
762 /* 16-bit rounding. */
763 rem = val & 0xffffff;
764 val = (val >> 24) & 0xffffu;
765 if (rem > 0x800000)
766 val++;
767 else if (rem == 0x800000)
768 val += (val & 1);
769 } else if (env->macsr & MACSR_RT) {
770 /* 32-bit rounding. */
771 rem = val & 0xff;
772 val >>= 8;
773 if (rem > 0x80)
774 val++;
775 else if (rem == 0x80)
776 val += (val & 1);
777 } else {
778 /* No rounding. */
779 val >>= 8;
781 if (env->macsr & MACSR_OMC) {
782 /* Saturate. */
783 if (env->macsr & MACSR_SU) {
784 if (val != (uint16_t) val) {
785 result = ((val >> 63) ^ 0x7fff) & 0xffff;
786 } else {
787 result = val & 0xffff;
789 } else {
790 if (val != (uint32_t)val) {
791 result = ((uint32_t)(val >> 63) & 0x7fffffff);
792 } else {
793 result = (uint32_t)val;
796 } else {
797 /* No saturation. */
798 if (env->macsr & MACSR_SU) {
799 result = val & 0xffff;
800 } else {
801 result = (uint32_t)val;
804 return result;
807 uint32_t HELPER(get_macs)(uint64_t val)
809 if (val == (int32_t)val) {
810 return (int32_t)val;
811 } else {
812 return (val >> 61) ^ ~SIGNBIT;
816 uint32_t HELPER(get_macu)(uint64_t val)
818 if ((val >> 32) == 0) {
819 return (uint32_t)val;
820 } else {
821 return 0xffffffffu;
825 uint32_t HELPER(get_mac_extf)(CPUState *env, uint32_t acc)
827 uint32_t val;
828 val = env->macc[acc] & 0x00ff;
829 val = (env->macc[acc] >> 32) & 0xff00;
830 val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
831 val |= (env->macc[acc + 1] >> 16) & 0xff000000;
832 return val;
835 uint32_t HELPER(get_mac_exti)(CPUState *env, uint32_t acc)
837 uint32_t val;
838 val = (env->macc[acc] >> 32) & 0xffff;
839 val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
840 return val;
843 void HELPER(set_mac_extf)(CPUState *env, uint32_t val, uint32_t acc)
845 int64_t res;
846 int32_t tmp;
847 res = env->macc[acc] & 0xffffffff00ull;
848 tmp = (int16_t)(val & 0xff00);
849 res |= ((int64_t)tmp) << 32;
850 res |= val & 0xff;
851 env->macc[acc] = res;
852 res = env->macc[acc + 1] & 0xffffffff00ull;
853 tmp = (val & 0xff000000);
854 res |= ((int64_t)tmp) << 16;
855 res |= (val >> 16) & 0xff;
856 env->macc[acc + 1] = res;
859 void HELPER(set_mac_exts)(CPUState *env, uint32_t val, uint32_t acc)
861 int64_t res;
862 int32_t tmp;
863 res = (uint32_t)env->macc[acc];
864 tmp = (int16_t)val;
865 res |= ((int64_t)tmp) << 32;
866 env->macc[acc] = res;
867 res = (uint32_t)env->macc[acc + 1];
868 tmp = val & 0xffff0000;
869 res |= (int64_t)tmp << 16;
870 env->macc[acc + 1] = res;
873 void HELPER(set_mac_extu)(CPUState *env, uint32_t val, uint32_t acc)
875 uint64_t res;
876 res = (uint32_t)env->macc[acc];
877 res |= ((uint64_t)(val & 0xffff)) << 32;
878 env->macc[acc] = res;
879 res = (uint32_t)env->macc[acc + 1];
880 res |= (uint64_t)(val & 0xffff0000) << 16;
881 env->macc[acc + 1] = res;