xref: /qemu/target/m68k/helper.c (revision 6e22b28e22aa6ed1b8db6f24da2633868019d4c9)
1e6e5906bSpbrook /*
2e6e5906bSpbrook  *  m68k op helpers
3e6e5906bSpbrook  *
40633879fSpbrook  *  Copyright (c) 2006-2007 CodeSourcery
5e6e5906bSpbrook  *  Written by Paul Brook
6e6e5906bSpbrook  *
7e6e5906bSpbrook  * This library is free software; you can redistribute it and/or
8e6e5906bSpbrook  * modify it under the terms of the GNU Lesser General Public
9e6e5906bSpbrook  * License as published by the Free Software Foundation; either
10e6e5906bSpbrook  * version 2 of the License, or (at your option) any later version.
11e6e5906bSpbrook  *
12e6e5906bSpbrook  * This library is distributed in the hope that it will be useful,
13e6e5906bSpbrook  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14e6e5906bSpbrook  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15e6e5906bSpbrook  * General Public License for more details.
16e6e5906bSpbrook  *
17e6e5906bSpbrook  * You should have received a copy of the GNU Lesser General Public
188167ee88SBlue Swirl  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19e6e5906bSpbrook  */
20e6e5906bSpbrook 
21d8416665SPeter Maydell #include "qemu/osdep.h"
22e6e5906bSpbrook #include "cpu.h"
2363c91552SPaolo Bonzini #include "exec/exec-all.h"
24022c62cbSPaolo Bonzini #include "exec/gdbstub.h"
25e6e5906bSpbrook 
262ef6175aSRichard Henderson #include "exec/helper-proto.h"
27e1f3808eSpbrook 
28e1f3808eSpbrook #define SIGNBIT (1u << 31)
29e1f3808eSpbrook 
3011150915SAndreas Färber /* Sort alphabetically, except for "any". */
3111150915SAndreas Färber static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b)
3211150915SAndreas Färber {
3311150915SAndreas Färber     ObjectClass *class_a = (ObjectClass *)a;
3411150915SAndreas Färber     ObjectClass *class_b = (ObjectClass *)b;
3511150915SAndreas Färber     const char *name_a, *name_b;
36aaed909aSbellard 
3711150915SAndreas Färber     name_a = object_class_get_name(class_a);
3811150915SAndreas Färber     name_b = object_class_get_name(class_b);
397a9f812bSAndreas Färber     if (strcmp(name_a, "any-" TYPE_M68K_CPU) == 0) {
4011150915SAndreas Färber         return 1;
417a9f812bSAndreas Färber     } else if (strcmp(name_b, "any-" TYPE_M68K_CPU) == 0) {
4211150915SAndreas Färber         return -1;
4311150915SAndreas Färber     } else {
4411150915SAndreas Färber         return strcasecmp(name_a, name_b);
4511150915SAndreas Färber     }
4611150915SAndreas Färber }
470402f767Spbrook 
4811150915SAndreas Färber static void m68k_cpu_list_entry(gpointer data, gpointer user_data)
4911150915SAndreas Färber {
5011150915SAndreas Färber     ObjectClass *c = data;
5192a31361SAndreas Färber     CPUListState *s = user_data;
527a9f812bSAndreas Färber     const char *typename;
537a9f812bSAndreas Färber     char *name;
5411150915SAndreas Färber 
557a9f812bSAndreas Färber     typename = object_class_get_name(c);
567a9f812bSAndreas Färber     name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_M68K_CPU));
5711150915SAndreas Färber     (*s->cpu_fprintf)(s->file, "%s\n",
587a9f812bSAndreas Färber                       name);
597a9f812bSAndreas Färber     g_free(name);
6011150915SAndreas Färber }
610402f767Spbrook 
629a78eeadSStefan Weil void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
63009a4356SLaurent Vivier {
6492a31361SAndreas Färber     CPUListState s = {
6511150915SAndreas Färber         .file = f,
6611150915SAndreas Färber         .cpu_fprintf = cpu_fprintf,
6711150915SAndreas Färber     };
6811150915SAndreas Färber     GSList *list;
69009a4356SLaurent Vivier 
7011150915SAndreas Färber     list = object_class_get_list(TYPE_M68K_CPU, false);
7111150915SAndreas Färber     list = g_slist_sort(list, m68k_cpu_list_compare);
7211150915SAndreas Färber     g_slist_foreach(list, m68k_cpu_list_entry, &s);
7311150915SAndreas Färber     g_slist_free(list);
74009a4356SLaurent Vivier }
75009a4356SLaurent Vivier 
76f83311e4SLaurent Vivier static int cf_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
7756aebc89Spbrook {
7856aebc89Spbrook     if (n < 8) {
79f83311e4SLaurent Vivier         float_status s;
80f83311e4SLaurent Vivier         stfq_p(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
8156aebc89Spbrook         return 8;
8256aebc89Spbrook     }
83ba624944SLaurent Vivier     switch (n) {
84ba624944SLaurent Vivier     case 8: /* fpcontrol */
85ba624944SLaurent Vivier         stl_be_p(mem_buf, env->fpcr);
86ba624944SLaurent Vivier         return 4;
87ba624944SLaurent Vivier     case 9: /* fpstatus */
88ba624944SLaurent Vivier         stl_be_p(mem_buf, env->fpsr);
89ba624944SLaurent Vivier         return 4;
90ba624944SLaurent Vivier     case 10: /* fpiar, not implemented */
9156aebc89Spbrook         memset(mem_buf, 0, 4);
9256aebc89Spbrook         return 4;
9356aebc89Spbrook     }
9456aebc89Spbrook     return 0;
9556aebc89Spbrook }
9656aebc89Spbrook 
97f83311e4SLaurent Vivier static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
9856aebc89Spbrook {
9956aebc89Spbrook     if (n < 8) {
100f83311e4SLaurent Vivier         float_status s;
101f83311e4SLaurent Vivier         env->fregs[n].d = float64_to_floatx80(ldfq_p(mem_buf), &s);
10256aebc89Spbrook         return 8;
10356aebc89Spbrook     }
104ba624944SLaurent Vivier     switch (n) {
105ba624944SLaurent Vivier     case 8: /* fpcontrol */
106ba624944SLaurent Vivier         cpu_m68k_set_fpcr(env, ldl_p(mem_buf));
107ba624944SLaurent Vivier         return 4;
108ba624944SLaurent Vivier     case 9: /* fpstatus */
109ba624944SLaurent Vivier         env->fpsr = ldl_p(mem_buf);
110ba624944SLaurent Vivier         return 4;
111ba624944SLaurent Vivier     case 10: /* fpiar, not implemented */
11256aebc89Spbrook         return 4;
11356aebc89Spbrook     }
11456aebc89Spbrook     return 0;
11556aebc89Spbrook }
11656aebc89Spbrook 
1175a4526b2SLaurent Vivier static int m68k_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
1185a4526b2SLaurent Vivier {
1195a4526b2SLaurent Vivier     if (n < 8) {
1205a4526b2SLaurent Vivier         stw_be_p(mem_buf, env->fregs[n].l.upper);
1215a4526b2SLaurent Vivier         memset(mem_buf + 2, 0, 2);
1225a4526b2SLaurent Vivier         stq_be_p(mem_buf + 4, env->fregs[n].l.lower);
1235a4526b2SLaurent Vivier         return 12;
1245a4526b2SLaurent Vivier     }
1255a4526b2SLaurent Vivier     switch (n) {
1265a4526b2SLaurent Vivier     case 8: /* fpcontrol */
1275a4526b2SLaurent Vivier         stl_be_p(mem_buf, env->fpcr);
1285a4526b2SLaurent Vivier         return 4;
1295a4526b2SLaurent Vivier     case 9: /* fpstatus */
1305a4526b2SLaurent Vivier         stl_be_p(mem_buf, env->fpsr);
1315a4526b2SLaurent Vivier         return 4;
1325a4526b2SLaurent Vivier     case 10: /* fpiar, not implemented */
1335a4526b2SLaurent Vivier         memset(mem_buf, 0, 4);
1345a4526b2SLaurent Vivier         return 4;
1355a4526b2SLaurent Vivier     }
1365a4526b2SLaurent Vivier     return 0;
1375a4526b2SLaurent Vivier }
1385a4526b2SLaurent Vivier 
1395a4526b2SLaurent Vivier static int m68k_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
1405a4526b2SLaurent Vivier {
1415a4526b2SLaurent Vivier     if (n < 8) {
1425a4526b2SLaurent Vivier         env->fregs[n].l.upper = lduw_be_p(mem_buf);
1435a4526b2SLaurent Vivier         env->fregs[n].l.lower = ldq_be_p(mem_buf + 4);
1445a4526b2SLaurent Vivier         return 12;
1455a4526b2SLaurent Vivier     }
1465a4526b2SLaurent Vivier     switch (n) {
1475a4526b2SLaurent Vivier     case 8: /* fpcontrol */
148ba624944SLaurent Vivier         cpu_m68k_set_fpcr(env, ldl_p(mem_buf));
1495a4526b2SLaurent Vivier         return 4;
1505a4526b2SLaurent Vivier     case 9: /* fpstatus */
1515a4526b2SLaurent Vivier         env->fpsr = ldl_p(mem_buf);
1525a4526b2SLaurent Vivier         return 4;
1535a4526b2SLaurent Vivier     case 10: /* fpiar, not implemented */
1545a4526b2SLaurent Vivier         return 4;
1555a4526b2SLaurent Vivier     }
1565a4526b2SLaurent Vivier     return 0;
1575a4526b2SLaurent Vivier }
1585a4526b2SLaurent Vivier 
1596d1bbc62SAndreas Färber void m68k_cpu_init_gdb(M68kCPU *cpu)
1606d1bbc62SAndreas Färber {
16122169d41SAndreas Färber     CPUState *cs = CPU(cpu);
1626d1bbc62SAndreas Färber     CPUM68KState *env = &cpu->env;
1636d1bbc62SAndreas Färber 
16411150915SAndreas Färber     if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
165f83311e4SLaurent Vivier         gdb_register_coprocessor(cs, cf_fpu_gdb_get_reg, cf_fpu_gdb_set_reg,
16611150915SAndreas Färber                                  11, "cf-fp.xml", 18);
1675a4526b2SLaurent Vivier     } else if (m68k_feature(env, M68K_FEATURE_FPU)) {
1685a4526b2SLaurent Vivier         gdb_register_coprocessor(cs, m68k_fpu_gdb_get_reg,
1695a4526b2SLaurent Vivier                                  m68k_fpu_gdb_set_reg, 11, "m68k-fp.xml", 18);
170aaed909aSbellard     }
17111150915SAndreas Färber     /* TODO: Add [E]MAC registers.  */
172aaed909aSbellard }
173aaed909aSbellard 
174*6e22b28eSLaurent Vivier void HELPER(cf_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val)
1750633879fSpbrook {
176a47dddd7SAndreas Färber     M68kCPU *cpu = m68k_env_get_cpu(env);
177a47dddd7SAndreas Färber 
1780633879fSpbrook     switch (reg) {
179*6e22b28eSLaurent Vivier     case M68K_CR_CACR:
18020dcee94Spbrook         env->cacr = val;
18120dcee94Spbrook         m68k_switch_sp(env);
18220dcee94Spbrook         break;
183*6e22b28eSLaurent Vivier     case M68K_CR_ACR0:
184*6e22b28eSLaurent Vivier     case M68K_CR_ACR1:
185*6e22b28eSLaurent Vivier     case M68K_CR_ACR2:
186*6e22b28eSLaurent Vivier     case M68K_CR_ACR3:
18720dcee94Spbrook         /* TODO: Implement Access Control Registers.  */
1880633879fSpbrook         break;
189*6e22b28eSLaurent Vivier     case M68K_CR_VBR:
1900633879fSpbrook         env->vbr = val;
1910633879fSpbrook         break;
1920633879fSpbrook     /* TODO: Implement control registers.  */
1930633879fSpbrook     default:
194*6e22b28eSLaurent Vivier         cpu_abort(CPU(cpu),
195*6e22b28eSLaurent Vivier                   "Unimplemented control register write 0x%x = 0x%x\n",
196*6e22b28eSLaurent Vivier                   reg, val);
197*6e22b28eSLaurent Vivier     }
198*6e22b28eSLaurent Vivier }
199*6e22b28eSLaurent Vivier 
200*6e22b28eSLaurent Vivier void HELPER(m68k_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val)
201*6e22b28eSLaurent Vivier {
202*6e22b28eSLaurent Vivier     M68kCPU *cpu = m68k_env_get_cpu(env);
203*6e22b28eSLaurent Vivier 
204*6e22b28eSLaurent Vivier     switch (reg) {
205*6e22b28eSLaurent Vivier     /* MC680[1234]0 */
206*6e22b28eSLaurent Vivier     case M68K_CR_VBR:
207*6e22b28eSLaurent Vivier         env->vbr = val;
208*6e22b28eSLaurent Vivier         return;
209*6e22b28eSLaurent Vivier     /* MC680[234]0 */
210*6e22b28eSLaurent Vivier     case M68K_CR_CACR:
211*6e22b28eSLaurent Vivier         env->cacr = val;
212*6e22b28eSLaurent Vivier         m68k_switch_sp(env);
213*6e22b28eSLaurent Vivier         return;
214*6e22b28eSLaurent Vivier     /* MC680[34]0 */
215*6e22b28eSLaurent Vivier     case M68K_CR_USP:
216*6e22b28eSLaurent Vivier         env->sp[M68K_USP] = val;
217*6e22b28eSLaurent Vivier         return;
218*6e22b28eSLaurent Vivier     case M68K_CR_MSP:
219*6e22b28eSLaurent Vivier         env->sp[M68K_SSP] = val;
220*6e22b28eSLaurent Vivier         return;
221*6e22b28eSLaurent Vivier     case M68K_CR_ISP:
222*6e22b28eSLaurent Vivier         env->sp[M68K_ISP] = val;
223*6e22b28eSLaurent Vivier         return;
224*6e22b28eSLaurent Vivier     }
225a47dddd7SAndreas Färber     cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x = 0x%x\n",
2260633879fSpbrook               reg, val);
2270633879fSpbrook }
228*6e22b28eSLaurent Vivier 
229*6e22b28eSLaurent Vivier uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, uint32_t reg)
230*6e22b28eSLaurent Vivier {
231*6e22b28eSLaurent Vivier     M68kCPU *cpu = m68k_env_get_cpu(env);
232*6e22b28eSLaurent Vivier 
233*6e22b28eSLaurent Vivier     switch (reg) {
234*6e22b28eSLaurent Vivier     /* MC680[1234]0 */
235*6e22b28eSLaurent Vivier     case M68K_CR_VBR:
236*6e22b28eSLaurent Vivier         return env->vbr;
237*6e22b28eSLaurent Vivier     /* MC680[234]0 */
238*6e22b28eSLaurent Vivier     case M68K_CR_CACR:
239*6e22b28eSLaurent Vivier         return env->cacr;
240*6e22b28eSLaurent Vivier     /* MC680[34]0 */
241*6e22b28eSLaurent Vivier     case M68K_CR_USP:
242*6e22b28eSLaurent Vivier         return env->sp[M68K_USP];
243*6e22b28eSLaurent Vivier     case M68K_CR_MSP:
244*6e22b28eSLaurent Vivier         return env->sp[M68K_SSP];
245*6e22b28eSLaurent Vivier     case M68K_CR_ISP:
246*6e22b28eSLaurent Vivier         return env->sp[M68K_ISP];
247*6e22b28eSLaurent Vivier     }
248*6e22b28eSLaurent Vivier     cpu_abort(CPU(cpu), "Unimplemented control register read 0x%x\n",
249*6e22b28eSLaurent Vivier               reg);
2500633879fSpbrook }
2510633879fSpbrook 
252e1f3808eSpbrook void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
253acf930aaSpbrook {
254acf930aaSpbrook     uint32_t acc;
255acf930aaSpbrook     int8_t exthigh;
256acf930aaSpbrook     uint8_t extlow;
257acf930aaSpbrook     uint64_t regval;
258acf930aaSpbrook     int i;
259acf930aaSpbrook     if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
260acf930aaSpbrook         for (i = 0; i < 4; i++) {
261acf930aaSpbrook             regval = env->macc[i];
262acf930aaSpbrook             exthigh = regval >> 40;
263acf930aaSpbrook             if (env->macsr & MACSR_FI) {
264acf930aaSpbrook                 acc = regval >> 8;
265acf930aaSpbrook                 extlow = regval;
266acf930aaSpbrook             } else {
267acf930aaSpbrook                 acc = regval;
268acf930aaSpbrook                 extlow = regval >> 32;
269acf930aaSpbrook             }
270acf930aaSpbrook             if (env->macsr & MACSR_FI) {
271acf930aaSpbrook                 regval = (((uint64_t)acc) << 8) | extlow;
272acf930aaSpbrook                 regval |= ((int64_t)exthigh) << 40;
273acf930aaSpbrook             } else if (env->macsr & MACSR_SU) {
274acf930aaSpbrook                 regval = acc | (((int64_t)extlow) << 32);
275acf930aaSpbrook                 regval |= ((int64_t)exthigh) << 40;
276acf930aaSpbrook             } else {
277acf930aaSpbrook                 regval = acc | (((uint64_t)extlow) << 32);
278acf930aaSpbrook                 regval |= ((uint64_t)(uint8_t)exthigh) << 40;
279acf930aaSpbrook             }
280acf930aaSpbrook             env->macc[i] = regval;
281acf930aaSpbrook         }
282acf930aaSpbrook     }
283acf930aaSpbrook     env->macsr = val;
284acf930aaSpbrook }
285acf930aaSpbrook 
28620dcee94Spbrook void m68k_switch_sp(CPUM68KState *env)
28720dcee94Spbrook {
28820dcee94Spbrook     int new_sp;
28920dcee94Spbrook 
29020dcee94Spbrook     env->sp[env->current_sp] = env->aregs[7];
291*6e22b28eSLaurent Vivier     if (m68k_feature(env, M68K_FEATURE_M68000)) {
292*6e22b28eSLaurent Vivier         if (env->sr & SR_S) {
293*6e22b28eSLaurent Vivier             if (env->sr & SR_M) {
294*6e22b28eSLaurent Vivier                 new_sp = M68K_SSP;
295*6e22b28eSLaurent Vivier             } else {
296*6e22b28eSLaurent Vivier                 new_sp = M68K_ISP;
297*6e22b28eSLaurent Vivier             }
298*6e22b28eSLaurent Vivier         } else {
299*6e22b28eSLaurent Vivier             new_sp = M68K_USP;
300*6e22b28eSLaurent Vivier         }
301*6e22b28eSLaurent Vivier     } else {
30220dcee94Spbrook         new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
30320dcee94Spbrook                  ? M68K_SSP : M68K_USP;
304*6e22b28eSLaurent Vivier     }
30520dcee94Spbrook     env->aregs[7] = env->sp[new_sp];
30620dcee94Spbrook     env->current_sp = new_sp;
30720dcee94Spbrook }
30820dcee94Spbrook 
3090633879fSpbrook #if defined(CONFIG_USER_ONLY)
3100633879fSpbrook 
3117510454eSAndreas Färber int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
31297b348e7SBlue Swirl                               int mmu_idx)
3130633879fSpbrook {
3147510454eSAndreas Färber     M68kCPU *cpu = M68K_CPU(cs);
3157510454eSAndreas Färber 
31627103424SAndreas Färber     cs->exception_index = EXCP_ACCESS;
3177510454eSAndreas Färber     cpu->env.mmu.ar = address;
3180633879fSpbrook     return 1;
3190633879fSpbrook }
3200633879fSpbrook 
3210633879fSpbrook #else
3220633879fSpbrook 
3234fcc562bSPaul Brook /* MMU */
3244fcc562bSPaul Brook 
3254fcc562bSPaul Brook /* TODO: This will need fixing once the MMU is implemented.  */
32600b941e5SAndreas Färber hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
3274fcc562bSPaul Brook {
3284fcc562bSPaul Brook     return addr;
3294fcc562bSPaul Brook }
3304fcc562bSPaul Brook 
3317510454eSAndreas Färber int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
33297b348e7SBlue Swirl                               int mmu_idx)
3330633879fSpbrook {
3340633879fSpbrook     int prot;
3350633879fSpbrook 
3360633879fSpbrook     address &= TARGET_PAGE_MASK;
337d4c430a8SPaul Brook     prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
3380c591eb0SAndreas Färber     tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
339d4c430a8SPaul Brook     return 0;
3400633879fSpbrook }
3410633879fSpbrook 
3420633879fSpbrook /* Notify CPU of a pending interrupt.  Prioritization and vectoring should
3430633879fSpbrook    be handled by the interrupt controller.  Real hardware only requests
3440633879fSpbrook    the vector when the interrupt is acknowledged by the CPU.  For
3450633879fSpbrook    simplicitly we calculate it when the interrupt is signalled.  */
346cb3fb38eSAndreas Färber void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
3470633879fSpbrook {
348d8ed887bSAndreas Färber     CPUState *cs = CPU(cpu);
349cb3fb38eSAndreas Färber     CPUM68KState *env = &cpu->env;
350cb3fb38eSAndreas Färber 
3510633879fSpbrook     env->pending_level = level;
3520633879fSpbrook     env->pending_vector = vector;
353d8ed887bSAndreas Färber     if (level) {
354c3affe56SAndreas Färber         cpu_interrupt(cs, CPU_INTERRUPT_HARD);
355d8ed887bSAndreas Färber     } else {
356d8ed887bSAndreas Färber         cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
357d8ed887bSAndreas Färber     }
3580633879fSpbrook }
3590633879fSpbrook 
3600633879fSpbrook #endif
361e1f3808eSpbrook 
362e1f3808eSpbrook uint32_t HELPER(bitrev)(uint32_t x)
363e1f3808eSpbrook {
364e1f3808eSpbrook     x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
365e1f3808eSpbrook     x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
366e1f3808eSpbrook     x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
367e1f3808eSpbrook     return bswap32(x);
368e1f3808eSpbrook }
369e1f3808eSpbrook 
370e1f3808eSpbrook uint32_t HELPER(ff1)(uint32_t x)
371e1f3808eSpbrook {
372e1f3808eSpbrook     int n;
373e1f3808eSpbrook     for (n = 32; x; n--)
374e1f3808eSpbrook         x >>= 1;
375e1f3808eSpbrook     return n;
376e1f3808eSpbrook }
377e1f3808eSpbrook 
378620c6cf6SRichard Henderson uint32_t HELPER(sats)(uint32_t val, uint32_t v)
379e1f3808eSpbrook {
380e1f3808eSpbrook     /* The result has the opposite sign to the original value.  */
381620c6cf6SRichard Henderson     if ((int32_t)v < 0) {
382e1f3808eSpbrook         val = (((int32_t)val) >> 31) ^ SIGNBIT;
383620c6cf6SRichard Henderson     }
384e1f3808eSpbrook     return val;
385e1f3808eSpbrook }
386e1f3808eSpbrook 
387d2f8fb8eSLaurent Vivier void cpu_m68k_set_sr(CPUM68KState *env, uint32_t sr)
388e1f3808eSpbrook {
389d2f8fb8eSLaurent Vivier     env->sr = sr & 0xffe0;
390d2f8fb8eSLaurent Vivier     cpu_m68k_set_ccr(env, sr);
391e1f3808eSpbrook     m68k_switch_sp(env);
392e1f3808eSpbrook }
393e1f3808eSpbrook 
394d2f8fb8eSLaurent Vivier void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
395d2f8fb8eSLaurent Vivier {
396d2f8fb8eSLaurent Vivier     cpu_m68k_set_sr(env, val);
397d2f8fb8eSLaurent Vivier }
398e1f3808eSpbrook 
399e1f3808eSpbrook /* MAC unit.  */
400e1f3808eSpbrook /* FIXME: The MAC unit implementation is a bit of a mess.  Some helpers
401e1f3808eSpbrook    take values,  others take register numbers and manipulate the contents
402e1f3808eSpbrook    in-place.  */
4032b3e3cfeSAndreas Färber void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
404e1f3808eSpbrook {
405e1f3808eSpbrook     uint32_t mask;
406e1f3808eSpbrook     env->macc[dest] = env->macc[src];
407e1f3808eSpbrook     mask = MACSR_PAV0 << dest;
408e1f3808eSpbrook     if (env->macsr & (MACSR_PAV0 << src))
409e1f3808eSpbrook         env->macsr |= mask;
410e1f3808eSpbrook     else
411e1f3808eSpbrook         env->macsr &= ~mask;
412e1f3808eSpbrook }
413e1f3808eSpbrook 
4142b3e3cfeSAndreas Färber uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
415e1f3808eSpbrook {
416e1f3808eSpbrook     int64_t product;
417e1f3808eSpbrook     int64_t res;
418e1f3808eSpbrook 
419e1f3808eSpbrook     product = (uint64_t)op1 * op2;
420e1f3808eSpbrook     res = (product << 24) >> 24;
421e1f3808eSpbrook     if (res != product) {
422e1f3808eSpbrook         env->macsr |= MACSR_V;
423e1f3808eSpbrook         if (env->macsr & MACSR_OMC) {
424e1f3808eSpbrook             /* Make sure the accumulate operation overflows.  */
425e1f3808eSpbrook             if (product < 0)
426e1f3808eSpbrook                 res = ~(1ll << 50);
427e1f3808eSpbrook             else
428e1f3808eSpbrook                 res = 1ll << 50;
429e1f3808eSpbrook         }
430e1f3808eSpbrook     }
431e1f3808eSpbrook     return res;
432e1f3808eSpbrook }
433e1f3808eSpbrook 
4342b3e3cfeSAndreas Färber uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
435e1f3808eSpbrook {
436e1f3808eSpbrook     uint64_t product;
437e1f3808eSpbrook 
438e1f3808eSpbrook     product = (uint64_t)op1 * op2;
439e1f3808eSpbrook     if (product & (0xffffffull << 40)) {
440e1f3808eSpbrook         env->macsr |= MACSR_V;
441e1f3808eSpbrook         if (env->macsr & MACSR_OMC) {
442e1f3808eSpbrook             /* Make sure the accumulate operation overflows.  */
443e1f3808eSpbrook             product = 1ll << 50;
444e1f3808eSpbrook         } else {
445e1f3808eSpbrook             product &= ((1ull << 40) - 1);
446e1f3808eSpbrook         }
447e1f3808eSpbrook     }
448e1f3808eSpbrook     return product;
449e1f3808eSpbrook }
450e1f3808eSpbrook 
4512b3e3cfeSAndreas Färber uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
452e1f3808eSpbrook {
453e1f3808eSpbrook     uint64_t product;
454e1f3808eSpbrook     uint32_t remainder;
455e1f3808eSpbrook 
456e1f3808eSpbrook     product = (uint64_t)op1 * op2;
457e1f3808eSpbrook     if (env->macsr & MACSR_RT) {
458e1f3808eSpbrook         remainder = product & 0xffffff;
459e1f3808eSpbrook         product >>= 24;
460e1f3808eSpbrook         if (remainder > 0x800000)
461e1f3808eSpbrook             product++;
462e1f3808eSpbrook         else if (remainder == 0x800000)
463e1f3808eSpbrook             product += (product & 1);
464e1f3808eSpbrook     } else {
465e1f3808eSpbrook         product >>= 24;
466e1f3808eSpbrook     }
467e1f3808eSpbrook     return product;
468e1f3808eSpbrook }
469e1f3808eSpbrook 
4702b3e3cfeSAndreas Färber void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
471e1f3808eSpbrook {
472e1f3808eSpbrook     int64_t tmp;
473e1f3808eSpbrook     int64_t result;
474e1f3808eSpbrook     tmp = env->macc[acc];
475e1f3808eSpbrook     result = ((tmp << 16) >> 16);
476e1f3808eSpbrook     if (result != tmp) {
477e1f3808eSpbrook         env->macsr |= MACSR_V;
478e1f3808eSpbrook     }
479e1f3808eSpbrook     if (env->macsr & MACSR_V) {
480e1f3808eSpbrook         env->macsr |= MACSR_PAV0 << acc;
481e1f3808eSpbrook         if (env->macsr & MACSR_OMC) {
482a1c7273bSStefan Weil             /* The result is saturated to 32 bits, despite overflow occurring
483e1f3808eSpbrook                at 48 bits.  Seems weird, but that's what the hardware docs
484e1f3808eSpbrook                say.  */
485e1f3808eSpbrook             result = (result >> 63) ^ 0x7fffffff;
486e1f3808eSpbrook         }
487e1f3808eSpbrook     }
488e1f3808eSpbrook     env->macc[acc] = result;
489e1f3808eSpbrook }
490e1f3808eSpbrook 
4912b3e3cfeSAndreas Färber void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
492e1f3808eSpbrook {
493e1f3808eSpbrook     uint64_t val;
494e1f3808eSpbrook 
495e1f3808eSpbrook     val = env->macc[acc];
496e1f3808eSpbrook     if (val & (0xffffull << 48)) {
497e1f3808eSpbrook         env->macsr |= MACSR_V;
498e1f3808eSpbrook     }
499e1f3808eSpbrook     if (env->macsr & MACSR_V) {
500e1f3808eSpbrook         env->macsr |= MACSR_PAV0 << acc;
501e1f3808eSpbrook         if (env->macsr & MACSR_OMC) {
502e1f3808eSpbrook             if (val > (1ull << 53))
503e1f3808eSpbrook                 val = 0;
504e1f3808eSpbrook             else
505e1f3808eSpbrook                 val = (1ull << 48) - 1;
506e1f3808eSpbrook         } else {
507e1f3808eSpbrook             val &= ((1ull << 48) - 1);
508e1f3808eSpbrook         }
509e1f3808eSpbrook     }
510e1f3808eSpbrook     env->macc[acc] = val;
511e1f3808eSpbrook }
512e1f3808eSpbrook 
5132b3e3cfeSAndreas Färber void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
514e1f3808eSpbrook {
515e1f3808eSpbrook     int64_t sum;
516e1f3808eSpbrook     int64_t result;
517e1f3808eSpbrook 
518e1f3808eSpbrook     sum = env->macc[acc];
519e1f3808eSpbrook     result = (sum << 16) >> 16;
520e1f3808eSpbrook     if (result != sum) {
521e1f3808eSpbrook         env->macsr |= MACSR_V;
522e1f3808eSpbrook     }
523e1f3808eSpbrook     if (env->macsr & MACSR_V) {
524e1f3808eSpbrook         env->macsr |= MACSR_PAV0 << acc;
525e1f3808eSpbrook         if (env->macsr & MACSR_OMC) {
526e1f3808eSpbrook             result = (result >> 63) ^ 0x7fffffffffffll;
527e1f3808eSpbrook         }
528e1f3808eSpbrook     }
529e1f3808eSpbrook     env->macc[acc] = result;
530e1f3808eSpbrook }
531e1f3808eSpbrook 
5322b3e3cfeSAndreas Färber void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
533e1f3808eSpbrook {
534e1f3808eSpbrook     uint64_t val;
535e1f3808eSpbrook     val = env->macc[acc];
536c4162574SBlue Swirl     if (val == 0) {
537e1f3808eSpbrook         env->macsr |= MACSR_Z;
538c4162574SBlue Swirl     } else if (val & (1ull << 47)) {
539e1f3808eSpbrook         env->macsr |= MACSR_N;
540c4162574SBlue Swirl     }
541e1f3808eSpbrook     if (env->macsr & (MACSR_PAV0 << acc)) {
542e1f3808eSpbrook         env->macsr |= MACSR_V;
543e1f3808eSpbrook     }
544e1f3808eSpbrook     if (env->macsr & MACSR_FI) {
545e1f3808eSpbrook         val = ((int64_t)val) >> 40;
546e1f3808eSpbrook         if (val != 0 && val != -1)
547e1f3808eSpbrook             env->macsr |= MACSR_EV;
548e1f3808eSpbrook     } else if (env->macsr & MACSR_SU) {
549e1f3808eSpbrook         val = ((int64_t)val) >> 32;
550e1f3808eSpbrook         if (val != 0 && val != -1)
551e1f3808eSpbrook             env->macsr |= MACSR_EV;
552e1f3808eSpbrook     } else {
553e1f3808eSpbrook         if ((val >> 32) != 0)
554e1f3808eSpbrook             env->macsr |= MACSR_EV;
555e1f3808eSpbrook     }
556e1f3808eSpbrook }
557e1f3808eSpbrook 
558db3d7945SLaurent Vivier #define EXTSIGN(val, index) (     \
559db3d7945SLaurent Vivier     (index == 0) ? (int8_t)(val) : ((index == 1) ? (int16_t)(val) : (val)) \
560db3d7945SLaurent Vivier )
561620c6cf6SRichard Henderson 
562620c6cf6SRichard Henderson #define COMPUTE_CCR(op, x, n, z, v, c) {                                   \
563620c6cf6SRichard Henderson     switch (op) {                                                          \
564620c6cf6SRichard Henderson     case CC_OP_FLAGS:                                                      \
565620c6cf6SRichard Henderson         /* Everything in place.  */                                        \
566620c6cf6SRichard Henderson         break;                                                             \
567db3d7945SLaurent Vivier     case CC_OP_ADDB:                                                       \
568db3d7945SLaurent Vivier     case CC_OP_ADDW:                                                       \
569db3d7945SLaurent Vivier     case CC_OP_ADDL:                                                       \
570620c6cf6SRichard Henderson         res = n;                                                           \
571620c6cf6SRichard Henderson         src2 = v;                                                          \
572db3d7945SLaurent Vivier         src1 = EXTSIGN(res - src2, op - CC_OP_ADDB);                       \
573620c6cf6SRichard Henderson         c = x;                                                             \
574620c6cf6SRichard Henderson         z = n;                                                             \
575620c6cf6SRichard Henderson         v = (res ^ src1) & ~(src1 ^ src2);                                 \
576620c6cf6SRichard Henderson         break;                                                             \
577db3d7945SLaurent Vivier     case CC_OP_SUBB:                                                       \
578db3d7945SLaurent Vivier     case CC_OP_SUBW:                                                       \
579db3d7945SLaurent Vivier     case CC_OP_SUBL:                                                       \
580620c6cf6SRichard Henderson         res = n;                                                           \
581620c6cf6SRichard Henderson         src2 = v;                                                          \
582db3d7945SLaurent Vivier         src1 = EXTSIGN(res + src2, op - CC_OP_SUBB);                       \
583620c6cf6SRichard Henderson         c = x;                                                             \
584620c6cf6SRichard Henderson         z = n;                                                             \
585620c6cf6SRichard Henderson         v = (res ^ src1) & (src1 ^ src2);                                  \
586620c6cf6SRichard Henderson         break;                                                             \
587db3d7945SLaurent Vivier     case CC_OP_CMPB:                                                       \
588db3d7945SLaurent Vivier     case CC_OP_CMPW:                                                       \
589db3d7945SLaurent Vivier     case CC_OP_CMPL:                                                       \
590620c6cf6SRichard Henderson         src1 = n;                                                          \
591620c6cf6SRichard Henderson         src2 = v;                                                          \
592db3d7945SLaurent Vivier         res = EXTSIGN(src1 - src2, op - CC_OP_CMPB);                       \
593620c6cf6SRichard Henderson         n = res;                                                           \
594620c6cf6SRichard Henderson         z = res;                                                           \
595620c6cf6SRichard Henderson         c = src1 < src2;                                                   \
596620c6cf6SRichard Henderson         v = (res ^ src1) & (src1 ^ src2);                                  \
597620c6cf6SRichard Henderson         break;                                                             \
598620c6cf6SRichard Henderson     case CC_OP_LOGIC:                                                      \
599620c6cf6SRichard Henderson         c = v = 0;                                                         \
600620c6cf6SRichard Henderson         z = n;                                                             \
601620c6cf6SRichard Henderson         break;                                                             \
602620c6cf6SRichard Henderson     default:                                                               \
603620c6cf6SRichard Henderson         cpu_abort(CPU(m68k_env_get_cpu(env)), "Bad CC_OP %d", op);         \
604620c6cf6SRichard Henderson     }                                                                      \
605620c6cf6SRichard Henderson } while (0)
606620c6cf6SRichard Henderson 
607620c6cf6SRichard Henderson uint32_t cpu_m68k_get_ccr(CPUM68KState *env)
608e1f3808eSpbrook {
609620c6cf6SRichard Henderson     uint32_t x, c, n, z, v;
610620c6cf6SRichard Henderson     uint32_t res, src1, src2;
611620c6cf6SRichard Henderson 
612620c6cf6SRichard Henderson     x = env->cc_x;
613620c6cf6SRichard Henderson     n = env->cc_n;
614620c6cf6SRichard Henderson     z = env->cc_z;
615620c6cf6SRichard Henderson     v = env->cc_v;
616db3d7945SLaurent Vivier     c = env->cc_c;
617620c6cf6SRichard Henderson 
618620c6cf6SRichard Henderson     COMPUTE_CCR(env->cc_op, x, n, z, v, c);
619620c6cf6SRichard Henderson 
620620c6cf6SRichard Henderson     n = n >> 31;
621620c6cf6SRichard Henderson     z = (z == 0);
622db3d7945SLaurent Vivier     v = v >> 31;
623620c6cf6SRichard Henderson 
624620c6cf6SRichard Henderson     return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C;
625620c6cf6SRichard Henderson }
626620c6cf6SRichard Henderson 
627620c6cf6SRichard Henderson uint32_t HELPER(get_ccr)(CPUM68KState *env)
628620c6cf6SRichard Henderson {
629620c6cf6SRichard Henderson     return cpu_m68k_get_ccr(env);
630620c6cf6SRichard Henderson }
631620c6cf6SRichard Henderson 
632620c6cf6SRichard Henderson void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t ccr)
633620c6cf6SRichard Henderson {
634620c6cf6SRichard Henderson     env->cc_x = (ccr & CCF_X ? 1 : 0);
635620c6cf6SRichard Henderson     env->cc_n = (ccr & CCF_N ? -1 : 0);
636620c6cf6SRichard Henderson     env->cc_z = (ccr & CCF_Z ? 0 : 1);
637620c6cf6SRichard Henderson     env->cc_v = (ccr & CCF_V ? -1 : 0);
638620c6cf6SRichard Henderson     env->cc_c = (ccr & CCF_C ? 1 : 0);
639620c6cf6SRichard Henderson     env->cc_op = CC_OP_FLAGS;
640620c6cf6SRichard Henderson }
641620c6cf6SRichard Henderson 
642620c6cf6SRichard Henderson void HELPER(set_ccr)(CPUM68KState *env, uint32_t ccr)
643620c6cf6SRichard Henderson {
644620c6cf6SRichard Henderson     cpu_m68k_set_ccr(env, ccr);
645620c6cf6SRichard Henderson }
646620c6cf6SRichard Henderson 
647620c6cf6SRichard Henderson void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
648620c6cf6SRichard Henderson {
649620c6cf6SRichard Henderson     uint32_t res, src1, src2;
650620c6cf6SRichard Henderson 
651620c6cf6SRichard Henderson     COMPUTE_CCR(cc_op, env->cc_x, env->cc_n, env->cc_z, env->cc_v, env->cc_c);
652620c6cf6SRichard Henderson     env->cc_op = CC_OP_FLAGS;
653e1f3808eSpbrook }
654e1f3808eSpbrook 
6552b3e3cfeSAndreas Färber uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
656e1f3808eSpbrook {
657e1f3808eSpbrook     int rem;
658e1f3808eSpbrook     uint32_t result;
659e1f3808eSpbrook 
660e1f3808eSpbrook     if (env->macsr & MACSR_SU) {
661e1f3808eSpbrook         /* 16-bit rounding.  */
662e1f3808eSpbrook         rem = val & 0xffffff;
663e1f3808eSpbrook         val = (val >> 24) & 0xffffu;
664e1f3808eSpbrook         if (rem > 0x800000)
665e1f3808eSpbrook             val++;
666e1f3808eSpbrook         else if (rem == 0x800000)
667e1f3808eSpbrook             val += (val & 1);
668e1f3808eSpbrook     } else if (env->macsr & MACSR_RT) {
669e1f3808eSpbrook         /* 32-bit rounding.  */
670e1f3808eSpbrook         rem = val & 0xff;
671e1f3808eSpbrook         val >>= 8;
672e1f3808eSpbrook         if (rem > 0x80)
673e1f3808eSpbrook             val++;
674e1f3808eSpbrook         else if (rem == 0x80)
675e1f3808eSpbrook             val += (val & 1);
676e1f3808eSpbrook     } else {
677e1f3808eSpbrook         /* No rounding.  */
678e1f3808eSpbrook         val >>= 8;
679e1f3808eSpbrook     }
680e1f3808eSpbrook     if (env->macsr & MACSR_OMC) {
681e1f3808eSpbrook         /* Saturate.  */
682e1f3808eSpbrook         if (env->macsr & MACSR_SU) {
683e1f3808eSpbrook             if (val != (uint16_t) val) {
684e1f3808eSpbrook                 result = ((val >> 63) ^ 0x7fff) & 0xffff;
685e1f3808eSpbrook             } else {
686e1f3808eSpbrook                 result = val & 0xffff;
687e1f3808eSpbrook             }
688e1f3808eSpbrook         } else {
689e1f3808eSpbrook             if (val != (uint32_t)val) {
690e1f3808eSpbrook                 result = ((uint32_t)(val >> 63) & 0x7fffffff);
691e1f3808eSpbrook             } else {
692e1f3808eSpbrook                 result = (uint32_t)val;
693e1f3808eSpbrook             }
694e1f3808eSpbrook         }
695e1f3808eSpbrook     } else {
696e1f3808eSpbrook         /* No saturation.  */
697e1f3808eSpbrook         if (env->macsr & MACSR_SU) {
698e1f3808eSpbrook             result = val & 0xffff;
699e1f3808eSpbrook         } else {
700e1f3808eSpbrook             result = (uint32_t)val;
701e1f3808eSpbrook         }
702e1f3808eSpbrook     }
703e1f3808eSpbrook     return result;
704e1f3808eSpbrook }
705e1f3808eSpbrook 
706e1f3808eSpbrook uint32_t HELPER(get_macs)(uint64_t val)
707e1f3808eSpbrook {
708e1f3808eSpbrook     if (val == (int32_t)val) {
709e1f3808eSpbrook         return (int32_t)val;
710e1f3808eSpbrook     } else {
711e1f3808eSpbrook         return (val >> 61) ^ ~SIGNBIT;
712e1f3808eSpbrook     }
713e1f3808eSpbrook }
714e1f3808eSpbrook 
715e1f3808eSpbrook uint32_t HELPER(get_macu)(uint64_t val)
716e1f3808eSpbrook {
717e1f3808eSpbrook     if ((val >> 32) == 0) {
718e1f3808eSpbrook         return (uint32_t)val;
719e1f3808eSpbrook     } else {
720e1f3808eSpbrook         return 0xffffffffu;
721e1f3808eSpbrook     }
722e1f3808eSpbrook }
723e1f3808eSpbrook 
7242b3e3cfeSAndreas Färber uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
725e1f3808eSpbrook {
726e1f3808eSpbrook     uint32_t val;
727e1f3808eSpbrook     val = env->macc[acc] & 0x00ff;
7285ce747cfSPaolo Bonzini     val |= (env->macc[acc] >> 32) & 0xff00;
729e1f3808eSpbrook     val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
730e1f3808eSpbrook     val |= (env->macc[acc + 1] >> 16) & 0xff000000;
731e1f3808eSpbrook     return val;
732e1f3808eSpbrook }
733e1f3808eSpbrook 
7342b3e3cfeSAndreas Färber uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
735e1f3808eSpbrook {
736e1f3808eSpbrook     uint32_t val;
737e1f3808eSpbrook     val = (env->macc[acc] >> 32) & 0xffff;
738e1f3808eSpbrook     val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
739e1f3808eSpbrook     return val;
740e1f3808eSpbrook }
741e1f3808eSpbrook 
7422b3e3cfeSAndreas Färber void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
743e1f3808eSpbrook {
744e1f3808eSpbrook     int64_t res;
745e1f3808eSpbrook     int32_t tmp;
746e1f3808eSpbrook     res = env->macc[acc] & 0xffffffff00ull;
747e1f3808eSpbrook     tmp = (int16_t)(val & 0xff00);
748e1f3808eSpbrook     res |= ((int64_t)tmp) << 32;
749e1f3808eSpbrook     res |= val & 0xff;
750e1f3808eSpbrook     env->macc[acc] = res;
751e1f3808eSpbrook     res = env->macc[acc + 1] & 0xffffffff00ull;
752e1f3808eSpbrook     tmp = (val & 0xff000000);
753e1f3808eSpbrook     res |= ((int64_t)tmp) << 16;
754e1f3808eSpbrook     res |= (val >> 16) & 0xff;
755e1f3808eSpbrook     env->macc[acc + 1] = res;
756e1f3808eSpbrook }
757e1f3808eSpbrook 
7582b3e3cfeSAndreas Färber void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
759e1f3808eSpbrook {
760e1f3808eSpbrook     int64_t res;
761e1f3808eSpbrook     int32_t tmp;
762e1f3808eSpbrook     res = (uint32_t)env->macc[acc];
763e1f3808eSpbrook     tmp = (int16_t)val;
764e1f3808eSpbrook     res |= ((int64_t)tmp) << 32;
765e1f3808eSpbrook     env->macc[acc] = res;
766e1f3808eSpbrook     res = (uint32_t)env->macc[acc + 1];
767e1f3808eSpbrook     tmp = val & 0xffff0000;
768e1f3808eSpbrook     res |= (int64_t)tmp << 16;
769e1f3808eSpbrook     env->macc[acc + 1] = res;
770e1f3808eSpbrook }
771e1f3808eSpbrook 
7722b3e3cfeSAndreas Färber void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
773e1f3808eSpbrook {
774e1f3808eSpbrook     uint64_t res;
775e1f3808eSpbrook     res = (uint32_t)env->macc[acc];
776e1f3808eSpbrook     res |= ((uint64_t)(val & 0xffff)) << 32;
777e1f3808eSpbrook     env->macc[acc] = res;
778e1f3808eSpbrook     res = (uint32_t)env->macc[acc + 1];
779e1f3808eSpbrook     res |= (uint64_t)(val & 0xffff0000) << 16;
780e1f3808eSpbrook     env->macc[acc + 1] = res;
781e1f3808eSpbrook }
7820bdb2b3bSLaurent Vivier 
7830bdb2b3bSLaurent Vivier #if defined(CONFIG_SOFTMMU)
7840bdb2b3bSLaurent Vivier void HELPER(reset)(CPUM68KState *env)
7850bdb2b3bSLaurent Vivier {
7860bdb2b3bSLaurent Vivier     /* FIXME: reset all except CPU */
7870bdb2b3bSLaurent Vivier }
7880bdb2b3bSLaurent Vivier #endif
789