Statistics
| Branch: | Revision:

root / target-m68k / op.c @ 0cf5c677

History | View | Annotate | Download (20.7 kB)

1 e6e5906b pbrook
/*
2 e6e5906b pbrook
 *  m68k micro operations
3 e6e5906b pbrook
 * 
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 "exec.h"
23 e6e5906b pbrook
#include "m68k-qreg.h"
24 e6e5906b pbrook
25 e6e5906b pbrook
#ifndef offsetof
26 e6e5906b pbrook
#define offsetof(type, field) ((size_t) &((type *)0)->field)
27 e6e5906b pbrook
#endif
28 e6e5906b pbrook
29 e6e5906b pbrook
static long qreg_offsets[] = {
30 e6e5906b pbrook
#define DEFO32(name, offset) offsetof(CPUState, offset),
31 e6e5906b pbrook
#define DEFR(name, reg, mode) -1,
32 e6e5906b pbrook
#define DEFF64(name, offset) offsetof(CPUState, offset),
33 e6e5906b pbrook
    0,
34 e6e5906b pbrook
#include "qregs.def"
35 e6e5906b pbrook
};
36 e6e5906b pbrook
37 e6e5906b pbrook
#define CPU_FP_STATUS env->fp_status
38 e6e5906b pbrook
39 e6e5906b pbrook
#define RAISE_EXCEPTION(n) do { \
40 e6e5906b pbrook
    env->exception_index = n; \
41 e6e5906b pbrook
    cpu_loop_exit(); \
42 e6e5906b pbrook
    } while(0)
43 e6e5906b pbrook
44 e6e5906b pbrook
#define get_op helper_get_op
45 e6e5906b pbrook
#define set_op helper_set_op
46 e6e5906b pbrook
#define get_opf64 helper_get_opf64
47 e6e5906b pbrook
#define set_opf64 helper_set_opf64
48 e6e5906b pbrook
uint32_t
49 e6e5906b pbrook
get_op(int qreg)
50 e6e5906b pbrook
{
51 7ec47ead pbrook
    if (qreg >= TARGET_NUM_QREGS) {
52 7ec47ead pbrook
        return env->qregs[qreg - TARGET_NUM_QREGS];
53 7ec47ead pbrook
    } else if (qreg == QREG_T0) {
54 e6e5906b pbrook
        return T0;
55 e6e5906b pbrook
    } else {
56 7ec47ead pbrook
        return *(uint32_t *)(((long)env) + qreg_offsets[qreg]);
57 e6e5906b pbrook
    }
58 e6e5906b pbrook
}
59 e6e5906b pbrook
60 e6e5906b pbrook
void set_op(int qreg, uint32_t val)
61 e6e5906b pbrook
{
62 7ec47ead pbrook
    if (qreg >= TARGET_NUM_QREGS) {
63 7ec47ead pbrook
        env->qregs[qreg - TARGET_NUM_QREGS] = val;
64 7ec47ead pbrook
    } else if (qreg == QREG_T0) {
65 e6e5906b pbrook
        T0 = val;
66 e6e5906b pbrook
    } else {
67 7ec47ead pbrook
        *(uint32_t *)(((long)env) + qreg_offsets[qreg]) = val;
68 e6e5906b pbrook
    }
69 e6e5906b pbrook
}
70 e6e5906b pbrook
71 e6e5906b pbrook
float64 get_opf64(int qreg)
72 e6e5906b pbrook
{
73 e6e5906b pbrook
    if (qreg < TARGET_NUM_QREGS) {
74 e6e5906b pbrook
        return *(float64 *)(((long)env) + qreg_offsets[qreg]);
75 e6e5906b pbrook
    } else {
76 e6e5906b pbrook
        return *(float64 *)&env->qregs[qreg - TARGET_NUM_QREGS];
77 e6e5906b pbrook
    }
78 e6e5906b pbrook
}
79 e6e5906b pbrook
80 e6e5906b pbrook
void set_opf64(int qreg, float64 val)
81 e6e5906b pbrook
{
82 e6e5906b pbrook
    if (qreg < TARGET_NUM_QREGS) {
83 e6e5906b pbrook
        *(float64 *)(((long)env) + qreg_offsets[qreg]) = val;
84 e6e5906b pbrook
    } else {
85 e6e5906b pbrook
        *(float64 *)&env->qregs[qreg - TARGET_NUM_QREGS] = val;
86 e6e5906b pbrook
    }
87 e6e5906b pbrook
}
88 e6e5906b pbrook
89 0633879f pbrook
#define OP(name) void OPPROTO glue(op_,name) (void)
90 e6e5906b pbrook
91 e6e5906b pbrook
OP(mov32)
92 e6e5906b pbrook
{
93 e6e5906b pbrook
    set_op(PARAM1, get_op(PARAM2));
94 e6e5906b pbrook
    FORCE_RET();
95 e6e5906b pbrook
}
96 e6e5906b pbrook
97 e6e5906b pbrook
OP(mov32_im)
98 e6e5906b pbrook
{
99 e6e5906b pbrook
    set_op(PARAM1, PARAM2);
100 e6e5906b pbrook
    FORCE_RET();
101 e6e5906b pbrook
}
102 e6e5906b pbrook
103 e6e5906b pbrook
OP(movf64)
104 e6e5906b pbrook
{
105 e6e5906b pbrook
    set_opf64(PARAM1, get_opf64(PARAM2));
106 e6e5906b pbrook
    FORCE_RET();
107 e6e5906b pbrook
}
108 e6e5906b pbrook
109 e6e5906b pbrook
OP(zerof64)
110 e6e5906b pbrook
{
111 e6e5906b pbrook
    set_opf64(PARAM1, 0);
112 e6e5906b pbrook
    FORCE_RET();
113 e6e5906b pbrook
}
114 e6e5906b pbrook
115 e6e5906b pbrook
OP(add32)
116 e6e5906b pbrook
{
117 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
118 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
119 e6e5906b pbrook
    set_op(PARAM1, op2 + op3);
120 e6e5906b pbrook
    FORCE_RET();
121 e6e5906b pbrook
}
122 e6e5906b pbrook
123 e6e5906b pbrook
OP(sub32)
124 e6e5906b pbrook
{
125 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
126 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
127 e6e5906b pbrook
    set_op(PARAM1, op2 - op3);
128 e6e5906b pbrook
    FORCE_RET();
129 e6e5906b pbrook
}
130 e6e5906b pbrook
131 e6e5906b pbrook
OP(mul32)
132 e6e5906b pbrook
{
133 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
134 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
135 e6e5906b pbrook
    set_op(PARAM1, op2 * op3);
136 e6e5906b pbrook
    FORCE_RET();
137 e6e5906b pbrook
}
138 e6e5906b pbrook
139 e6e5906b pbrook
OP(not32)
140 e6e5906b pbrook
{
141 e6e5906b pbrook
    uint32_t arg = get_op(PARAM2);
142 e6e5906b pbrook
    set_op(PARAM1, ~arg);
143 e6e5906b pbrook
    FORCE_RET();
144 e6e5906b pbrook
}
145 e6e5906b pbrook
146 e6e5906b pbrook
OP(neg32)
147 e6e5906b pbrook
{
148 e6e5906b pbrook
    uint32_t arg = get_op(PARAM2);
149 e6e5906b pbrook
    set_op(PARAM1, -arg);
150 e6e5906b pbrook
    FORCE_RET();
151 e6e5906b pbrook
}
152 e6e5906b pbrook
153 e6e5906b pbrook
OP(bswap32)
154 e6e5906b pbrook
{
155 e6e5906b pbrook
    uint32_t arg = get_op(PARAM2);
156 e6e5906b pbrook
    arg = (arg >> 24) | (arg << 24)
157 e6e5906b pbrook
          | ((arg >> 16) & 0xff00) | ((arg << 16) & 0xff0000);
158 e6e5906b pbrook
    set_op(PARAM1, arg);
159 e6e5906b pbrook
    FORCE_RET();
160 e6e5906b pbrook
}
161 e6e5906b pbrook
162 e6e5906b pbrook
OP(btest)
163 e6e5906b pbrook
{
164 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
165 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
166 e6e5906b pbrook
    if (op1 & op2)
167 e6e5906b pbrook
        env->cc_dest &= ~CCF_Z;
168 e6e5906b pbrook
    else
169 e6e5906b pbrook
        env->cc_dest |= CCF_Z;
170 e6e5906b pbrook
    FORCE_RET();
171 e6e5906b pbrook
}
172 e6e5906b pbrook
173 821f7e76 pbrook
OP(ff1)
174 821f7e76 pbrook
{
175 821f7e76 pbrook
    uint32_t arg = get_op(PARAM2);
176 821f7e76 pbrook
    int n;
177 821f7e76 pbrook
    for (n = 32; arg; n--)
178 821f7e76 pbrook
        arg >>= 1;
179 821f7e76 pbrook
    set_op(PARAM1, n);
180 821f7e76 pbrook
    FORCE_RET();
181 821f7e76 pbrook
}
182 821f7e76 pbrook
183 8d7fe053 pbrook
OP(subx_cc)
184 e6e5906b pbrook
{
185 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
186 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
187 e6e5906b pbrook
    uint32_t res;
188 e6e5906b pbrook
    if (env->cc_x) {
189 e6e5906b pbrook
        env->cc_x = (op1 <= op2);
190 e6e5906b pbrook
        env->cc_op = CC_OP_SUBX;
191 e6e5906b pbrook
        res = op1 - (op2 + 1);
192 e6e5906b pbrook
    } else {
193 e6e5906b pbrook
        env->cc_x = (op1 < op2);
194 e6e5906b pbrook
        env->cc_op = CC_OP_SUB;
195 e6e5906b pbrook
        res = op1 - op2;
196 e6e5906b pbrook
    }
197 e6e5906b pbrook
    set_op(PARAM1, res);
198 e6e5906b pbrook
    FORCE_RET();
199 e6e5906b pbrook
}
200 e6e5906b pbrook
201 8d7fe053 pbrook
OP(addx_cc)
202 e6e5906b pbrook
{
203 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
204 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
205 e6e5906b pbrook
    uint32_t res;
206 e6e5906b pbrook
    if (env->cc_x) {
207 e6e5906b pbrook
        res = op1 + op2 + 1;
208 e6e5906b pbrook
        env->cc_x = (res <= op2);
209 e6e5906b pbrook
        env->cc_op = CC_OP_ADDX;
210 e6e5906b pbrook
    } else {
211 e6e5906b pbrook
        res = op1 + op2;
212 e6e5906b pbrook
        env->cc_x = (res < op2);
213 e6e5906b pbrook
        env->cc_op = CC_OP_ADD;
214 e6e5906b pbrook
    }
215 e6e5906b pbrook
    set_op(PARAM1, res);
216 e6e5906b pbrook
    FORCE_RET();
217 e6e5906b pbrook
}
218 e6e5906b pbrook
219 e6e5906b pbrook
/* Logic ops.  */
220 e6e5906b pbrook
221 e6e5906b pbrook
OP(and32)
222 e6e5906b pbrook
{
223 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
224 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
225 e6e5906b pbrook
    set_op(PARAM1, op2 & op3);
226 e6e5906b pbrook
    FORCE_RET();
227 e6e5906b pbrook
}
228 e6e5906b pbrook
229 e6e5906b pbrook
OP(or32)
230 e6e5906b pbrook
{
231 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
232 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
233 e6e5906b pbrook
    set_op(PARAM1, op2 | op3);
234 e6e5906b pbrook
    FORCE_RET();
235 e6e5906b pbrook
}
236 e6e5906b pbrook
237 e6e5906b pbrook
OP(xor32)
238 e6e5906b pbrook
{
239 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
240 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
241 e6e5906b pbrook
    set_op(PARAM1, op2 ^ op3);
242 e6e5906b pbrook
    FORCE_RET();
243 e6e5906b pbrook
}
244 e6e5906b pbrook
245 e6e5906b pbrook
/* Shifts.  */
246 e6e5906b pbrook
OP(shl32)
247 e6e5906b pbrook
{
248 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
249 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
250 e6e5906b pbrook
    uint32_t result;
251 e6e5906b pbrook
    result = op2 << op3;
252 e6e5906b pbrook
    set_op(PARAM1, result);
253 e6e5906b pbrook
    FORCE_RET();
254 e6e5906b pbrook
}
255 e6e5906b pbrook
256 e6e5906b pbrook
OP(shl_cc)
257 e6e5906b pbrook
{
258 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
259 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
260 e6e5906b pbrook
    uint32_t result;
261 e6e5906b pbrook
    result = op1 << op2;
262 e6e5906b pbrook
    set_op(PARAM1, result);
263 e6e5906b pbrook
    env->cc_x = (op1 << (op2 - 1)) & 1;
264 e6e5906b pbrook
    FORCE_RET();
265 e6e5906b pbrook
}
266 e6e5906b pbrook
267 e6e5906b pbrook
OP(shr32)
268 e6e5906b pbrook
{
269 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
270 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
271 e6e5906b pbrook
    uint32_t result;
272 e6e5906b pbrook
    result = op2 >> op3;
273 e6e5906b pbrook
    set_op(PARAM1, result);
274 e6e5906b pbrook
    FORCE_RET();
275 e6e5906b pbrook
}
276 e6e5906b pbrook
277 e6e5906b pbrook
OP(shr_cc)
278 e6e5906b pbrook
{
279 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
280 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
281 e6e5906b pbrook
    uint32_t result;
282 e6e5906b pbrook
    result = op1 >> op2;
283 e6e5906b pbrook
    set_op(PARAM1, result);
284 e6e5906b pbrook
    env->cc_x = (op1 >> (op2 - 1)) & 1;
285 e6e5906b pbrook
    FORCE_RET();
286 e6e5906b pbrook
}
287 e6e5906b pbrook
288 acf930aa pbrook
OP(sar32)
289 acf930aa pbrook
{
290 acf930aa pbrook
    int32_t op2 = get_op(PARAM2);
291 acf930aa pbrook
    uint32_t op3 = get_op(PARAM3);
292 acf930aa pbrook
    uint32_t result;
293 acf930aa pbrook
    result = op2 >> op3;
294 acf930aa pbrook
    set_op(PARAM1, result);
295 acf930aa pbrook
    FORCE_RET();
296 acf930aa pbrook
}
297 acf930aa pbrook
298 e6e5906b pbrook
OP(sar_cc)
299 e6e5906b pbrook
{
300 e6e5906b pbrook
    int32_t op1 = get_op(PARAM1);
301 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
302 e6e5906b pbrook
    uint32_t result;
303 e6e5906b pbrook
    result = op1 >> op2;
304 e6e5906b pbrook
    set_op(PARAM1, result);
305 e6e5906b pbrook
    env->cc_x = (op1 >> (op2 - 1)) & 1;
306 e6e5906b pbrook
    FORCE_RET();
307 e6e5906b pbrook
}
308 e6e5906b pbrook
309 e6e5906b pbrook
/* Value extend.  */
310 e6e5906b pbrook
311 e6e5906b pbrook
OP(ext8u32)
312 e6e5906b pbrook
{
313 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
314 e6e5906b pbrook
    set_op(PARAM1, (uint8_t)op2);
315 e6e5906b pbrook
    FORCE_RET();
316 e6e5906b pbrook
}
317 e6e5906b pbrook
318 e6e5906b pbrook
OP(ext8s32)
319 e6e5906b pbrook
{
320 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
321 e6e5906b pbrook
    set_op(PARAM1, (int8_t)op2);
322 e6e5906b pbrook
    FORCE_RET();
323 e6e5906b pbrook
}
324 e6e5906b pbrook
325 e6e5906b pbrook
OP(ext16u32)
326 e6e5906b pbrook
{
327 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
328 e6e5906b pbrook
    set_op(PARAM1, (uint16_t)op2);
329 e6e5906b pbrook
    FORCE_RET();
330 e6e5906b pbrook
}
331 e6e5906b pbrook
332 e6e5906b pbrook
OP(ext16s32)
333 e6e5906b pbrook
{
334 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
335 e6e5906b pbrook
    set_op(PARAM1, (int16_t)op2);
336 e6e5906b pbrook
    FORCE_RET();
337 e6e5906b pbrook
}
338 e6e5906b pbrook
339 e6e5906b pbrook
OP(flush_flags)
340 e6e5906b pbrook
{
341 0cf5c677 pbrook
    cpu_m68k_flush_flags(env, env->cc_op);
342 e6e5906b pbrook
    FORCE_RET();
343 e6e5906b pbrook
}
344 e6e5906b pbrook
345 e6e5906b pbrook
OP(divu)
346 e6e5906b pbrook
{
347 e6e5906b pbrook
    uint32_t num;
348 e6e5906b pbrook
    uint32_t den;
349 e6e5906b pbrook
    uint32_t quot;
350 e6e5906b pbrook
    uint32_t rem;
351 e6e5906b pbrook
    uint32_t flags;
352 e6e5906b pbrook
    
353 e6e5906b pbrook
    num = env->div1;
354 e6e5906b pbrook
    den = env->div2;
355 e6e5906b pbrook
    /* ??? This needs to make sure the throwing location is accurate.  */
356 e6e5906b pbrook
    if (den == 0)
357 e6e5906b pbrook
        RAISE_EXCEPTION(EXCP_DIV0);
358 e6e5906b pbrook
    quot = num / den;
359 e6e5906b pbrook
    rem = num % den;
360 e6e5906b pbrook
    flags = 0;
361 2d37be61 pbrook
    /* Avoid using a PARAM1 of zero.  This breaks dyngen because it uses
362 2d37be61 pbrook
       the address of a symbol, and gcc knows symbols can't have address
363 2d37be61 pbrook
       zero.  */
364 2d37be61 pbrook
    if (PARAM1 == 2 && quot > 0xffff)
365 e6e5906b pbrook
        flags |= CCF_V;
366 e6e5906b pbrook
    if (quot == 0)
367 e6e5906b pbrook
        flags |= CCF_Z;
368 e6e5906b pbrook
    else if ((int32_t)quot < 0)
369 e6e5906b pbrook
        flags |= CCF_N;
370 e6e5906b pbrook
    env->div1 = quot;
371 e6e5906b pbrook
    env->div2 = rem;
372 e6e5906b pbrook
    env->cc_dest = flags;
373 e6e5906b pbrook
    FORCE_RET();
374 e6e5906b pbrook
}
375 e6e5906b pbrook
376 e6e5906b pbrook
OP(divs)
377 e6e5906b pbrook
{
378 e6e5906b pbrook
    int32_t num;
379 e6e5906b pbrook
    int32_t den;
380 e6e5906b pbrook
    int32_t quot;
381 e6e5906b pbrook
    int32_t rem;
382 e6e5906b pbrook
    int32_t flags;
383 e6e5906b pbrook
    
384 e6e5906b pbrook
    num = env->div1;
385 e6e5906b pbrook
    den = env->div2;
386 e6e5906b pbrook
    if (den == 0)
387 e6e5906b pbrook
        RAISE_EXCEPTION(EXCP_DIV0);
388 e6e5906b pbrook
    quot = num / den;
389 e6e5906b pbrook
    rem = num % den;
390 e6e5906b pbrook
    flags = 0;
391 2d37be61 pbrook
    if (PARAM1 == 2 && quot != (int16_t)quot)
392 e6e5906b pbrook
        flags |= CCF_V;
393 e6e5906b pbrook
    if (quot == 0)
394 e6e5906b pbrook
        flags |= CCF_Z;
395 e6e5906b pbrook
    else if (quot < 0)
396 e6e5906b pbrook
        flags |= CCF_N;
397 e6e5906b pbrook
    env->div1 = quot;
398 e6e5906b pbrook
    env->div2 = rem;
399 e6e5906b pbrook
    env->cc_dest = flags;
400 e6e5906b pbrook
    FORCE_RET();
401 e6e5906b pbrook
}
402 e6e5906b pbrook
403 a87295e8 pbrook
/* Halt is special because it may be a semihosting call.  */
404 0633879f pbrook
OP(halt)
405 0633879f pbrook
{
406 a87295e8 pbrook
    RAISE_EXCEPTION(EXCP_HALT_INSN);
407 a87295e8 pbrook
    FORCE_RET();
408 a87295e8 pbrook
}
409 a87295e8 pbrook
410 a87295e8 pbrook
OP(stop)
411 a87295e8 pbrook
{
412 0633879f pbrook
    env->halted = 1;
413 0633879f pbrook
    RAISE_EXCEPTION(EXCP_HLT);
414 0633879f pbrook
    FORCE_RET();
415 0633879f pbrook
}
416 0633879f pbrook
417 e6e5906b pbrook
OP(raise_exception)
418 e6e5906b pbrook
{
419 e6e5906b pbrook
    RAISE_EXCEPTION(PARAM1);
420 e6e5906b pbrook
    FORCE_RET();
421 e6e5906b pbrook
}
422 e6e5906b pbrook
423 e6e5906b pbrook
/* Floating point comparison sets flags differently to other instructions.  */
424 e6e5906b pbrook
425 e6e5906b pbrook
OP(sub_cmpf64)
426 e6e5906b pbrook
{
427 e6e5906b pbrook
    float64 src0;
428 e6e5906b pbrook
    float64 src1;
429 e6e5906b pbrook
    src0 = get_opf64(PARAM2);
430 e6e5906b pbrook
    src1 = get_opf64(PARAM3);
431 e6e5906b pbrook
    set_opf64(PARAM1, helper_sub_cmpf64(env, src0, src1));
432 e6e5906b pbrook
    FORCE_RET();
433 e6e5906b pbrook
}
434 e6e5906b pbrook
435 e6e5906b pbrook
OP(update_xflag_tst)
436 e6e5906b pbrook
{
437 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
438 e6e5906b pbrook
    env->cc_x = op1;
439 e6e5906b pbrook
    FORCE_RET();
440 e6e5906b pbrook
}
441 e6e5906b pbrook
442 e6e5906b pbrook
OP(update_xflag_lt)
443 e6e5906b pbrook
{
444 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
445 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
446 e6e5906b pbrook
    env->cc_x = (op1 < op2);
447 e6e5906b pbrook
    FORCE_RET();
448 e6e5906b pbrook
}
449 e6e5906b pbrook
450 e6e5906b pbrook
OP(get_xflag)
451 e6e5906b pbrook
{
452 e6e5906b pbrook
    set_op(PARAM1, env->cc_x);
453 e6e5906b pbrook
    FORCE_RET();
454 e6e5906b pbrook
}
455 e6e5906b pbrook
456 e6e5906b pbrook
OP(logic_cc)
457 e6e5906b pbrook
{
458 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
459 e6e5906b pbrook
    env->cc_dest = op1;
460 e6e5906b pbrook
    FORCE_RET();
461 e6e5906b pbrook
}
462 e6e5906b pbrook
463 e6e5906b pbrook
OP(update_cc_add)
464 e6e5906b pbrook
{
465 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
466 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
467 e6e5906b pbrook
    env->cc_dest = op1;
468 e6e5906b pbrook
    env->cc_src = op2;
469 e6e5906b pbrook
    FORCE_RET();
470 e6e5906b pbrook
}
471 e6e5906b pbrook
472 e6e5906b pbrook
OP(fp_result)
473 e6e5906b pbrook
{
474 e6e5906b pbrook
    env->fp_result = get_opf64(PARAM1);
475 e6e5906b pbrook
    FORCE_RET();
476 e6e5906b pbrook
}
477 e6e5906b pbrook
478 20dcee94 pbrook
OP(set_sr)
479 20dcee94 pbrook
{
480 0cf5c677 pbrook
    env->sr = get_op(PARAM1) & 0xffff;
481 20dcee94 pbrook
    m68k_switch_sp(env);
482 20dcee94 pbrook
    FORCE_RET();
483 20dcee94 pbrook
}
484 20dcee94 pbrook
485 e6e5906b pbrook
OP(jmp)
486 e6e5906b pbrook
{
487 e6e5906b pbrook
    GOTO_LABEL_PARAM(1);
488 e6e5906b pbrook
}
489 e6e5906b pbrook
490 e6e5906b pbrook
/* These ops involve a function call, which probably requires a stack frame
491 e6e5906b pbrook
   and breaks things on some hosts.  */
