Statistics
| Branch: | Revision:

root / target-m68k / helper.c @ b42ec42d

History | View | Annotate | Download (22.5 kB)

1 e6e5906b pbrook
/*
2 e6e5906b pbrook
 *  m68k op helpers
3 5fafdf24 ths
 *
4 0633879f pbrook
 *  Copyright (c) 2006-2007 CodeSourcery
5 e6e5906b pbrook
 *  Written by Paul Brook
6 e6e5906b pbrook
 *
7 e6e5906b pbrook
 * This library is free software; you can redistribute it and/or
8 e6e5906b pbrook
 * modify it under the terms of the GNU Lesser General Public
9 e6e5906b pbrook
 * License as published by the Free Software Foundation; either
10 e6e5906b pbrook
 * version 2 of the License, or (at your option) any later version.
11 e6e5906b pbrook
 *
12 e6e5906b pbrook
 * This library is distributed in the hope that it will be useful,
13 e6e5906b pbrook
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 e6e5906b pbrook
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 e6e5906b pbrook
 * General Public License for more details.
16 e6e5906b pbrook
 *
17 e6e5906b pbrook
 * You should have received a copy of the GNU Lesser General Public
18 e6e5906b pbrook
 * License along with this library; if not, write to the Free Software
19 fad6cb1a aurel32
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
20 e6e5906b pbrook
 */
21 e6e5906b pbrook
22 e6e5906b pbrook
#include <stdio.h>
23 0402f767 pbrook
#include <string.h>
24 e6e5906b pbrook
25 e6e5906b pbrook
#include "config.h"
26 e6e5906b pbrook
#include "cpu.h"
27 e6e5906b pbrook
#include "exec-all.h"
28 ca10f867 aurel32
#include "qemu-common.h"
29 56aebc89 pbrook
#include "gdbstub.h"
30 e6e5906b pbrook
31 e1f3808e pbrook
#include "helpers.h"
32 e1f3808e pbrook
33 e1f3808e pbrook
#define SIGNBIT (1u << 31)
34 e1f3808e pbrook
35 0402f767 pbrook
enum m68k_cpuid {
36 0402f767 pbrook
    M68K_CPUID_M5206,
37 20dcee94 pbrook
    M68K_CPUID_M5208,
38 0402f767 pbrook
    M68K_CPUID_CFV4E,
39 0402f767 pbrook
    M68K_CPUID_ANY,
40 0402f767 pbrook
};
41 0402f767 pbrook
42 aaed909a bellard
typedef struct m68k_def_t m68k_def_t;
43 aaed909a bellard
44 0402f767 pbrook
struct m68k_def_t {
45 0402f767 pbrook
    const char * name;
46 0402f767 pbrook
    enum m68k_cpuid id;
47 0402f767 pbrook
};
48 0402f767 pbrook
49 0402f767 pbrook
static m68k_def_t m68k_cpu_defs[] = {
50 5fafdf24 ths
    {"m5206", M68K_CPUID_M5206},
51 5fafdf24 ths
    {"m5208", M68K_CPUID_M5208},
52 0402f767 pbrook
    {"cfv4e", M68K_CPUID_CFV4E},
53 0402f767 pbrook
    {"any", M68K_CPUID_ANY},
54 5fafdf24 ths
    {NULL, 0},
55 0402f767 pbrook
};
56 0402f767 pbrook
57 56aebc89 pbrook
static int fpu_gdb_get_reg(CPUState *env, uint8_t *mem_buf, int n)
58 56aebc89 pbrook
{
59 56aebc89 pbrook
    if (n < 8) {
60 56aebc89 pbrook
        stfq_p(mem_buf, env->fregs[n]);
61 56aebc89 pbrook
        return 8;
62 56aebc89 pbrook
    }
63 56aebc89 pbrook
    if (n < 11) {
64 56aebc89 pbrook
        /* FP control registers (not implemented)  */
65 56aebc89 pbrook
        memset(mem_buf, 0, 4);
66 56aebc89 pbrook
        return 4;
67 56aebc89 pbrook
    }
68 56aebc89 pbrook
    return 0;
69 56aebc89 pbrook
}
70 56aebc89 pbrook
71 56aebc89 pbrook
static int fpu_gdb_set_reg(CPUState *env, uint8_t *mem_buf, int n)
72 56aebc89 pbrook
{
73 56aebc89 pbrook
    if (n < 8) {
74 56aebc89 pbrook
        env->fregs[n] = ldfq_p(mem_buf);
75 56aebc89 pbrook
        return 8;
76 56aebc89 pbrook
    }
77 56aebc89 pbrook
    if (n < 11) {
78 56aebc89 pbrook
        /* FP control registers (not implemented)  */
79 56aebc89 pbrook
        return 4;
80 56aebc89 pbrook
    }
81 56aebc89 pbrook
    return 0;
82 56aebc89 pbrook
}
83 56aebc89 pbrook
84 0402f767 pbrook
static void m68k_set_feature(CPUM68KState *env, int feature)
85 0402f767 pbrook
{
86 0402f767 pbrook
    env->features |= (1u << feature);
87 0402f767 pbrook
}
88 0402f767 pbrook
89 aaed909a bellard
static int cpu_m68k_set_model(CPUM68KState *env, const char *name)
90 0402f767 pbrook
{
91 0402f767 pbrook
    m68k_def_t *def;
92 0402f767 pbrook
93 0402f767 pbrook
    for (def = m68k_cpu_defs; def->name; def++) {
94 0402f767 pbrook
        if (strcmp(def->name, name) == 0)
95 0402f767 pbrook
            break;
96 0402f767 pbrook
    }
97 0402f767 pbrook
    if (!def->name)
98 aaed909a bellard
        return -1;
99 0402f767 pbrook
100 0402f767 pbrook
    switch (def->id) {
101 0402f767 pbrook
    case M68K_CPUID_M5206:
102 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
103 0402f767 pbrook
        break;
104 20dcee94 pbrook
    case M68K_CPUID_M5208:
105 20dcee94 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
106 d315c888 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
107 d315c888 pbrook
        m68k_set_feature(env, M68K_FEATURE_BRAL);
108 20dcee94 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
109 20dcee94 pbrook
        m68k_set_feature(env, M68K_FEATURE_USP);
110 20dcee94 pbrook
        break;
111 0402f767 pbrook
    case M68K_CPUID_CFV4E:
112 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
113 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
114 d315c888 pbrook
        m68k_set_feature(env, M68K_FEATURE_BRAL);
115 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_FPU);
116 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
117 20dcee94 pbrook
        m68k_set_feature(env, M68K_FEATURE_USP);
118 0402f767 pbrook
        break;
119 0402f767 pbrook
    case M68K_CPUID_ANY:
120 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
121 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
122 d315c888 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
123 d315c888 pbrook
        m68k_set_feature(env, M68K_FEATURE_BRAL);
124 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_FPU);
125 acf930aa pbrook
        /* MAC and EMAC are mututally exclusive, so pick EMAC.
126 acf930aa pbrook
           It's mostly backwards compatible.  */
