Statistics
| Branch: | Revision:

root / target-m68k / helper.c @ 551bd27f

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