492 e6e5906b pbrook
OP(jmp_z32)
493 e6e5906b pbrook
{
494 e6e5906b pbrook
    uint32_t arg = get_op(PARAM1);
495 e6e5906b pbrook
    if (arg == 0)
496 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
497 e6e5906b pbrook
    FORCE_RET();
498 e6e5906b pbrook
}
499 e6e5906b pbrook
500 e6e5906b pbrook
OP(jmp_nz32)
501 e6e5906b pbrook
{
502 e6e5906b pbrook
    uint32_t arg = get_op(PARAM1);
503 e6e5906b pbrook
    if (arg != 0)
504 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
505 e6e5906b pbrook
    FORCE_RET();
506 e6e5906b pbrook
}
507 e6e5906b pbrook
508 e6e5906b pbrook
OP(jmp_s32)
509 e6e5906b pbrook
{
510 e6e5906b pbrook
    int32_t arg = get_op(PARAM1);
511 e6e5906b pbrook
    if (arg < 0)
512 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
513 e6e5906b pbrook
    FORCE_RET();
514 e6e5906b pbrook
}
515 e6e5906b pbrook
516 e6e5906b pbrook
OP(jmp_ns32)
517 e6e5906b pbrook
{
518 e6e5906b pbrook
    int32_t arg = get_op(PARAM1);
519 e6e5906b pbrook
    if (arg >= 0)
520 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
521 e6e5906b pbrook
    FORCE_RET();
522 e6e5906b pbrook
}
523 e6e5906b pbrook
524 e6e5906b pbrook
void OPPROTO op_goto_tb0(void)
525 e6e5906b pbrook
{
526 e6e5906b pbrook
    GOTO_TB(op_goto_tb0, PARAM1, 0);
527 e6e5906b pbrook
}
528 e6e5906b pbrook
529 e6e5906b pbrook
void OPPROTO op_goto_tb1(void)
530 e6e5906b pbrook
{
531 e6e5906b pbrook
    GOTO_TB(op_goto_tb1, PARAM1, 1);
532 e6e5906b pbrook
}
533 e6e5906b pbrook
534 e6e5906b pbrook
OP(exit_tb)
535 e6e5906b pbrook
{
536 e6e5906b pbrook
    EXIT_TB();
537 e6e5906b pbrook
}
538 e6e5906b pbrook
539 e6e5906b pbrook
540 e6e5906b pbrook
/* Floating point.  */
541 e6e5906b pbrook
OP(f64_to_i32)
542 e6e5906b pbrook
{
543 e6e5906b pbrook
    set_op(PARAM1, float64_to_int32(get_opf64(PARAM2), &CPU_FP_STATUS));
544 e6e5906b pbrook
    FORCE_RET();
545 e6e5906b pbrook
}
546 e6e5906b pbrook
547 e6e5906b pbrook
OP(f64_to_f32)
548 e6e5906b pbrook
{
549 e6e5906b pbrook
    union {
550 e6e5906b pbrook
        float32 f;
551 e6e5906b pbrook
        uint32_t i;
552 e6e5906b pbrook
    } u;
553 e6e5906b pbrook
    u.f = float64_to_float32(get_opf64(PARAM2), &CPU_FP_STATUS);
554 e6e5906b pbrook
    set_op(PARAM1, u.i);
555 e6e5906b pbrook
    FORCE_RET();
556 e6e5906b pbrook
}
557 e6e5906b pbrook
558 e6e5906b pbrook
OP(i32_to_f64)
559 e6e5906b pbrook
{
560 e6e5906b pbrook
    set_opf64(PARAM1, int32_to_float64(get_op(PARAM2), &CPU_FP_STATUS));
561 e6e5906b pbrook
    FORCE_RET();
562 e6e5906b pbrook
}
563 e6e5906b pbrook
564 e6e5906b pbrook
OP(f32_to_f64)
565 e6e5906b pbrook
{
566 e6e5906b pbrook
    union {
567 e6e5906b pbrook
        float32 f;
568 e6e5906b pbrook
        uint32_t i;
569 e6e5906b pbrook
    } u;
570 e6e5906b pbrook
    u.i = get_op(PARAM2);
571 e6e5906b pbrook
    set_opf64(PARAM1, float32_to_float64(u.f, &CPU_FP_STATUS));
572 e6e5906b pbrook
    FORCE_RET();
573 e6e5906b pbrook
}
574 e6e5906b pbrook
575 e6e5906b pbrook
OP(absf64)
576 e6e5906b pbrook
{
577 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
578 e6e5906b pbrook
    set_opf64(PARAM1, float64_abs(op0));
579 e6e5906b pbrook
    FORCE_RET();
580 e6e5906b pbrook
}
581 e6e5906b pbrook
582 e6e5906b pbrook
OP(chsf64)
583 e6e5906b pbrook
{
584 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
585 e6e5906b pbrook
    set_opf64(PARAM1, float64_chs(op0));
586 e6e5906b pbrook
    FORCE_RET();
587 e6e5906b pbrook
}
588 e6e5906b pbrook
589 e6e5906b pbrook
OP(sqrtf64)
590 e6e5906b pbrook
{
591 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
592 e6e5906b pbrook
    set_opf64(PARAM1, float64_sqrt(op0, &CPU_FP_STATUS));
593 e6e5906b pbrook
    FORCE_RET();
594 e6e5906b pbrook
}
595 e6e5906b pbrook
596 e6e5906b pbrook
OP(addf64)
597 e6e5906b pbrook
{
598 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
599 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
600 e6e5906b pbrook
    set_opf64(PARAM1, float64_add(op0, op1, &CPU_FP_STATUS));
601 e6e5906b pbrook
    FORCE_RET();
602 e6e5906b pbrook
}
603 e6e5906b pbrook
604 e6e5906b pbrook
OP(subf64)
605 e6e5906b pbrook
{
606 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
607 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
608 e6e5906b pbrook
    set_opf64(PARAM1, float64_sub(op0, op1, &CPU_FP_STATUS));
609 e6e5906b pbrook
    FORCE_RET();
610 e6e5906b pbrook
}
611 e6e5906b pbrook
612 e6e5906b pbrook
OP(mulf64)
613 e6e5906b pbrook
{
614 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
615 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
616 e6e5906b pbrook
    set_opf64(PARAM1, float64_mul(op0, op1, &CPU_FP_STATUS));
617 e6e5906b pbrook
    FORCE_RET();
618 e6e5906b pbrook
}
619 e6e5906b pbrook
620 e6e5906b pbrook
OP(divf64)
621 e6e5906b pbrook
{
622 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
623 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
624 e6e5906b pbrook
    set_opf64(PARAM1, float64_div(op0, op1, &CPU_FP_STATUS));
625 e6e5906b pbrook
    FORCE_RET();
626 e6e5906b pbrook
}
627 e6e5906b pbrook
628 e6e5906b pbrook
OP(iround_f64)
629 e6e5906b pbrook
{
630 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
631 e6e5906b pbrook
    set_opf64(PARAM1, float64_round_to_int(op0, &CPU_FP_STATUS));
632 e6e5906b pbrook
    FORCE_RET();
633 e6e5906b pbrook
}
634 e6e5906b pbrook
635 e6e5906b pbrook
OP(itrunc_f64)
636 e6e5906b pbrook
{
637 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
638 e6e5906b pbrook
    set_opf64(PARAM1, float64_trunc_to_int(op0, &CPU_FP_STATUS));
639 e6e5906b pbrook
    FORCE_RET();
640 e6e5906b pbrook
}
641 e6e5906b pbrook
642 e6e5906b pbrook
OP(compare_quietf64)
643 e6e5906b pbrook
{
644 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
645 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
646 e6e5906b pbrook
    set_op(PARAM1, float64_compare_quiet(op0, op1, &CPU_FP_STATUS));
647 e6e5906b pbrook
    FORCE_RET();
648 e6e5906b pbrook
}
649 0633879f pbrook
650 0633879f pbrook
OP(movec)
651 0633879f pbrook
{
652 0633879f pbrook
    int op1 = get_op(PARAM1);
653 0633879f pbrook
    uint32_t op2 = get_op(PARAM2);
654 0633879f pbrook
    helper_movec(env, op1, op2);
655 0633879f pbrook
}
656 0633879f pbrook
657 0633879f pbrook
/* Memory access.  */
658 0633879f pbrook
659 0633879f pbrook
#define MEMSUFFIX _raw
660 0633879f pbrook
#include "op_mem.h"
661 0633879f pbrook
662 0633879f pbrook
#if !defined(CONFIG_USER_ONLY)
663 0633879f pbrook
#define MEMSUFFIX _user
664 0633879f pbrook
#include "op_mem.h"
665 0633879f pbrook
#define MEMSUFFIX _kernel
666 0633879f pbrook
#include "op_mem.h"
667 0633879f pbrook
#endif
668 acf930aa pbrook
669 acf930aa pbrook
/* MAC unit.  */
670 acf930aa pbrook
/* TODO: The MAC instructions use 64-bit arithmetic fairly extensively.
671 acf930aa pbrook
   This results in fairly large ops (and sometimes other issues) on 32-bit
672 acf930aa pbrook
   hosts.  Maybe move most of them into helpers.  */