127 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
128 d315c888 pbrook
        m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
129 20dcee94 pbrook
        m68k_set_feature(env, M68K_FEATURE_USP);
130 0402f767 pbrook
        m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
131 d315c888 pbrook
        m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
132 0402f767 pbrook
        break;
133 0402f767 pbrook
    }
134 0402f767 pbrook
135 0402f767 pbrook
    register_m68k_insns(env);
136 56aebc89 pbrook
    if (m68k_feature (env, M68K_FEATURE_CF_FPU)) {
137 56aebc89 pbrook
        gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg,
138 56aebc89 pbrook
                                 11, "cf-fp.xml", 18);
139 56aebc89 pbrook
    }
140 56aebc89 pbrook
    /* TODO: Add [E]MAC registers.  */
141 4f6cf9e8 bellard
    return 0;
142 aaed909a bellard
}
143 aaed909a bellard
144 aaed909a bellard
void cpu_reset(CPUM68KState *env)
145 aaed909a bellard
{
146 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
147 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
148 eca1bdf4 aliguori
        log_cpu_state(env, 0);
149 eca1bdf4 aliguori
    }
150 eca1bdf4 aliguori
151 aaed909a bellard
    memset(env, 0, offsetof(CPUM68KState, breakpoints));
152 aaed909a bellard
#if !defined (CONFIG_USER_ONLY)
153 aaed909a bellard
    env->sr = 0x2700;
154 aaed909a bellard
#endif
155 aaed909a bellard
    m68k_switch_sp(env);
156 aaed909a bellard
    /* ??? FP regs should be initialized to NaN.  */
157 aaed909a bellard
    env->cc_op = CC_OP_FLAGS;
158 aaed909a bellard
    /* TODO: We should set PC from the interrupt vector.  */
159 aaed909a bellard
    env->pc = 0;
160 aaed909a bellard
    tlb_flush(env, 1);
161 aaed909a bellard
}
162 aaed909a bellard
163 aaed909a bellard
CPUM68KState *cpu_m68k_init(const char *cpu_model)
164 aaed909a bellard
{
165 aaed909a bellard
    CPUM68KState *env;
166 e1f3808e pbrook
    static int inited;
167 aaed909a bellard
168 6ad1d22b pbrook
    env = qemu_mallocz(sizeof(CPUM68KState));
169 aaed909a bellard
    cpu_exec_init(env);
170 e1f3808e pbrook
    if (!inited) {
171 e1f3808e pbrook
        inited = 1;
172 e1f3808e pbrook
        m68k_tcg_init();
173 e1f3808e pbrook
    }
174 aaed909a bellard
175 01ba9816 ths
    env->cpu_model_str = cpu_model;
176 01ba9816 ths
177 aaed909a bellard
    if (cpu_m68k_set_model(env, cpu_model) < 0) {
178 aaed909a bellard
        cpu_m68k_close(env);
179 aaed909a bellard
        return NULL;
180 aaed909a bellard
    }
181 01ba9816 ths
182 aaed909a bellard
    cpu_reset(env);
183 aaed909a bellard
    return env;
184 aaed909a bellard
}
185 0402f767 pbrook
186 aaed909a bellard
void cpu_m68k_close(CPUM68KState *env)
187 aaed909a bellard
{
188 aaed909a bellard
    qemu_free(env);
189 0402f767 pbrook
}
190 0402f767 pbrook
191 e6e5906b pbrook
void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
192 e6e5906b pbrook
{
193 e6e5906b pbrook
    int flags;
194 e6e5906b pbrook
    uint32_t src;
195 e6e5906b pbrook
    uint32_t dest;
196 e6e5906b pbrook
    uint32_t tmp;
197 e6e5906b pbrook
198 e6e5906b pbrook
#define HIGHBIT 0x80000000u
199 e6e5906b pbrook
200 e6e5906b pbrook
#define SET_NZ(x) do { \
201 e6e5906b pbrook
    if ((x) == 0) \
202 e6e5906b pbrook
        flags |= CCF_Z; \
203 e6e5906b pbrook
    else if ((int32_t)(x) < 0) \
204 e6e5906b pbrook
        flags |= CCF_N; \
205 e6e5906b pbrook
    } while (0)
206 e6e5906b pbrook
207 e6e5906b pbrook
#define SET_FLAGS_SUB(type, utype) do { \
208 e6e5906b pbrook
    SET_NZ((type)dest); \
209 e6e5906b pbrook
    tmp = dest + src; \
210 e6e5906b pbrook
    if ((utype) tmp < (utype) src) \
211 e6e5906b pbrook
        flags |= CCF_C; \
212 e6e5906b pbrook
    if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \
213 e6e5906b pbrook
        flags |= CCF_V; \
214 e6e5906b pbrook
    } while (0)
215 e6e5906b pbrook
216 e6e5906b pbrook
    flags = 0;
217 e6e5906b pbrook
    src = env->cc_src;
218 e6e5906b pbrook
    dest = env->cc_dest;