673 acf930aa pbrook
OP(macmuls)
674 acf930aa pbrook
{
675 acf930aa pbrook
    uint32_t op1 = get_op(PARAM1);
676 acf930aa pbrook
    uint32_t op2 = get_op(PARAM2);
677 acf930aa pbrook
    int64_t product;
678 acf930aa pbrook
    int64_t res;
679 acf930aa pbrook
680 acf930aa pbrook
    product = (uint64_t)op1 * op2;
681 acf930aa pbrook
    res = (product << 24) >> 24;
682 acf930aa pbrook
    if (res != product) {
683 acf930aa pbrook
        env->macsr |= MACSR_V;
684 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
685 acf930aa pbrook
            /* Make sure the accumulate operation overflows.  */
686 acf930aa pbrook
            if (product < 0)
687 acf930aa pbrook
                res = ~(1ll << 50);
688 acf930aa pbrook
            else
689 acf930aa pbrook
                res = 1ll << 50;
690 acf930aa pbrook
        }
691 acf930aa pbrook
    }
692 acf930aa pbrook
    env->mactmp = res;
693 acf930aa pbrook
    FORCE_RET();
694 acf930aa pbrook
}
695 acf930aa pbrook
696 acf930aa pbrook
OP(macmulu)
697 acf930aa pbrook
{
698 acf930aa pbrook
    uint32_t op1 = get_op(PARAM1);
699 acf930aa pbrook
    uint32_t op2 = get_op(PARAM2);
700 acf930aa pbrook
    uint64_t product;
701 acf930aa pbrook
702 acf930aa pbrook
    product = (uint64_t)op1 * op2;
703 acf930aa pbrook
    if (product & (0xffffffull << 40)) {
704 acf930aa pbrook
        env->macsr |= MACSR_V;
705 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
706 acf930aa pbrook
            /* Make sure the accumulate operation overflows.  */
707 acf930aa pbrook
            product = 1ll << 50;
708 acf930aa pbrook
        } else {
709 acf930aa pbrook
            product &= ((1ull << 40) - 1);
710 acf930aa pbrook
        }
711 acf930aa pbrook
    }
712 acf930aa pbrook
    env->mactmp = product;
713 acf930aa pbrook
    FORCE_RET();
714 acf930aa pbrook
}
715 acf930aa pbrook
716 acf930aa pbrook
OP(macmulf)
717 acf930aa pbrook
{
718 acf930aa pbrook
    int32_t op1 = get_op(PARAM1);
719 acf930aa pbrook
    int32_t op2 = get_op(PARAM2);
720 acf930aa pbrook
    uint64_t product;
721 acf930aa pbrook
    uint32_t remainder;
722 acf930aa pbrook
723 acf930aa pbrook
    product = (uint64_t)op1 * op2;
724 acf930aa pbrook
    if (env->macsr & MACSR_RT) {
725 acf930aa pbrook
        remainder = product & 0xffffff;
726 acf930aa pbrook
        product >>= 24;
727 acf930aa pbrook
        if (remainder > 0x800000)
728 acf930aa pbrook
            product++;
729 acf930aa pbrook
        else if (remainder == 0x800000)
730 acf930aa pbrook
            product += (product & 1);
731 acf930aa pbrook
    } else {
732 acf930aa pbrook
        product >>= 24;
733 acf930aa pbrook
    }
734 acf930aa pbrook
    env->mactmp = product;
735 acf930aa pbrook
    FORCE_RET();
736 acf930aa pbrook
}
737 acf930aa pbrook
738 acf930aa pbrook
OP(macshl)
739 acf930aa pbrook
{
740 acf930aa pbrook
    env->mactmp <<= 1;
741 acf930aa pbrook
}
742 acf930aa pbrook
743 acf930aa pbrook
OP(macshr)
744 acf930aa pbrook
{
745 acf930aa pbrook
    env->mactmp >>= 1;
746 acf930aa pbrook
}
747 acf930aa pbrook
748 acf930aa pbrook
OP(macadd)
749 acf930aa pbrook
{
750 acf930aa pbrook
    int acc = PARAM1;
751 acf930aa pbrook
    env->macc[acc] += env->mactmp;
752 acf930aa pbrook
    FORCE_RET();
753 acf930aa pbrook
}
754 acf930aa pbrook
755 acf930aa pbrook
OP(macsub)
756 acf930aa pbrook
{
757 acf930aa pbrook
    int acc = PARAM1;
758 acf930aa pbrook
    env->macc[acc] -= env->mactmp;
759 acf930aa pbrook
    FORCE_RET();
760 acf930aa pbrook
}
761 acf930aa pbrook
762 acf930aa pbrook
OP(macsats)
763 acf930aa pbrook
{
764 acf930aa pbrook
    int acc = PARAM1;
765 acf930aa pbrook
    int64_t sum;
766 acf930aa pbrook
    int64_t result;
767 acf930aa pbrook
768 acf930aa pbrook
    sum = env->macc[acc];
769 acf930aa pbrook
    result = (sum << 16) >> 16;
770 acf930aa pbrook
    if (result != sum) {
771 acf930aa pbrook
        env->macsr |= MACSR_V;
772 acf930aa pbrook
    }
773 acf930aa pbrook
    if (env->macsr & MACSR_V) {
774 acf930aa pbrook
        env->macsr |= MACSR_PAV0 << acc;
775 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
776 acf930aa pbrook
            /* The result is saturated to 32 bits, despite overflow occuring
777 acf930aa pbrook
               at 48 bits.  Seems weird, but that's what the hardware docs
778 acf930aa pbrook
               say.  */
779 acf930aa pbrook
            result = (result >> 63) ^ 0x7fffffff;
780 acf930aa pbrook
        }
781 acf930aa pbrook
    }