219 e6e5906b pbrook
    switch (cc_op) {
220 e6e5906b pbrook
    case CC_OP_FLAGS:
221 e6e5906b pbrook
        flags = dest;
222 e6e5906b pbrook
        break;
223 e6e5906b pbrook
    case CC_OP_LOGIC:
224 e6e5906b pbrook
        SET_NZ(dest);
225 e6e5906b pbrook
        break;
226 e6e5906b pbrook
    case CC_OP_ADD:
227 e6e5906b pbrook
        SET_NZ(dest);
228 e6e5906b pbrook
        if (dest < src)
229 e6e5906b pbrook
            flags |= CCF_C;
230 e6e5906b pbrook
        tmp = dest - src;
231 e6e5906b pbrook
        if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
232 e6e5906b pbrook
            flags |= CCF_V;
233 e6e5906b pbrook
        break;
234 e6e5906b pbrook
    case CC_OP_SUB:
235 e6e5906b pbrook
        SET_FLAGS_SUB(int32_t, uint32_t);
236 e6e5906b pbrook
        break;
237 e6e5906b pbrook
    case CC_OP_CMPB:
238 e6e5906b pbrook
        SET_FLAGS_SUB(int8_t, uint8_t);
239 e6e5906b pbrook
        break;
240 e6e5906b pbrook
    case CC_OP_CMPW:
241 e6e5906b pbrook
        SET_FLAGS_SUB(int16_t, uint16_t);
242 e6e5906b pbrook
        break;
243 e6e5906b pbrook
    case CC_OP_ADDX:
244 e6e5906b pbrook
        SET_NZ(dest);
245 e6e5906b pbrook
        if (dest <= src)
246 e6e5906b pbrook
            flags |= CCF_C;
247 e6e5906b pbrook
        tmp = dest - src - 1;
248 e6e5906b pbrook
        if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
249 e6e5906b pbrook
            flags |= CCF_V;
250 e6e5906b pbrook
        break;
251 e6e5906b pbrook
    case CC_OP_SUBX:
252 e6e5906b pbrook
        SET_NZ(dest);
253 e6e5906b pbrook
        tmp = dest + src + 1;
254 e6e5906b pbrook
        if (tmp <= src)
255 e6e5906b pbrook
            flags |= CCF_C;
256 e6e5906b pbrook
        if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
257 e6e5906b pbrook
            flags |= CCF_V;
258 e6e5906b pbrook
        break;
259 e1f3808e pbrook
    case CC_OP_SHIFT:
260 e1f3808e pbrook
        SET_NZ(dest);
261 e1f3808e pbrook
        if (src)
262 e6e5906b pbrook
            flags |= CCF_C;
263 e6e5906b pbrook
        break;
264 e6e5906b pbrook
    default:
265 e6e5906b pbrook
        cpu_abort(env, "Bad CC_OP %d", cc_op);
266 e6e5906b pbrook
    }
267 e6e5906b pbrook
    env->cc_op = CC_OP_FLAGS;
268 e6e5906b pbrook
    env->cc_dest = flags;
269 e6e5906b pbrook
}
270 e6e5906b pbrook
271 e1f3808e pbrook
void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
272 0633879f pbrook
{
273 0633879f pbrook
    switch (reg) {
274 0633879f pbrook
    case 0x02: /* CACR */
275 20dcee94 pbrook
        env->cacr = val;
276 20dcee94 pbrook
        m68k_switch_sp(env);
277 20dcee94 pbrook
        break;
278 20dcee94 pbrook
    case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
279 20dcee94 pbrook
        /* TODO: Implement Access Control Registers.  */
280 0633879f pbrook
        break;
281 0633879f pbrook
    case 0x801: /* VBR */
282 0633879f pbrook
        env->vbr = val;
283 0633879f pbrook
        break;
284 0633879f pbrook
    /* TODO: Implement control registers.  */
285 0633879f pbrook
    default:
286 0633879f pbrook
        cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n",
287 0633879f pbrook
                  reg, val);
288 0633879f pbrook
    }
289 0633879f pbrook
}
290 0633879f pbrook
291 e1f3808e pbrook
void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
292 acf930aa pbrook
{
293 acf930aa pbrook
    uint32_t acc;
294 acf930aa pbrook
    int8_t exthigh;
295 acf930aa pbrook
    uint8_t extlow;
296 acf930aa pbrook
    uint64_t regval;
297 acf930aa pbrook
    int i;
298 acf930aa pbrook
    if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
299 acf930aa pbrook
        for (i = 0; i < 4; i++) {
300 acf930aa pbrook
            regval = env->macc[i];
301 acf930aa pbrook
            exthigh = regval >> 40;
302 acf930aa pbrook
            if (env->macsr & MACSR_FI) {
303 acf930aa pbrook
                acc = regval >> 8;
304 acf930aa pbrook
                extlow = regval;
305 acf930aa pbrook
            } else {
306 acf930aa pbrook
                acc = regval;
307 acf930aa pbrook
                extlow = regval >> 32;
308 acf930aa pbrook
            }
309 acf930aa pbrook
            if (env->macsr & MACSR_FI) {
310 acf930aa pbrook
                regval = (((uint64_t)acc) << 8) | extlow;
311 acf930aa pbrook
                regval |= ((int64_t)exthigh) << 40;
312 acf930aa pbrook
            } else if (env->macsr & MACSR_SU) {
313 acf930aa pbrook
                regval = acc | (((int64_t)extlow) << 32);
314 acf930aa pbrook
                regval |= ((int64_t)exthigh) << 40;
315 acf930aa pbrook
            } else {
316 acf930aa pbrook
                regval = acc | (((uint64_t)extlow) << 32);
317 acf930aa pbrook
                regval |= ((uint64_t)(uint8_t)exthigh) << 40;
318 acf930aa pbrook
            }
319 acf930aa pbrook
            env->macc[i] = regval;
320 acf930aa pbrook
        }
321 acf930aa pbrook
    }
322 acf930aa pbrook
    env->macsr = val;
323 acf930aa pbrook
}
324 acf930aa pbrook
325 20dcee94 pbrook
void m68k_switch_sp(CPUM68KState *env)
326 20dcee94 pbrook
{
327 20dcee94 pbrook
    int new_sp;
328 20dcee94 pbrook
329 20dcee94 pbrook
    env->sp[env->current_sp] = env->aregs[7];
330 20dcee94 pbrook
    new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
331 20dcee94 pbrook
             ? M68K_SSP : M68K_USP;
332 20dcee94 pbrook
    env->aregs[7] = env->sp[new_sp];
333 20dcee94 pbrook
    env->current_sp = new_sp;
334 20dcee94 pbrook
}
335 20dcee94 pbrook
336 0633879f pbrook
/* MMU */
337 0633879f pbrook
338 0633879f pbrook
/* TODO: This will need fixing once the MMU is implemented.  */
339 0633879f pbrook
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
340 0633879f pbrook
{
341 0633879f pbrook
    return addr;
342 0633879f pbrook
}
343 0633879f pbrook
344 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
345 0633879f pbrook
346 0633879f pbrook
int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
347 6ebbf390 j_mayer
                               int mmu_idx, int is_softmmu)
348 0633879f pbrook
{
349 0633879f pbrook
    env->exception_index = EXCP_ACCESS;
350 0633879f pbrook
    env->mmu.ar = address;
351 0633879f pbrook
    return 1;
352 0633879f pbrook
}
353 0633879f pbrook
354 0633879f pbrook
#else
355 0633879f pbrook
356 0633879f pbrook
int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
357 6ebbf390 j_mayer
                               int mmu_idx, int is_softmmu)
358 0633879f pbrook
{
359 0633879f pbrook
    int prot;
360 0633879f pbrook
361 0633879f pbrook
    address &= TARGET_PAGE_MASK;
362 0633879f pbrook
    prot = PAGE_READ | PAGE_WRITE;
363 6ebbf390 j_mayer
    return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);