782 acf930aa pbrook
    env->macc[acc] = result;
783 acf930aa pbrook
    FORCE_RET();
784 acf930aa pbrook
}
785 acf930aa pbrook
786 acf930aa pbrook
OP(macsatu)
787 acf930aa pbrook
{
788 acf930aa pbrook
    int acc = PARAM1;
789 acf930aa pbrook
    uint64_t sum;
790 acf930aa pbrook
791 acf930aa pbrook
    sum = env->macc[acc];
792 acf930aa pbrook
    if (sum & (0xffffull << 48)) {
793 acf930aa pbrook
        env->macsr |= MACSR_V;
794 acf930aa pbrook
    }
795 acf930aa pbrook
    if (env->macsr & MACSR_V) {
796 acf930aa pbrook
        env->macsr |= MACSR_PAV0 << acc;
797 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
798 acf930aa pbrook
            if (sum > (1ull << 53))
799 acf930aa pbrook
                sum = 0;
800 acf930aa pbrook
            else
801 acf930aa pbrook
                sum = (1ull << 48) - 1;
802 acf930aa pbrook
        } else {
803 acf930aa pbrook
            sum &= ((1ull << 48) - 1);
804 acf930aa pbrook
        }
805 acf930aa pbrook
    }
806 acf930aa pbrook
    FORCE_RET();
807 acf930aa pbrook
}
808 acf930aa pbrook
809 acf930aa pbrook
OP(macsatf)
810 acf930aa pbrook
{
811 acf930aa pbrook
    int acc = PARAM1;
812 acf930aa pbrook
    int64_t sum;
813 acf930aa pbrook
    int64_t result;
814 acf930aa pbrook
815 acf930aa pbrook
    sum = env->macc[acc];
816 acf930aa pbrook
    result = (sum << 16) >> 16;
817 acf930aa pbrook
    if (result != sum) {
818 acf930aa pbrook
        env->macsr |= MACSR_V;
819 acf930aa pbrook
    }
820 acf930aa pbrook
    if (env->macsr & MACSR_V) {
821 acf930aa pbrook
        env->macsr |= MACSR_PAV0 << acc;
822 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
823 acf930aa pbrook
            result = (result >> 63) ^ 0x7fffffffffffll;
824 acf930aa pbrook
        }
825 acf930aa pbrook
    }
826 acf930aa pbrook
    env->macc[acc] = result;
827 acf930aa pbrook
    FORCE_RET();
828 acf930aa pbrook
}
829 acf930aa pbrook
830 acf930aa pbrook
OP(mac_clear_flags)
831 acf930aa pbrook
{
832 acf930aa pbrook
    env->macsr &= ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV);