364 0633879f pbrook
}
365 0633879f pbrook
366 0633879f pbrook
/* Notify CPU of a pending interrupt.  Prioritization and vectoring should
367 0633879f pbrook
   be handled by the interrupt controller.  Real hardware only requests
368 0633879f pbrook
   the vector when the interrupt is acknowledged by the CPU.  For
369 0633879f pbrook
   simplicitly we calculate it when the interrupt is signalled.  */
370 0633879f pbrook
void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector)
371 0633879f pbrook
{
372 0633879f pbrook
    env->pending_level = level;
373 0633879f pbrook
    env->pending_vector = vector;
374 0633879f pbrook
    if (level)
375 0633879f pbrook
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
376 0633879f pbrook
    else
377 0633879f pbrook
        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
378 0633879f pbrook
}
379 0633879f pbrook
380 0633879f pbrook
#endif
381 e1f3808e pbrook
382 e1f3808e pbrook
uint32_t HELPER(bitrev)(uint32_t x)
383 e1f3808e pbrook
{
384 e1f3808e pbrook
    x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
385 e1f3808e pbrook
    x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
386 e1f3808e pbrook
    x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
387 e1f3808e pbrook
    return bswap32(x);
388 e1f3808e pbrook
}
389 e1f3808e pbrook
390 e1f3808e pbrook
uint32_t HELPER(ff1)(uint32_t x)
391 e1f3808e pbrook
{
392 e1f3808e pbrook
    int n;
393 e1f3808e pbrook
    for (n = 32; x; n--)
394 e1f3808e pbrook
        x >>= 1;
395 e1f3808e pbrook
    return n;
396 e1f3808e pbrook
}
397 e1f3808e pbrook
398 e1f3808e pbrook
uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
399 e1f3808e pbrook
{
400 e1f3808e pbrook
    /* The result has the opposite sign to the original value.  */
401 e1f3808e pbrook
    if (ccr & CCF_V)
402 e1f3808e pbrook
        val = (((int32_t)val) >> 31) ^ SIGNBIT;
403 e1f3808e pbrook
    return val;
404 e1f3808e pbrook
}
405 e1f3808e pbrook
406 e1f3808e pbrook
uint32_t HELPER(subx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
407 e1f3808e pbrook
{
408 e1f3808e pbrook
    uint32_t res;
409 e1f3808e pbrook
    uint32_t old_flags;
410 e1f3808e pbrook
411 e1f3808e pbrook
    old_flags = env->cc_dest;
412 e1f3808e pbrook
    if (env->cc_x) {
413 e1f3808e pbrook
        env->cc_x = (op1 <= op2);
414 e1f3808e pbrook
        env->cc_op = CC_OP_SUBX;
415 e1f3808e pbrook
        res = op1 - (op2 + 1);
416 e1f3808e pbrook
    } else {
417 e1f3808e pbrook
        env->cc_x = (op1 < op2);
418 e1f3808e pbrook
        env->cc_op = CC_OP_SUB;
419 e1f3808e pbrook
        res = op1 - op2;
420 e1f3808e pbrook
    }
421 e1f3808e pbrook
    env->cc_dest = res;
422 e1f3808e pbrook
    env->cc_src = op2;
423 e1f3808e pbrook
    cpu_m68k_flush_flags(env, env->cc_op);
424 e1f3808e pbrook
    /* !Z is sticky.  */
425 e1f3808e pbrook
    env->cc_dest &= (old_flags | ~CCF_Z);
426 e1f3808e pbrook
    return res;
427 e1f3808e pbrook
}
428 e1f3808e pbrook
429 e1f3808e pbrook
uint32_t HELPER(addx_cc)(CPUState *env, uint32_t op1, uint32_t op2)
430 e1f3808e pbrook
{
431 e1f3808e pbrook
    uint32_t res;
432 e1f3808e pbrook
    uint32_t old_flags;
433 e1f3808e pbrook
434 e1f3808e pbrook
    old_flags = env->cc_dest;
435 e1f3808e pbrook
    if (env->cc_x) {
436 e1f3808e pbrook
        res = op1 + op2 + 1;
437 e1f3808e pbrook
        env->cc_x = (res <= op2);
438 e1f3808e pbrook
        env->cc_op = CC_OP_ADDX;
439 e1f3808e pbrook
    } else {
440 e1f3808e pbrook
        res = op1 + op2;
441 e1f3808e pbrook
        env->cc_x = (res < op2);
442 e1f3808e pbrook
        env->cc_op = CC_OP_ADD;
443 e1f3808e pbrook
    }
444 e1f3808e pbrook
    env->cc_dest = res;
445 e1f3808e pbrook
    env->cc_src = op2;
446 e1f3808e pbrook
    cpu_m68k_flush_flags(env, env->cc_op);
447 e1f3808e pbrook
    /* !Z is sticky.  */
448 e1f3808e pbrook
    env->cc_dest &= (old_flags | ~CCF_Z);
449 e1f3808e pbrook
    return res;
450 e1f3808e pbrook
}
451 e1f3808e pbrook
452 e1f3808e pbrook
uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
453 e1f3808e pbrook
{
454 e1f3808e pbrook
    return a < b;
455 e1f3808e pbrook
}
456 e1f3808e pbrook
457 e1f3808e pbrook
uint32_t HELPER(btest)(uint32_t x)
458 e1f3808e pbrook
{
459 e1f3808e pbrook
    return x != 0;
460 e1f3808e pbrook
}
461 e1f3808e pbrook
462 e1f3808e pbrook
void HELPER(set_sr)(CPUState *env, uint32_t val)
463 e1f3808e pbrook
{
464 e1f3808e pbrook
    env->sr = val & 0xffff;
465 e1f3808e pbrook
    m68k_switch_sp(env);
466 e1f3808e pbrook
}
467 e1f3808e pbrook
468 e1f3808e pbrook
uint32_t HELPER(shl_cc)(CPUState *env, uint32_t val, uint32_t shift)
469 e1f3808e pbrook
{
470 e1f3808e pbrook
    uint32_t result;
471 e1f3808e pbrook
    uint32_t cf;
472 e1f3808e pbrook
473 e1f3808e pbrook
    shift &= 63;
474 e1f3808e pbrook
    if (shift == 0) {
475 e1f3808e pbrook
        result = val;
476 e1f3808e pbrook
        cf = env->cc_src & CCF_C;
477 e1f3808e pbrook
    } else if (shift < 32) {
478 e1f3808e pbrook
        result = val << shift;
479 e1f3808e pbrook
        cf = (val >> (32 - shift)) & 1;
480 e1f3808e pbrook
    } else if (shift == 32) {
481 e1f3808e pbrook
        result = 0;
482 e1f3808e pbrook
        cf = val & 1;
483 e1f3808e pbrook
    } else /* shift > 32 */ {
484 e1f3808e pbrook
        result = 0;
485 e1f3808e pbrook
        cf = 0;
486 e1f3808e pbrook
    }
487 e1f3808e pbrook
    env->cc_src = cf;
488 e1f3808e pbrook
    env->cc_x = (cf != 0);
489 e1f3808e pbrook
    env->cc_dest = result;
490 e1f3808e pbrook
    return result;
491 e1f3808e pbrook
}
492 e1f3808e pbrook
493 e1f3808e pbrook
uint32_t HELPER(shr_cc)(CPUState *env, uint32_t val, uint32_t shift)
494 e1f3808e pbrook
{
495 e1f3808e pbrook
    uint32_t result;
496 e1f3808e pbrook
    uint32_t cf;
497 e1f3808e pbrook
498 e1f3808e pbrook
    shift &= 63;
499 e1f3808e pbrook
    if (shift == 0) {
500 e1f3808e pbrook
        result = val;
501 e1f3808e pbrook
        cf = env->cc_src & CCF_C;
502 e1f3808e pbrook
    } else if (shift < 32) {
503 e1f3808e pbrook
        result = val >> shift;
504 e1f3808e pbrook
        cf = (val >> (shift - 1)) & 1;
505 e1f3808e pbrook
    } else if (shift == 32) {
506 e1f3808e pbrook
        result = 0;
507 e1f3808e pbrook
        cf = val >> 31;
508 e1f3808e pbrook
    } else /* shift > 32 */ {
509 e1f3808e pbrook
        result = 0;
510 e1f3808e pbrook
        cf = 0;
511 e1f3808e pbrook
    }
512 e1f3808e pbrook
    env->cc_src = cf;
513 e1f3808e pbrook
    env->cc_x = (cf != 0);
514 e1f3808e pbrook
    env->cc_dest = result;
515 e1f3808e pbrook
    return result;
516 e1f3808e pbrook
}
517 e1f3808e pbrook
518 e1f3808e pbrook
uint32_t HELPER(sar_cc)(CPUState *env, uint32_t val, uint32_t shift)
519 e1f3808e pbrook
{
520 e1f3808e pbrook
    uint32_t result;
521 e1f3808e pbrook
    uint32_t cf;
522 e1f3808e pbrook
523 e1f3808e pbrook
    shift &= 63;
524 e1f3808e pbrook
    if (shift == 0) {
525 e1f3808e pbrook
        result = val;
526 e1f3808e pbrook
        cf = (env->cc_src & CCF_C) != 0;
527 e1f3808e pbrook
    } else if (shift < 32) {
528 e1f3808e pbrook
        result = (int32_t)val >> shift;
529 e1f3808e pbrook
        cf = (val >> (shift - 1)) & 1;
530 e1f3808e pbrook
    } else /* shift >= 32 */ {
531 e1f3808e pbrook
        result = (int32_t)val >> 31;
532 e1f3808e pbrook
        cf = val >> 31;
533 e1f3808e pbrook
    }
534 e1f3808e pbrook
    env->cc_src = cf;
535 e1f3808e pbrook
    env->cc_x = cf;
536 e1f3808e pbrook
    env->cc_dest = result;
537 e1f3808e pbrook
    return result;
538 e1f3808e pbrook
}
539 e1f3808e pbrook
540 e1f3808e pbrook
/* FPU helpers.  */
541 e1f3808e pbrook
uint32_t HELPER(f64_to_i32)(CPUState *env, float64 val)
542 e1f3808e pbrook
{
543 e1f3808e pbrook
    return float64_to_int32(val, &env->fp_status);
544 e1f3808e pbrook
}
545 e1f3808e pbrook
546 e1f3808e pbrook
float32 HELPER(f64_to_f32)(CPUState *env, float64 val)
547 e1f3808e pbrook
{
548 e1f3808e pbrook
    return float64_to_float32(val, &env->fp_status);
549 e1f3808e pbrook
}
550 e1f3808e pbrook
551 e1f3808e pbrook
float64 HELPER(i32_to_f64)(CPUState *env, uint32_t val)
552 e1f3808e pbrook
{
553 e1f3808e pbrook
    return int32_to_float64(val, &env->fp_status);
554 e1f3808e pbrook
}
555 e1f3808e pbrook
556 e1f3808e pbrook
float64 HELPER(f32_to_f64)(CPUState *env, float32 val)
557 e1f3808e pbrook
{
558 e1f3808e pbrook
    return float32_to_float64(val, &env->fp_status);
559 e1f3808e pbrook
}
560 e1f3808e pbrook
561 e1f3808e pbrook
float64 HELPER(iround_f64)(CPUState *env, float64 val)
562 e1f3808e pbrook
{
563 e1f3808e pbrook
    return float64_round_to_int(val, &env->fp_status);
564 e1f3808e pbrook
}
565 e1f3808e pbrook
566 e1f3808e pbrook
float64 HELPER(itrunc_f64)(CPUState *env, float64 val)
567 e1f3808e pbrook
{
568 e1f3808e pbrook
    return float64_trunc_to_int(val, &env->fp_status);
569 e1f3808e pbrook
}
570 e1f3808e pbrook
571 e1f3808e pbrook
float64 HELPER(sqrt_f64)(CPUState *env, float64 val)
572 e1f3808e pbrook
{
573 e1f3808e pbrook
    return float64_sqrt(val, &env->fp_status);
574 e1f3808e pbrook
}
575 e1f3808e pbrook
576 e1f3808e pbrook
float64 HELPER(abs_f64)(float64 val)
577 e1f3808e pbrook
{
578 e1f3808e pbrook
    return float64_abs(val);
579 e1f3808e pbrook
}
580 e1f3808e pbrook
581 e1f3808e pbrook
float64 HELPER(chs_f64)(float64 val)
582 e1f3808e pbrook
{
583 e1f3808e pbrook
    return float64_chs(val);
584 e1f3808e pbrook
}
585 e1f3808e pbrook
586 e1f3808e pbrook
float64 HELPER(add_f64)(CPUState *env, float64 a, float64 b)
587 e1f3808e pbrook
{
588 e1f3808e pbrook
    return float64_add(a, b, &env->fp_status);
589 e1f3808e pbrook
}
590 e1f3808e pbrook
591 e1f3808e pbrook
float64 HELPER(sub_f64)(CPUState *env, float64 a, float64 b)
592 e1f3808e pbrook
{
593 e1f3808e pbrook
    return float64_sub(a, b, &env->fp_status);
594 e1f3808e pbrook
}
595 e1f3808e pbrook
596 e1f3808e pbrook
float64 HELPER(mul_f64)(CPUState *env, float64 a, float64 b)
597 e1f3808e pbrook
{
598 e1f3808e pbrook
    return float64_mul(a, b, &env->fp_status);
599 e1f3808e pbrook
}
600 e1f3808e pbrook
601 e1f3808e pbrook
float64 HELPER(div_f64)(CPUState *env, float64 a, float64 b)
602 e1f3808e pbrook
{
603 e1f3808e pbrook
    return float64_div(a, b, &env->fp_status);
604 e1f3808e pbrook
}
605 e1f3808e pbrook
606 e1f3808e pbrook
float64 HELPER(sub_cmp_f64)(CPUState *env, float64 a, float64 b)
607 e1f3808e pbrook
{
608 e1f3808e pbrook
    /* ??? This may incorrectly raise exceptions.  */
609 e1f3808e pbrook
    /* ??? Should flush denormals to zero.  */
610 e1f3808e pbrook
    float64 res;
611 e1f3808e pbrook
    res = float64_sub(a, b, &env->fp_status);
612 e1f3808e pbrook
    if (float64_is_nan(res)) {
613 e1f3808e pbrook
        /* +/-inf compares equal against itself, but sub returns nan.  */
614 e1f3808e pbrook
        if (!float64_is_nan(a)
615 e1f3808e pbrook
            && !float64_is_nan(b)) {
616 e1f3808e pbrook
            res = float64_zero;
617 e1f3808e pbrook
            if (float64_lt_quiet(a, res, &env->fp_status))
618 e1f3808e pbrook
                res = float64_chs(res);
619 e1f3808e pbrook
        }
620 e1f3808e pbrook
    }
621 e1f3808e pbrook
    return res;
622 e1f3808e pbrook
}
623 e1f3808e pbrook
624 e1f3808e pbrook
uint32_t HELPER(compare_f64)(CPUState *env, float64 val)
625 e1f3808e pbrook
{
626 e1f3808e pbrook
    return float64_compare_quiet(val, float64_zero, &env->fp_status);
627 e1f3808e pbrook
}
628 e1f3808e pbrook
629 e1f3808e pbrook
/* MAC unit.  */
630 e1f3808e pbrook
/* FIXME: The MAC unit implementation is a bit of a mess.  Some helpers
631 e1f3808e pbrook
   take values,  others take register numbers and manipulate the contents
632 e1f3808e pbrook
   in-place.  */
633 e1f3808e pbrook
void HELPER(mac_move)(CPUState *env, uint32_t dest, uint32_t src)
634 e1f3808e pbrook
{
635 e1f3808e pbrook
    uint32_t mask;
636 e1f3808e pbrook
    env->macc[dest] = env->macc[src];
637 e1f3808e pbrook
    mask = MACSR_PAV0 << dest;
638 e1f3808e pbrook
    if (env->macsr & (MACSR_PAV0 << src))
639 e1f3808e pbrook
        env->macsr |= mask;
640 e1f3808e pbrook
    else
641 e1f3808e pbrook
        env->macsr &= ~mask;
642 e1f3808e pbrook
}
643 e1f3808e pbrook
644 e1f3808e pbrook
uint64_t HELPER(macmuls)(CPUState *env, uint32_t op1, uint32_t op2)
645 e1f3808e pbrook
{
646 e1f3808e pbrook
    int64_t product;
647 e1f3808e pbrook
    int64_t res;
648 e1f3808e pbrook
649 e1f3808e pbrook
    product = (uint64_t)op1 * op2;
650 e1f3808e pbrook
    res = (product << 24) >> 24;
651 e1f3808e pbrook
    if (res != product) {
652 e1f3808e pbrook
        env->macsr |= MACSR_V;
653 e1f3808e pbrook
        if (env->macsr & MACSR_OMC) {
654 e1f3808e pbrook
            /* Make sure the accumulate operation overflows.  */
655 e1f3808e pbrook
            if (product < 0)
656 e1f3808e pbrook
                res = ~(1ll << 50);
657 e1f3808e pbrook
            else
658 e1f3808e pbrook
                res = 1ll << 50;
659 e1f3808e pbrook
        }
660 e1f3808e pbrook
    }
661 e1f3808e pbrook
    return res;
662 e1f3808e pbrook
}
663 e1f3808e pbrook
664 e1f3808e pbrook
uint64_t HELPER(macmulu)(CPUState *env, uint32_t op1, uint32_t op2)
665 e1f3808e pbrook
{
666 e1f3808e pbrook
    uint64_t product;
667 e1f3808e pbrook
668 e1f3808e pbrook
    product = (uint64_t)op1 * op2;
669 e1f3808e pbrook
    if (product & (0xffffffull << 40)) {
670 e1f3808e pbrook
        env->macsr |= MACSR_V;
671 e1f3808e pbrook
        if (env->macsr & MACSR_OMC) {
672 e1f3808e pbrook
            /* Make sure the accumulate operation overflows.  */
673 e1f3808e pbrook
            product = 1ll << 50;
674 e1f3808e pbrook
        } else {
675 e1f3808e pbrook
            product &= ((1ull << 40) - 1);
676 e1f3808e pbrook
        }
677 e1f3808e pbrook
    }
678 e1f3808e pbrook
    return product;
679 e1f3808e pbrook
}
680 e1f3808e pbrook
681 e1f3808e pbrook
uint64_t HELPER(macmulf)(CPUState *env, uint32_t op1, uint32_t op2)
682 e1f3808e pbrook
{
683 e1f3808e pbrook
    uint64_t product;
684 e1f3808e pbrook
    uint32_t remainder;
685 e1f3808e pbrook
686 e1f3808e pbrook
    product = (uint64_t)op1 * op2;
687 e1f3808e pbrook
    if (env->macsr & MACSR_RT) {
688 e1f3808e pbrook
        remainder = product & 0xffffff;
689 e1f3808e pbrook
        product >>= 24;
690 e1f3808e pbrook
        if (remainder > 0x800000)
691 e1f3808e pbrook
            product++;
692 e1f3808e pbrook
        else if (remainder == 0x800000)
693 e1f3808e pbrook
            product += (product & 1);
694 e1f3808e pbrook
    } else {
695 e1f3808e pbrook
        product >>= 24;
696 e1f3808e pbrook
    }
697 e1f3808e pbrook
    return product;
698 e1f3808e pbrook
}
699 e1f3808e pbrook
700 e1f3808e pbrook
void HELPER(macsats)(CPUState *env, uint32_t acc)
701 e1f3808e pbrook
{
702 e1f3808e pbrook
    int64_t tmp;
703 e1f3808e pbrook
    int64_t result;
704 e1f3808e pbrook
    tmp = env->macc[acc];
705 e1f3808e pbrook
    result = ((tmp << 16) >> 16);
706 e1f3808e pbrook
    if (result != tmp) {
707 e1f3808e pbrook
        env->macsr |= MACSR_V;
708 e1f3808e pbrook
    }
709 e1f3808e pbrook
    if (env->macsr & MACSR_V) {
710 e1f3808e pbrook
        env->macsr |= MACSR_PAV0 << acc;
711 e1f3808e pbrook
        if (env->macsr & MACSR_OMC) {
712 e1f3808e pbrook
            /* The result is saturated to 32 bits, despite overflow occuring
713 e1f3808e pbrook
               at 48 bits.  Seems weird, but that's what the hardware docs
714 e1f3808e pbrook
               say.  */
715 e1f3808e pbrook
            result = (result >> 63) ^ 0x7fffffff;
716 e1f3808e pbrook
        }
717 e1f3808e pbrook
    }
718 e1f3808e pbrook
    env->macc[acc] = result;
719 e1f3808e pbrook
}
720 e1f3808e pbrook
721 e1f3808e pbrook
void HELPER(macsatu)(CPUState *env, uint32_t acc)
722 e1f3808e pbrook
{
723 e1f3808e pbrook
    uint64_t val;
724 e1f3808e pbrook
725 e1f3808e pbrook
    val = env->macc[acc];
726 e1f3808e pbrook
    if (val & (0xffffull << 48)) {
727 e1f3808e pbrook
        env->macsr |= MACSR_V;
728 e1f3808e pbrook
    }
729 e1f3808e pbrook
    if (env->macsr & MACSR_V) {
730 e1f3808e pbrook
        env->macsr |= MACSR_PAV0 << acc;
731 e1f3808e pbrook
        if (env->macsr & MACSR_OMC) {
732 e1f3808e pbrook
            if (val > (1ull << 53))
733 e1f3808e pbrook
                val = 0;
734 e1f3808e pbrook
            else
735 e1f3808e pbrook
                val = (1ull << 48) - 1;
736 e1f3808e pbrook
        } else {
737 e1f3808e pbrook
            val &= ((1ull << 48) - 1);
738 e1f3808e pbrook
        }
739 e1f3808e pbrook
    }
740 e1f3808e pbrook
    env->macc[acc] = val;
741 e1f3808e pbrook
}
742 e1f3808e pbrook
743 e1f3808e pbrook
void HELPER(macsatf)(CPUState *env, uint32_t acc)
744 e1f3808e pbrook
{
745 e1f3808e pbrook
    int64_t sum;
746 e1f3808e pbrook
    int64_t result;
747 e1f3808e pbrook
748 e1f3808e pbrook
    sum = env->macc[acc];
749 e1f3808e pbrook
    result = (sum << 16) >> 16;
750 e1f3808e pbrook
    if (result != sum) {
751 e1f3808e pbrook
        env->macsr |= MACSR_V;
752 e1f3808e pbrook
    }
753 e1f3808e pbrook
    if (env->macsr & MACSR_V) {
754 e1f3808e pbrook
        env->macsr |= MACSR_PAV0 << acc;
755 e1f3808e pbrook
        if (env->macsr & MACSR_OMC) {
756 e1f3808e pbrook
            result = (result >> 63) ^ 0x7fffffffffffll;
757 e1f3808e pbrook
        }
758 e1f3808e pbrook
    }
759 e1f3808e pbrook
    env->macc[acc] = result;
760 e1f3808e pbrook
}
761 e1f3808e pbrook
762 e1f3808e pbrook
void HELPER(mac_set_flags)(CPUState *env, uint32_t acc)
763 e1f3808e pbrook
{
764 e1f3808e pbrook
    uint64_t val;
765 e1f3808e pbrook
    val = env->macc[acc];
766 e1f3808e pbrook
    if (val == 0)
767 e1f3808e pbrook
        env->macsr |= MACSR_Z;
768 e1f3808e pbrook
    else if (val & (1ull << 47));
769 e1f3808e pbrook
        env->macsr |= MACSR_N;
770 e1f3808e pbrook
    if (env->macsr & (MACSR_PAV0 << acc)) {
771 e1f3808e pbrook
        env->macsr |= MACSR_V;
772 e1f3808e pbrook
    }
773 e1f3808e pbrook
    if (env->macsr & MACSR_FI) {
774 e1f3808e pbrook
        val = ((int64_t)val) >> 40;
775 e1f3808e pbrook
        if (val != 0 && val != -1)
776 e1f3808e pbrook
            env->macsr |= MACSR_EV;
777 e1f3808e pbrook
    } else if (env->macsr & MACSR_SU) {
778 e1f3808e pbrook
        val = ((int64_t)val) >> 32;
779 e1f3808e pbrook
        if (val != 0 && val != -1)
780 e1f3808e pbrook
            env->macsr |= MACSR_EV;
781 e1f3808e pbrook
    } else {
782 e1f3808e pbrook
        if ((val >> 32) != 0)
783 e1f3808e pbrook
            env->macsr |= MACSR_EV;
784 e1f3808e pbrook
    }
785 e1f3808e pbrook
}
786 e1f3808e pbrook
787 e1f3808e pbrook
void HELPER(flush_flags)(CPUState *env, uint32_t cc_op)
788 e1f3808e pbrook
{
789 e1f3808e pbrook
    cpu_m68k_flush_flags(env, cc_op);
790 e1f3808e pbrook
}
791 e1f3808e pbrook
792 e1f3808e pbrook
uint32_t HELPER(get_macf)(CPUState *env, uint64_t val)
793 e1f3808e pbrook
{
794 e1f3808e pbrook
    int rem;
795 e1f3808e pbrook
    uint32_t result;
796 e1f3808e pbrook
797 e1f3808e pbrook
    if (env->macsr & MACSR_SU) {
798 e1f3808e pbrook
        /* 16-bit rounding.  */
799 e1f3808e pbrook
        rem = val & 0xffffff;
800 e1f3808e pbrook
        val = (val >> 24) & 0xffffu;
801 e1f3808e pbrook
        if (rem > 0x800000)
802 e1f3808e pbrook
            val++;
803 e1f3808e pbrook
        else if (rem == 0x800000)
804 e1f3808e pbrook
            val += (val & 1);
805 e1f3808e pbrook
    } else if (env->macsr & MACSR_RT) {
806 e1f3808e pbrook
        /* 32-bit rounding.  */
807 e1f3808e pbrook
        rem = val & 0xff;
808 e1f3808e pbrook
        val >>= 8;
809 e1f3808e pbrook
        if (rem > 0x80)
810 e1f3808e pbrook
            val++;
811 e1f3808e pbrook
        else if (rem == 0x80)
812 e1f3808e pbrook
            val += (val & 1);
813 e1f3808e pbrook
    } else {
814 e1f3808e pbrook
        /* No rounding.  */
815 e1f3808e pbrook
        val >>= 8;
816 e1f3808e pbrook
    }
817 e1f3808e pbrook
    if (env->macsr & MACSR_OMC) {
818 e1f3808e pbrook
        /* Saturate.  */
819 e1f3808e pbrook
        if (env->macsr & MACSR_SU) {
820 e1f3808e pbrook
            if (val != (uint16_t) val) {
821 e1f3808e pbrook
                result = ((val >> 63) ^ 0x7fff) & 0xffff;
822 e1f3808e pbrook
            } else {
823 e1f3808e pbrook
                result = val & 0xffff;
824 e1f3808e pbrook
            }
825 e1f3808e pbrook
        } else {
826 e1f3808e pbrook
            if (val != (uint32_t)val) {
827 e1f3808e pbrook
                result = ((uint32_t)(val >> 63) & 0x7fffffff);
828 e1f3808e pbrook
            } else {
829 e1f3808e pbrook
                result = (uint32_t)val;
830 e1f3808e pbrook
            }
831 e1f3808e pbrook
        }
832 e1f3808e pbrook
    } else {
833 e1f3808e pbrook
        /* No saturation.  */
834 e1f3808e pbrook
        if (env->macsr & MACSR_SU) {
835 e1f3808e pbrook
            result = val & 0xffff;
836 e1f3808e pbrook
        } else {
837 e1f3808e pbrook
            result = (uint32_t)val;
838 e1f3808e pbrook
        }
839 e1f3808e pbrook
    }
840 e1f3808e pbrook
    return result;
841 e1f3808e pbrook
}
842 e1f3808e pbrook
843 e1f3808e pbrook
uint32_t HELPER(get_macs)(uint64_t val)
844 e1f3808e pbrook
{
845 e1f3808e pbrook
    if (val == (int32_t)val) {
846 e1f3808e pbrook
        return (int32_t)val;
847 e1f3808e pbrook
    } else {
848 e1f3808e pbrook
        return (val >> 61) ^ ~SIGNBIT;
849 e1f3808e pbrook
    }
850 e1f3808e pbrook
}
851 e1f3808e pbrook
852 e1f3808e pbrook
uint32_t HELPER(get_macu)(uint64_t val)
853 e1f3808e pbrook
{
854 e1f3808e pbrook
    if ((val >> 32) == 0) {
855 e1f3808e pbrook
        return (uint32_t)val;
856 e1f3808e pbrook
    } else {
857 e1f3808e pbrook
        return 0xffffffffu;
858 e1f3808e pbrook
    }
859 e1f3808e pbrook
}
860 e1f3808e pbrook
861 e1f3808e pbrook
uint32_t HELPER(get_mac_extf)(CPUState *env, uint32_t acc)
862 e1f3808e pbrook
{
863 e1f3808e pbrook
    uint32_t val;
864 e1f3808e pbrook
    val = env->macc[acc] & 0x00ff;
865 e1f3808e pbrook
    val = (env->macc[acc] >> 32) & 0xff00;
866 e1f3808e pbrook
    val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
867 e1f3808e pbrook
    val |= (env->macc[acc + 1] >> 16) & 0xff000000;
868 e1f3808e pbrook
    return val;
869 e1f3808e pbrook
}
870 e1f3808e pbrook
871 e1f3808e pbrook
uint32_t HELPER(get_mac_exti)(CPUState *env, uint32_t acc)
872 e1f3808e pbrook
{
873 e1f3808e pbrook
    uint32_t val;
874 e1f3808e pbrook
    val = (env->macc[acc] >> 32) & 0xffff;
875 e1f3808e pbrook
    val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
876 e1f3808e pbrook
    return val;
877 e1f3808e pbrook
}
878 e1f3808e pbrook
879 e1f3808e pbrook
void HELPER(set_mac_extf)(CPUState *env, uint32_t val, uint32_t acc)
880 e1f3808e pbrook
{
881 e1f3808e pbrook
    int64_t res;
882 e1f3808e pbrook
    int32_t tmp;
883 e1f3808e pbrook
    res = env->macc[acc] & 0xffffffff00ull;
884 e1f3808e pbrook
    tmp = (int16_t)(val & 0xff00);
885 e1f3808e pbrook
    res |= ((int64_t)tmp) << 32;
886 e1f3808e pbrook
    res |= val & 0xff;
887 e1f3808e pbrook
    env->macc[acc] = res;
888 e1f3808e pbrook
    res = env->macc[acc + 1] & 0xffffffff00ull;
889 e1f3808e pbrook
    tmp = (val & 0xff000000);
890 e1f3808e pbrook
    res |= ((int64_t)tmp) << 16;
891 e1f3808e pbrook
    res |= (val >> 16) & 0xff;
892 e1f3808e pbrook
    env->macc[acc + 1] = res;
893 e1f3808e pbrook
}
894 e1f3808e pbrook
895 e1f3808e pbrook
void HELPER(set_mac_exts)(CPUState *env, uint32_t val, uint32_t acc)
896 e1f3808e pbrook
{
897 e1f3808e pbrook
    int64_t res;
898 e1f3808e pbrook
    int32_t tmp;
899 e1f3808e pbrook
    res = (uint32_t)env->macc[acc];
900 e1f3808e pbrook
    tmp = (int16_t)val;
901 e1f3808e pbrook
    res |= ((int64_t)tmp) << 32;
902 e1f3808e pbrook
    env->macc[acc] = res;
903 e1f3808e pbrook
    res = (uint32_t)env->macc[acc + 1];
904 e1f3808e pbrook
    tmp = val & 0xffff0000;
905 e1f3808e pbrook
    res |= (int64_t)tmp << 16;
906 e1f3808e pbrook
    env->macc[acc + 1] = res;
907 e1f3808e pbrook
}
908 e1f3808e pbrook
909 e1f3808e pbrook
void HELPER(set_mac_extu)(CPUState *env, uint32_t val, uint32_t acc)
910 e1f3808e pbrook
{
911 e1f3808e pbrook
    uint64_t res;
912 e1f3808e pbrook
    res = (uint32_t)env->macc[acc];
913 e1f3808e pbrook
    res |= ((uint64_t)(val & 0xffff)) << 32;
914 e1f3808e pbrook
    env->macc[acc] = res;
915 e1f3808e pbrook
    res = (uint32_t)env->macc[acc + 1];
916 e1f3808e pbrook
    res |= (uint64_t)(val & 0xffff0000) << 16;
917 e1f3808e pbrook
    env->macc[acc + 1] = res;
918 e1f3808e pbrook
}