833 acf930aa pbrook
}
834 acf930aa pbrook
835 acf930aa pbrook
OP(mac_set_flags)
836 acf930aa pbrook
{
837 acf930aa pbrook
    int acc = PARAM1;
838 acf930aa pbrook
    uint64_t val;
839 acf930aa pbrook
    val = env->macc[acc];
840 acf930aa pbrook
    if (val == 0)
841 acf930aa pbrook
        env->macsr |= MACSR_Z;
842 acf930aa pbrook
    else if (val & (1ull << 47));
843 acf930aa pbrook
        env->macsr |= MACSR_N;
844 acf930aa pbrook
    if (env->macsr & (MACSR_PAV0 << acc)) {
845 acf930aa pbrook
        env->macsr |= MACSR_V;
846 acf930aa pbrook
    }
847 acf930aa pbrook
    if (env->macsr & MACSR_FI) {
848 acf930aa pbrook
        val = ((int64_t)val) >> 40;
849 acf930aa pbrook
        if (val != 0 && val != -1)
850 acf930aa pbrook
            env->macsr |= MACSR_EV;
851 acf930aa pbrook
    } else if (env->macsr & MACSR_SU) {
852 acf930aa pbrook
        val = ((int64_t)val) >> 32;
853 acf930aa pbrook
        if (val != 0 && val != -1)
854 acf930aa pbrook
            env->macsr |= MACSR_EV;
855 acf930aa pbrook
    } else {
856 acf930aa pbrook
        if ((val >> 32) != 0)
857 acf930aa pbrook
            env->macsr |= MACSR_EV;
858 acf930aa pbrook
    }
859 acf930aa pbrook
    FORCE_RET();
860 acf930aa pbrook
}
861 acf930aa pbrook
862 acf930aa pbrook
OP(get_macf)
863 acf930aa pbrook
{
864 acf930aa pbrook
    int acc = PARAM2;
865 acf930aa pbrook
    int64_t val;
866 acf930aa pbrook
    int rem;
867 acf930aa pbrook
    uint32_t result;
868 acf930aa pbrook
869 acf930aa pbrook
    val = env->macc[acc];
870 acf930aa pbrook
    if (env->macsr & MACSR_SU) {
871 acf930aa pbrook
        /* 16-bit rounding.  */
872 acf930aa pbrook
        rem = val & 0xffffff;
873 acf930aa pbrook
        val = (val >> 24) & 0xffffu;
874 acf930aa pbrook
        if (rem > 0x800000)
875 acf930aa pbrook
            val++;
876 acf930aa pbrook
        else if (rem == 0x800000)
877 acf930aa pbrook
            val += (val & 1);
878 acf930aa pbrook
    } else if (env->macsr & MACSR_RT) {
879 acf930aa pbrook
        /* 32-bit rounding.  */
880 acf930aa pbrook
        rem = val & 0xff;
881 acf930aa pbrook
        val >>= 8;
882 acf930aa pbrook
        if (rem > 0x80)
883 acf930aa pbrook
            val++;
884 acf930aa pbrook
        else if (rem == 0x80)
885 acf930aa pbrook
            val += (val & 1);
886 acf930aa pbrook
    } else {
887 acf930aa pbrook
        /* No rounding.  */
888 acf930aa pbrook
        val >>= 8;
889 acf930aa pbrook
    }
890 acf930aa pbrook
    if (env->macsr & MACSR_OMC) {
891 acf930aa pbrook
        /* Saturate.  */
892 acf930aa pbrook
        if (env->macsr & MACSR_SU) {
893 acf930aa pbrook
            if (val != (uint16_t) val) {
894 acf930aa pbrook
                result = ((val >> 63) ^ 0x7fff) & 0xffff;
895 acf930aa pbrook
            } else {
896 acf930aa pbrook
                result = val & 0xffff;
897 acf930aa pbrook
            }
898 acf930aa pbrook
        } else {
899 acf930aa pbrook
            if (val != (uint32_t)val) {
900 acf930aa pbrook
                result = ((uint32_t)(val >> 63) & 0x7fffffff);
901 acf930aa pbrook
            } else {
902 acf930aa pbrook
                result = (uint32_t)val;
903 acf930aa pbrook
            }
904 acf930aa pbrook
        }
905 acf930aa pbrook
    } else {
906 acf930aa pbrook
        /* No saturation.  */
907 acf930aa pbrook
        if (env->macsr & MACSR_SU) {
908 acf930aa pbrook
            result = val & 0xffff;
909 acf930aa pbrook
        } else {
910 acf930aa pbrook
            result = (uint32_t)val;
911 acf930aa pbrook
        }
912 acf930aa pbrook
    }
913 acf930aa pbrook
    set_op(PARAM1, result);
914 acf930aa pbrook
    FORCE_RET();
915 acf930aa pbrook
}
916 acf930aa pbrook
917 acf930aa pbrook
OP(get_maci)
918 acf930aa pbrook
{
919 acf930aa pbrook
    int acc = PARAM2;
920 acf930aa pbrook
    set_op(PARAM1, (uint32_t)env->macc[acc]);
921 acf930aa pbrook
    FORCE_RET();
922 acf930aa pbrook
}
923 acf930aa pbrook
924 acf930aa pbrook
OP(get_macs)
925 acf930aa pbrook
{
926 acf930aa pbrook
    int acc = PARAM2;
927 acf930aa pbrook
    int64_t val = env->macc[acc];
928 acf930aa pbrook
    uint32_t result;
929 acf930aa pbrook
    if (val == (int32_t)val) {
930 acf930aa pbrook
        result = (int32_t)val;
931 acf930aa pbrook
    } else {
932 acf930aa pbrook
        result = (val >> 61) ^ 0x7fffffff;
933 acf930aa pbrook
    }
934 acf930aa pbrook
    set_op(PARAM1, result);
935 acf930aa pbrook
    FORCE_RET();
936 acf930aa pbrook
}
937 acf930aa pbrook
938 acf930aa pbrook
OP(get_macu)
939 acf930aa pbrook
{
940 acf930aa pbrook
    int acc = PARAM2;
941 acf930aa pbrook
    uint64_t val = env->macc[acc];
942 acf930aa pbrook
    uint32_t result;
943 acf930aa pbrook
    if ((val >> 32) == 0) {
944 acf930aa pbrook
        result = (uint32_t)val;
945 acf930aa pbrook
    } else {
946 acf930aa pbrook
        result = 0xffffffffu;
947 acf930aa pbrook
    }
948 acf930aa pbrook
    set_op(PARAM1, result);
949 acf930aa pbrook
    FORCE_RET();
950 acf930aa pbrook
}
951 acf930aa pbrook
952 acf930aa pbrook
OP(clear_mac)
953 acf930aa pbrook
{
954 acf930aa pbrook
    int acc = PARAM1;
955 acf930aa pbrook
956 acf930aa pbrook
    env->macc[acc] = 0;
957 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
958 acf930aa pbrook
    FORCE_RET();
959 acf930aa pbrook
}
960 acf930aa pbrook
961 acf930aa pbrook
OP(move_mac)
962 acf930aa pbrook
{
963 acf930aa pbrook
    int dest = PARAM1;
964 acf930aa pbrook
    int src = PARAM2;
965 acf930aa pbrook
    uint32_t mask;
966 acf930aa pbrook
    env->macc[dest] = env->macc[src];
967 acf930aa pbrook
    mask = MACSR_PAV0 << dest;
968 acf930aa pbrook
    if (env->macsr & (MACSR_PAV0 << src))
969 acf930aa pbrook
        env->macsr |= mask;
970 acf930aa pbrook
    else
971 acf930aa pbrook
        env->macsr &= ~mask;
972 acf930aa pbrook
    FORCE_RET();
973 acf930aa pbrook
}
974 acf930aa pbrook
975 acf930aa pbrook
OP(get_mac_extf)
976 acf930aa pbrook
{
977 acf930aa pbrook
    uint32_t val;
978 acf930aa pbrook
    int acc = PARAM2;
979 acf930aa pbrook
    val = env->macc[acc] & 0x00ff;
980 acf930aa pbrook
    val = (env->macc[acc] >> 32) & 0xff00;
981 acf930aa pbrook
    val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
982 acf930aa pbrook
    val |= (env->macc[acc + 1] >> 16) & 0xff000000;
983 acf930aa pbrook
    set_op(PARAM1, val);
984 acf930aa pbrook
    FORCE_RET();
985 acf930aa pbrook
}
986 acf930aa pbrook
987 acf930aa pbrook
OP(get_mac_exti)
988 acf930aa pbrook
{
989 acf930aa pbrook
    uint32_t val;
990 acf930aa pbrook
    int acc = PARAM2;
991 acf930aa pbrook
    val = (env->macc[acc] >> 32) & 0xffff;
992 acf930aa pbrook
    val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
993 acf930aa pbrook
    set_op(PARAM1, val);
994 acf930aa pbrook
    FORCE_RET();
995 acf930aa pbrook
}
996 acf930aa pbrook
997 acf930aa pbrook
OP(set_macf)
998 acf930aa pbrook
{
999 acf930aa pbrook
    int acc = PARAM2;
1000 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1001 acf930aa pbrook
    env->macc[acc] = ((int64_t)val) << 8;
1002 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
1003 acf930aa pbrook
    FORCE_RET();
1004 acf930aa pbrook
}
1005 acf930aa pbrook
1006 acf930aa pbrook
OP(set_macs)
1007 acf930aa pbrook
{
1008 acf930aa pbrook
    int acc = PARAM2;
1009 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1010 acf930aa pbrook
    env->macc[acc] = val;
1011 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
1012 acf930aa pbrook
    FORCE_RET();
1013 acf930aa pbrook
}
1014 acf930aa pbrook
1015 acf930aa pbrook
OP(set_macu)
1016 acf930aa pbrook
{
1017 acf930aa pbrook
    int acc = PARAM2;
1018 acf930aa pbrook
    uint32_t val = get_op(PARAM1);
1019 acf930aa pbrook
    env->macc[acc] = val;
1020 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
1021 acf930aa pbrook
    FORCE_RET();
1022 acf930aa pbrook
}
1023 acf930aa pbrook
1024 acf930aa pbrook
OP(set_mac_extf)
1025 acf930aa pbrook
{
1026 acf930aa pbrook
    int acc = PARAM2;
1027 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1028 acf930aa pbrook
    int64_t res;
1029 acf930aa pbrook
    int32_t tmp;
1030 acf930aa pbrook
    res = env->macc[acc] & 0xffffffff00ull;
1031 acf930aa pbrook
    tmp = (int16_t)(val & 0xff00);
1032 acf930aa pbrook
    res |= ((int64_t)tmp) << 32;
1033 acf930aa pbrook
    res |= val & 0xff;
1034 acf930aa pbrook
    env->macc[acc] = res;
1035 acf930aa pbrook
    res = env->macc[acc + 1] & 0xffffffff00ull;
1036 acf930aa pbrook
    tmp = (val & 0xff000000);
1037 acf930aa pbrook
    res |= ((int64_t)tmp) << 16;
1038 acf930aa pbrook
    res |= (val >> 16) & 0xff;
1039 acf930aa pbrook
    env->macc[acc + 1] = res;
1040 acf930aa pbrook
}
1041 acf930aa pbrook
1042 acf930aa pbrook
OP(set_mac_exts)
1043 acf930aa pbrook
{
1044 acf930aa pbrook
    int acc = PARAM2;
1045 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1046 acf930aa pbrook
    int64_t res;
1047 acf930aa pbrook
    int32_t tmp;
1048 acf930aa pbrook
    res = (uint32_t)env->macc[acc];
1049 acf930aa pbrook
    tmp = (int16_t)val;
1050 acf930aa pbrook
    res |= ((int64_t)tmp) << 32;
1051 acf930aa pbrook
    env->macc[acc] = res;
1052 acf930aa pbrook
    res = (uint32_t)env->macc[acc + 1];
1053 acf930aa pbrook
    tmp = val & 0xffff0000;
1054 acf930aa pbrook
    res |= (int64_t)tmp << 16;
1055 acf930aa pbrook
    env->macc[acc + 1] = res;
1056 acf930aa pbrook
}
1057 acf930aa pbrook
1058 acf930aa pbrook
OP(set_mac_extu)
1059 acf930aa pbrook
{
1060 acf930aa pbrook
    int acc = PARAM2;
1061 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1062 acf930aa pbrook
    uint64_t res;
1063 acf930aa pbrook
    res = (uint32_t)env->macc[acc];
1064 acf930aa pbrook
    res |= ((uint64_t)(val & 0xffff)) << 32;
1065 acf930aa pbrook
    env->macc[acc] = res;
1066 acf930aa pbrook
    res = (uint32_t)env->macc[acc + 1];
1067 acf930aa pbrook
    res |= (uint64_t)(val & 0xffff0000) << 16;
1068 acf930aa pbrook
    env->macc[acc + 1] = res;
1069 acf930aa pbrook
}
1070 acf930aa pbrook
1071 acf930aa pbrook
OP(set_macsr)
1072 acf930aa pbrook
{
1073 acf930aa pbrook
    m68k_set_macsr(env, get_op(PARAM1));
1074 acf930aa pbrook
}