Statistics
| Branch: | Revision:

root / target-m68k / op.c @ ce62e5ba

History | View | Annotate | Download (20.6 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 06d92f40 pbrook
OP(set_T0_z32)
491 e6e5906b pbrook
{
492 e6e5906b pbrook
    uint32_t arg = get_op(PARAM1);
493 06d92f40 pbrook
    T0 = (arg == 0);
494 e6e5906b pbrook
    FORCE_RET();
495 e6e5906b pbrook
}
496 e6e5906b pbrook
497 06d92f40 pbrook
OP(set_T0_nz32)
498 e6e5906b pbrook
{
499 e6e5906b pbrook
    uint32_t arg = get_op(PARAM1);
500 06d92f40 pbrook
    T0 = (arg != 0);
501 e6e5906b pbrook
    FORCE_RET();
502 e6e5906b pbrook
}
503 e6e5906b pbrook
504 06d92f40 pbrook
OP(set_T0_s32)
505 e6e5906b pbrook
{
506 e6e5906b pbrook
    int32_t arg = get_op(PARAM1);
507 06d92f40 pbrook
    T0 = (arg > 0);
508 e6e5906b pbrook
    FORCE_RET();
509 e6e5906b pbrook
}
510 e6e5906b pbrook
511 06d92f40 pbrook
OP(set_T0_ns32)
512 e6e5906b pbrook
{
513 e6e5906b pbrook
    int32_t arg = get_op(PARAM1);
514 06d92f40 pbrook
    T0 = (arg >= 0);
515 06d92f40 pbrook
    FORCE_RET();
516 06d92f40 pbrook
}
517 06d92f40 pbrook
518 06d92f40 pbrook
OP(jmp_T0)
519 06d92f40 pbrook
{
520 06d92f40 pbrook
    if (T0)
521 06d92f40 pbrook
        GOTO_LABEL_PARAM(1);
522 e6e5906b pbrook
    FORCE_RET();
523 e6e5906b pbrook
}
524 e6e5906b pbrook
525 e6e5906b pbrook
void OPPROTO op_goto_tb0(void)
526 e6e5906b pbrook
{
527 e6e5906b pbrook
    GOTO_TB(op_goto_tb0, PARAM1, 0);
528 e6e5906b pbrook
}
529 e6e5906b pbrook
530 e6e5906b pbrook
void OPPROTO op_goto_tb1(void)
531 e6e5906b pbrook
{
532 e6e5906b pbrook
    GOTO_TB(op_goto_tb1, PARAM1, 1);
533 e6e5906b pbrook
}
534 e6e5906b pbrook
535 e6e5906b pbrook
OP(exit_tb)
536 e6e5906b pbrook
{
537 e6e5906b pbrook
    EXIT_TB();
538 e6e5906b pbrook
}
539 e6e5906b pbrook
540 e6e5906b pbrook
541 e6e5906b pbrook
/* Floating point.  */
542 e6e5906b pbrook
OP(f64_to_i32)
543 e6e5906b pbrook
{
544 e6e5906b pbrook
    set_op(PARAM1, float64_to_int32(get_opf64(PARAM2), &CPU_FP_STATUS));
545 e6e5906b pbrook
    FORCE_RET();
546 e6e5906b pbrook
}
547 e6e5906b pbrook
548 e6e5906b pbrook
OP(f64_to_f32)
549 e6e5906b pbrook
{
550 e6e5906b pbrook
    union {
551 e6e5906b pbrook
        float32 f;
552 e6e5906b pbrook
        uint32_t i;
553 e6e5906b pbrook
    } u;
554 e6e5906b pbrook
    u.f = float64_to_float32(get_opf64(PARAM2), &CPU_FP_STATUS);
555 e6e5906b pbrook
    set_op(PARAM1, u.i);
556 e6e5906b pbrook
    FORCE_RET();
557 e6e5906b pbrook
}
558 e6e5906b pbrook
559 e6e5906b pbrook
OP(i32_to_f64)
560 e6e5906b pbrook
{
561 e6e5906b pbrook
    set_opf64(PARAM1, int32_to_float64(get_op(PARAM2), &CPU_FP_STATUS));
562 e6e5906b pbrook
    FORCE_RET();
563 e6e5906b pbrook
}
564 e6e5906b pbrook
565 e6e5906b pbrook
OP(f32_to_f64)
566 e6e5906b pbrook
{
567 e6e5906b pbrook
    union {
568 e6e5906b pbrook
        float32 f;
569 e6e5906b pbrook
        uint32_t i;
570 e6e5906b pbrook
    } u;
571 e6e5906b pbrook
    u.i = get_op(PARAM2);
572 e6e5906b pbrook
    set_opf64(PARAM1, float32_to_float64(u.f, &CPU_FP_STATUS));
573 e6e5906b pbrook
    FORCE_RET();
574 e6e5906b pbrook
}
575 e6e5906b pbrook
576 e6e5906b pbrook
OP(absf64)
577 e6e5906b pbrook
{
578 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
579 e6e5906b pbrook
    set_opf64(PARAM1, float64_abs(op0));
580 e6e5906b pbrook
    FORCE_RET();
581 e6e5906b pbrook
}
582 e6e5906b pbrook
583 e6e5906b pbrook
OP(chsf64)
584 e6e5906b pbrook
{
585 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
586 e6e5906b pbrook
    set_opf64(PARAM1, float64_chs(op0));
587 e6e5906b pbrook
    FORCE_RET();
588 e6e5906b pbrook
}
589 e6e5906b pbrook
590 e6e5906b pbrook
OP(sqrtf64)
591 e6e5906b pbrook
{
592 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
593 e6e5906b pbrook
    set_opf64(PARAM1, float64_sqrt(op0, &CPU_FP_STATUS));
594 e6e5906b pbrook
    FORCE_RET();
595 e6e5906b pbrook
}
596 e6e5906b pbrook
597 e6e5906b pbrook
OP(addf64)
598 e6e5906b pbrook
{
599 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
600 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
601 e6e5906b pbrook
    set_opf64(PARAM1, float64_add(op0, op1, &CPU_FP_STATUS));
602 e6e5906b pbrook
    FORCE_RET();
603 e6e5906b pbrook
}
604 e6e5906b pbrook
605 e6e5906b pbrook
OP(subf64)
606 e6e5906b pbrook
{
607 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
608 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
609 e6e5906b pbrook
    set_opf64(PARAM1, float64_sub(op0, op1, &CPU_FP_STATUS));
610 e6e5906b pbrook
    FORCE_RET();
611 e6e5906b pbrook
}
612 e6e5906b pbrook
613 e6e5906b pbrook
OP(mulf64)
614 e6e5906b pbrook
{
615 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
616 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
617 e6e5906b pbrook
    set_opf64(PARAM1, float64_mul(op0, op1, &CPU_FP_STATUS));
618 e6e5906b pbrook
    FORCE_RET();
619 e6e5906b pbrook
}
620 e6e5906b pbrook
621 e6e5906b pbrook
OP(divf64)
622 e6e5906b pbrook
{
623 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
624 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
625 e6e5906b pbrook
    set_opf64(PARAM1, float64_div(op0, op1, &CPU_FP_STATUS));
626 e6e5906b pbrook
    FORCE_RET();
627 e6e5906b pbrook
}
628 e6e5906b pbrook
629 e6e5906b pbrook
OP(iround_f64)
630 e6e5906b pbrook
{
631 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
632 e6e5906b pbrook
    set_opf64(PARAM1, float64_round_to_int(op0, &CPU_FP_STATUS));
633 e6e5906b pbrook
    FORCE_RET();
634 e6e5906b pbrook
}
635 e6e5906b pbrook
636 e6e5906b pbrook
OP(itrunc_f64)
637 e6e5906b pbrook
{
638 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
639 e6e5906b pbrook
    set_opf64(PARAM1, float64_trunc_to_int(op0, &CPU_FP_STATUS));
640 e6e5906b pbrook
    FORCE_RET();
641 e6e5906b pbrook
}
642 e6e5906b pbrook
643 e6e5906b pbrook
OP(compare_quietf64)
644 e6e5906b pbrook
{
645 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
646 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
647 e6e5906b pbrook
    set_op(PARAM1, float64_compare_quiet(op0, op1, &CPU_FP_STATUS));
648 e6e5906b pbrook
    FORCE_RET();
649 e6e5906b pbrook
}
650 0633879f pbrook
651 0633879f pbrook
OP(movec)
652 0633879f pbrook
{
653 0633879f pbrook
    int op1 = get_op(PARAM1);
654 0633879f pbrook
    uint32_t op2 = get_op(PARAM2);
655 0633879f pbrook
    helper_movec(env, op1, op2);
656 0633879f pbrook
}
657 0633879f pbrook
658 0633879f pbrook
/* Memory access.  */
659 0633879f pbrook
660 0633879f pbrook
#define MEMSUFFIX _raw
661 0633879f pbrook
#include "op_mem.h"
662 0633879f pbrook
663 0633879f pbrook
#if !defined(CONFIG_USER_ONLY)
664 0633879f pbrook
#define MEMSUFFIX _user
665 0633879f pbrook
#include "op_mem.h"
666 0633879f pbrook
#define MEMSUFFIX _kernel
667 0633879f pbrook
#include "op_mem.h"
668 0633879f pbrook
#endif
669 acf930aa pbrook
670 acf930aa pbrook
/* MAC unit.  */
671 acf930aa pbrook
/* TODO: The MAC instructions use 64-bit arithmetic fairly extensively.
672 acf930aa pbrook
   This results in fairly large ops (and sometimes other issues) on 32-bit
673 acf930aa pbrook
   hosts.  Maybe move most of them into helpers.  */
674 acf930aa pbrook
OP(macmuls)
675 acf930aa pbrook
{
676 acf930aa pbrook
    uint32_t op1 = get_op(PARAM1);
677 acf930aa pbrook
    uint32_t op2 = get_op(PARAM2);
678 acf930aa pbrook
    int64_t product;
679 acf930aa pbrook
    int64_t res;
680 acf930aa pbrook
681 acf930aa pbrook
    product = (uint64_t)op1 * op2;
682 acf930aa pbrook
    res = (product << 24) >> 24;
683 acf930aa pbrook
    if (res != product) {
684 acf930aa pbrook
        env->macsr |= MACSR_V;
685 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
686 acf930aa pbrook
            /* Make sure the accumulate operation overflows.  */
687 acf930aa pbrook
            if (product < 0)
688 acf930aa pbrook
                res = ~(1ll << 50);
689 acf930aa pbrook
            else
690 acf930aa pbrook
                res = 1ll << 50;
691 acf930aa pbrook
        }
692 acf930aa pbrook
    }
693 acf930aa pbrook
    env->mactmp = res;
694 acf930aa pbrook
    FORCE_RET();
695 acf930aa pbrook
}
696 acf930aa pbrook
697 acf930aa pbrook
OP(macmulu)
698 acf930aa pbrook
{
699 acf930aa pbrook
    uint32_t op1 = get_op(PARAM1);
700 acf930aa pbrook
    uint32_t op2 = get_op(PARAM2);
701 acf930aa pbrook
    uint64_t product;
702 acf930aa pbrook
703 acf930aa pbrook
    product = (uint64_t)op1 * op2;
704 acf930aa pbrook
    if (product & (0xffffffull << 40)) {
705 acf930aa pbrook
        env->macsr |= MACSR_V;
706 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
707 acf930aa pbrook
            /* Make sure the accumulate operation overflows.  */
708 acf930aa pbrook
            product = 1ll << 50;
709 acf930aa pbrook
        } else {
710 acf930aa pbrook
            product &= ((1ull << 40) - 1);
711 acf930aa pbrook
        }
712 acf930aa pbrook
    }
713 acf930aa pbrook
    env->mactmp = product;
714 acf930aa pbrook
    FORCE_RET();
715 acf930aa pbrook
}
716 acf930aa pbrook
717 acf930aa pbrook
OP(macmulf)
718 acf930aa pbrook
{
719 acf930aa pbrook
    int32_t op1 = get_op(PARAM1);
720 acf930aa pbrook
    int32_t op2 = get_op(PARAM2);
721 acf930aa pbrook
    uint64_t product;
722 acf930aa pbrook
    uint32_t remainder;
723 acf930aa pbrook
724 acf930aa pbrook
    product = (uint64_t)op1 * op2;
725 acf930aa pbrook
    if (env->macsr & MACSR_RT) {
726 acf930aa pbrook
        remainder = product & 0xffffff;
727 acf930aa pbrook
        product >>= 24;
728 acf930aa pbrook
        if (remainder > 0x800000)
729 acf930aa pbrook
            product++;
730 acf930aa pbrook
        else if (remainder == 0x800000)
731 acf930aa pbrook
            product += (product & 1);
732 acf930aa pbrook
    } else {
733 acf930aa pbrook
        product >>= 24;
734 acf930aa pbrook
    }
735 acf930aa pbrook
    env->mactmp = product;
736 acf930aa pbrook
    FORCE_RET();
737 acf930aa pbrook
}
738 acf930aa pbrook
739 acf930aa pbrook
OP(macshl)
740 acf930aa pbrook
{
741 acf930aa pbrook
    env->mactmp <<= 1;
742 acf930aa pbrook
}
743 acf930aa pbrook
744 acf930aa pbrook
OP(macshr)
745 acf930aa pbrook
{
746 acf930aa pbrook
    env->mactmp >>= 1;
747 acf930aa pbrook
}
748 acf930aa pbrook
749 acf930aa pbrook
OP(macadd)
750 acf930aa pbrook
{
751 acf930aa pbrook
    int acc = PARAM1;
752 acf930aa pbrook
    env->macc[acc] += env->mactmp;
753 acf930aa pbrook
    FORCE_RET();
754 acf930aa pbrook
}
755 acf930aa pbrook
756 acf930aa pbrook
OP(macsub)
757 acf930aa pbrook
{
758 acf930aa pbrook
    int acc = PARAM1;
759 acf930aa pbrook
    env->macc[acc] -= env->mactmp;
760 acf930aa pbrook
    FORCE_RET();
761 acf930aa pbrook
}
762 acf930aa pbrook
763 acf930aa pbrook
OP(macsats)
764 acf930aa pbrook
{
765 acf930aa pbrook
    int acc = PARAM1;
766 acf930aa pbrook
    int64_t sum;
767 acf930aa pbrook
    int64_t result;
768 acf930aa pbrook
769 acf930aa pbrook
    sum = env->macc[acc];
770 acf930aa pbrook
    result = (sum << 16) >> 16;
771 acf930aa pbrook
    if (result != sum) {
772 acf930aa pbrook
        env->macsr |= MACSR_V;
773 acf930aa pbrook
    }
774 acf930aa pbrook
    if (env->macsr & MACSR_V) {
775 acf930aa pbrook
        env->macsr |= MACSR_PAV0 << acc;
776 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
777 acf930aa pbrook
            /* The result is saturated to 32 bits, despite overflow occuring
778 acf930aa pbrook
               at 48 bits.  Seems weird, but that's what the hardware docs
779 acf930aa pbrook
               say.  */
780 acf930aa pbrook
            result = (result >> 63) ^ 0x7fffffff;
781 acf930aa pbrook
        }
782 acf930aa pbrook
    }
783 acf930aa pbrook
    env->macc[acc] = result;
784 acf930aa pbrook
    FORCE_RET();
785 acf930aa pbrook
}
786 acf930aa pbrook
787 acf930aa pbrook
OP(macsatu)
788 acf930aa pbrook
{
789 acf930aa pbrook
    int acc = PARAM1;
790 acf930aa pbrook
    uint64_t sum;
791 acf930aa pbrook
792 acf930aa pbrook
    sum = env->macc[acc];
793 acf930aa pbrook
    if (sum & (0xffffull << 48)) {
794 acf930aa pbrook
        env->macsr |= MACSR_V;
795 acf930aa pbrook
    }
796 acf930aa pbrook
    if (env->macsr & MACSR_V) {
797 acf930aa pbrook
        env->macsr |= MACSR_PAV0 << acc;
798 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
799 acf930aa pbrook
            if (sum > (1ull << 53))
800 acf930aa pbrook
                sum = 0;
801 acf930aa pbrook
            else
802 acf930aa pbrook
                sum = (1ull << 48) - 1;
803 acf930aa pbrook
        } else {
804 acf930aa pbrook
            sum &= ((1ull << 48) - 1);
805 acf930aa pbrook
        }
806 acf930aa pbrook
    }
807 acf930aa pbrook
    FORCE_RET();
808 acf930aa pbrook
}
809 acf930aa pbrook
810 acf930aa pbrook
OP(macsatf)
811 acf930aa pbrook
{
812 acf930aa pbrook
    int acc = PARAM1;
813 acf930aa pbrook
    int64_t sum;
814 acf930aa pbrook
    int64_t result;
815 acf930aa pbrook
816 acf930aa pbrook
    sum = env->macc[acc];
817 acf930aa pbrook
    result = (sum << 16) >> 16;
818 acf930aa pbrook
    if (result != sum) {
819 acf930aa pbrook
        env->macsr |= MACSR_V;
820 acf930aa pbrook
    }
821 acf930aa pbrook
    if (env->macsr & MACSR_V) {
822 acf930aa pbrook
        env->macsr |= MACSR_PAV0 << acc;
823 acf930aa pbrook
        if (env->macsr & MACSR_OMC) {
824 acf930aa pbrook
            result = (result >> 63) ^ 0x7fffffffffffll;
825 acf930aa pbrook
        }
826 acf930aa pbrook
    }
827 acf930aa pbrook
    env->macc[acc] = result;
828 acf930aa pbrook
    FORCE_RET();
829 acf930aa pbrook
}
830 acf930aa pbrook
831 acf930aa pbrook
OP(mac_clear_flags)
832 acf930aa pbrook
{
833 acf930aa pbrook
    env->macsr &= ~(MACSR_V | MACSR_Z | MACSR_N | MACSR_EV);
834 acf930aa pbrook
}
835 acf930aa pbrook
836 acf930aa pbrook
OP(mac_set_flags)
837 acf930aa pbrook
{
838 acf930aa pbrook
    int acc = PARAM1;
839 acf930aa pbrook
    uint64_t val;
840 acf930aa pbrook
    val = env->macc[acc];
841 acf930aa pbrook
    if (val == 0)
842 acf930aa pbrook
        env->macsr |= MACSR_Z;
843 acf930aa pbrook
    else if (val & (1ull << 47));
844 acf930aa pbrook
        env->macsr |= MACSR_N;
845 acf930aa pbrook
    if (env->macsr & (MACSR_PAV0 << acc)) {
846 acf930aa pbrook
        env->macsr |= MACSR_V;
847 acf930aa pbrook
    }
848 acf930aa pbrook
    if (env->macsr & MACSR_FI) {
849 acf930aa pbrook
        val = ((int64_t)val) >> 40;
850 acf930aa pbrook
        if (val != 0 && val != -1)
851 acf930aa pbrook
            env->macsr |= MACSR_EV;
852 acf930aa pbrook
    } else if (env->macsr & MACSR_SU) {
853 acf930aa pbrook
        val = ((int64_t)val) >> 32;
854 acf930aa pbrook
        if (val != 0 && val != -1)
855 acf930aa pbrook
            env->macsr |= MACSR_EV;
856 acf930aa pbrook
    } else {
857 acf930aa pbrook
        if ((val >> 32) != 0)
858 acf930aa pbrook
            env->macsr |= MACSR_EV;
859 acf930aa pbrook
    }
860 acf930aa pbrook
    FORCE_RET();
861 acf930aa pbrook
}
862 acf930aa pbrook
863 acf930aa pbrook
OP(get_macf)
864 acf930aa pbrook
{
865 acf930aa pbrook
    int acc = PARAM2;
866 acf930aa pbrook
    int64_t val;
867 acf930aa pbrook
    int rem;
868 acf930aa pbrook
    uint32_t result;
869 acf930aa pbrook
870 acf930aa pbrook
    val = env->macc[acc];
871 acf930aa pbrook
    if (env->macsr & MACSR_SU) {
872 acf930aa pbrook
        /* 16-bit rounding.  */
873 acf930aa pbrook
        rem = val & 0xffffff;
874 acf930aa pbrook
        val = (val >> 24) & 0xffffu;
875 acf930aa pbrook
        if (rem > 0x800000)
876 acf930aa pbrook
            val++;
877 acf930aa pbrook
        else if (rem == 0x800000)
878 acf930aa pbrook
            val += (val & 1);
879 acf930aa pbrook
    } else if (env->macsr & MACSR_RT) {
880 acf930aa pbrook
        /* 32-bit rounding.  */
881 acf930aa pbrook
        rem = val & 0xff;
882 acf930aa pbrook
        val >>= 8;
883 acf930aa pbrook
        if (rem > 0x80)
884 acf930aa pbrook
            val++;
885 acf930aa pbrook
        else if (rem == 0x80)
886 acf930aa pbrook
            val += (val & 1);
887 acf930aa pbrook
    } else {
888 acf930aa pbrook
        /* No rounding.  */
889 acf930aa pbrook
        val >>= 8;
890 acf930aa pbrook
    }
891 acf930aa pbrook
    if (env->macsr & MACSR_OMC) {
892 acf930aa pbrook
        /* Saturate.  */
893 acf930aa pbrook
        if (env->macsr & MACSR_SU) {
894 acf930aa pbrook
            if (val != (uint16_t) val) {
895 acf930aa pbrook
                result = ((val >> 63) ^ 0x7fff) & 0xffff;
896 acf930aa pbrook
            } else {
897 acf930aa pbrook
                result = val & 0xffff;
898 acf930aa pbrook
            }
899 acf930aa pbrook
        } else {
900 acf930aa pbrook
            if (val != (uint32_t)val) {
901 acf930aa pbrook
                result = ((uint32_t)(val >> 63) & 0x7fffffff);
902 acf930aa pbrook
            } else {
903 acf930aa pbrook
                result = (uint32_t)val;
904 acf930aa pbrook
            }
905 acf930aa pbrook
        }
906 acf930aa pbrook
    } else {
907 acf930aa pbrook
        /* No saturation.  */
908 acf930aa pbrook
        if (env->macsr & MACSR_SU) {
909 acf930aa pbrook
            result = val & 0xffff;
910 acf930aa pbrook
        } else {
911 acf930aa pbrook
            result = (uint32_t)val;
912 acf930aa pbrook
        }
913 acf930aa pbrook
    }
914 acf930aa pbrook
    set_op(PARAM1, result);
915 acf930aa pbrook
    FORCE_RET();
916 acf930aa pbrook
}
917 acf930aa pbrook
918 acf930aa pbrook
OP(get_maci)
919 acf930aa pbrook
{
920 acf930aa pbrook
    int acc = PARAM2;
921 acf930aa pbrook
    set_op(PARAM1, (uint32_t)env->macc[acc]);
922 acf930aa pbrook
    FORCE_RET();
923 acf930aa pbrook
}
924 acf930aa pbrook
925 acf930aa pbrook
OP(get_macs)
926 acf930aa pbrook
{
927 acf930aa pbrook
    int acc = PARAM2;
928 acf930aa pbrook
    int64_t val = env->macc[acc];
929 acf930aa pbrook
    uint32_t result;
930 acf930aa pbrook
    if (val == (int32_t)val) {
931 acf930aa pbrook
        result = (int32_t)val;
932 acf930aa pbrook
    } else {
933 acf930aa pbrook
        result = (val >> 61) ^ 0x7fffffff;
934 acf930aa pbrook
    }
935 acf930aa pbrook
    set_op(PARAM1, result);
936 acf930aa pbrook
    FORCE_RET();
937 acf930aa pbrook
}
938 acf930aa pbrook
939 acf930aa pbrook
OP(get_macu)
940 acf930aa pbrook
{
941 acf930aa pbrook
    int acc = PARAM2;
942 acf930aa pbrook
    uint64_t val = env->macc[acc];
943 acf930aa pbrook
    uint32_t result;
944 acf930aa pbrook
    if ((val >> 32) == 0) {
945 acf930aa pbrook
        result = (uint32_t)val;
946 acf930aa pbrook
    } else {
947 acf930aa pbrook
        result = 0xffffffffu;
948 acf930aa pbrook
    }
949 acf930aa pbrook
    set_op(PARAM1, result);
950 acf930aa pbrook
    FORCE_RET();
951 acf930aa pbrook
}
952 acf930aa pbrook
953 acf930aa pbrook
OP(clear_mac)
954 acf930aa pbrook
{
955 acf930aa pbrook
    int acc = PARAM1;
956 acf930aa pbrook
957 acf930aa pbrook
    env->macc[acc] = 0;
958 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
959 acf930aa pbrook
    FORCE_RET();
960 acf930aa pbrook
}
961 acf930aa pbrook
962 acf930aa pbrook
OP(move_mac)
963 acf930aa pbrook
{
964 acf930aa pbrook
    int dest = PARAM1;
965 acf930aa pbrook
    int src = PARAM2;
966 acf930aa pbrook
    uint32_t mask;
967 acf930aa pbrook
    env->macc[dest] = env->macc[src];
968 acf930aa pbrook
    mask = MACSR_PAV0 << dest;
969 acf930aa pbrook
    if (env->macsr & (MACSR_PAV0 << src))
970 acf930aa pbrook
        env->macsr |= mask;
971 acf930aa pbrook
    else
972 acf930aa pbrook
        env->macsr &= ~mask;
973 acf930aa pbrook
    FORCE_RET();
974 acf930aa pbrook
}
975 acf930aa pbrook
976 acf930aa pbrook
OP(get_mac_extf)
977 acf930aa pbrook
{
978 acf930aa pbrook
    uint32_t val;
979 acf930aa pbrook
    int acc = PARAM2;
980 acf930aa pbrook
    val = env->macc[acc] & 0x00ff;
981 acf930aa pbrook
    val = (env->macc[acc] >> 32) & 0xff00;
982 acf930aa pbrook
    val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
983 acf930aa pbrook
    val |= (env->macc[acc + 1] >> 16) & 0xff000000;
984 acf930aa pbrook
    set_op(PARAM1, val);
985 acf930aa pbrook
    FORCE_RET();
986 acf930aa pbrook
}
987 acf930aa pbrook
988 acf930aa pbrook
OP(get_mac_exti)
989 acf930aa pbrook
{
990 acf930aa pbrook
    uint32_t val;
991 acf930aa pbrook
    int acc = PARAM2;
992 acf930aa pbrook
    val = (env->macc[acc] >> 32) & 0xffff;
993 acf930aa pbrook
    val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
994 acf930aa pbrook
    set_op(PARAM1, val);
995 acf930aa pbrook
    FORCE_RET();
996 acf930aa pbrook
}
997 acf930aa pbrook
998 acf930aa pbrook
OP(set_macf)
999 acf930aa pbrook
{
1000 acf930aa pbrook
    int acc = PARAM2;
1001 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1002 acf930aa pbrook
    env->macc[acc] = ((int64_t)val) << 8;
1003 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
1004 acf930aa pbrook
    FORCE_RET();
1005 acf930aa pbrook
}
1006 acf930aa pbrook
1007 acf930aa pbrook
OP(set_macs)
1008 acf930aa pbrook
{
1009 acf930aa pbrook
    int acc = PARAM2;
1010 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1011 acf930aa pbrook
    env->macc[acc] = val;
1012 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
1013 acf930aa pbrook
    FORCE_RET();
1014 acf930aa pbrook
}
1015 acf930aa pbrook
1016 acf930aa pbrook
OP(set_macu)
1017 acf930aa pbrook
{
1018 acf930aa pbrook
    int acc = PARAM2;
1019 acf930aa pbrook
    uint32_t val = get_op(PARAM1);
1020 acf930aa pbrook
    env->macc[acc] = val;
1021 acf930aa pbrook
    env->macsr &= ~(MACSR_PAV0 << acc);
1022 acf930aa pbrook
    FORCE_RET();
1023 acf930aa pbrook
}
1024 acf930aa pbrook
1025 acf930aa pbrook
OP(set_mac_extf)
1026 acf930aa pbrook
{
1027 acf930aa pbrook
    int acc = PARAM2;
1028 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1029 acf930aa pbrook
    int64_t res;
1030 acf930aa pbrook
    int32_t tmp;
1031 acf930aa pbrook
    res = env->macc[acc] & 0xffffffff00ull;
1032 acf930aa pbrook
    tmp = (int16_t)(val & 0xff00);
1033 acf930aa pbrook
    res |= ((int64_t)tmp) << 32;
1034 acf930aa pbrook
    res |= val & 0xff;
1035 acf930aa pbrook
    env->macc[acc] = res;
1036 acf930aa pbrook
    res = env->macc[acc + 1] & 0xffffffff00ull;
1037 acf930aa pbrook
    tmp = (val & 0xff000000);
1038 acf930aa pbrook
    res |= ((int64_t)tmp) << 16;
1039 acf930aa pbrook
    res |= (val >> 16) & 0xff;
1040 acf930aa pbrook
    env->macc[acc + 1] = res;
1041 acf930aa pbrook
}
1042 acf930aa pbrook
1043 acf930aa pbrook
OP(set_mac_exts)
1044 acf930aa pbrook
{
1045 acf930aa pbrook
    int acc = PARAM2;
1046 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1047 acf930aa pbrook
    int64_t res;
1048 acf930aa pbrook
    int32_t tmp;
1049 acf930aa pbrook
    res = (uint32_t)env->macc[acc];
1050 acf930aa pbrook
    tmp = (int16_t)val;
1051 acf930aa pbrook
    res |= ((int64_t)tmp) << 32;
1052 acf930aa pbrook
    env->macc[acc] = res;
1053 acf930aa pbrook
    res = (uint32_t)env->macc[acc + 1];
1054 acf930aa pbrook
    tmp = val & 0xffff0000;
1055 acf930aa pbrook
    res |= (int64_t)tmp << 16;
1056 acf930aa pbrook
    env->macc[acc + 1] = res;
1057 acf930aa pbrook
}
1058 acf930aa pbrook
1059 acf930aa pbrook
OP(set_mac_extu)
1060 acf930aa pbrook
{
1061 acf930aa pbrook
    int acc = PARAM2;
1062 acf930aa pbrook
    int32_t val = get_op(PARAM1);
1063 acf930aa pbrook
    uint64_t res;
1064 acf930aa pbrook
    res = (uint32_t)env->macc[acc];
1065 acf930aa pbrook
    res |= ((uint64_t)(val & 0xffff)) << 32;
1066 acf930aa pbrook
    env->macc[acc] = res;
1067 acf930aa pbrook
    res = (uint32_t)env->macc[acc + 1];
1068 acf930aa pbrook
    res |= (uint64_t)(val & 0xffff0000) << 16;
1069 acf930aa pbrook
    env->macc[acc + 1] = res;
1070 acf930aa pbrook
}
1071 acf930aa pbrook
1072 acf930aa pbrook
OP(set_macsr)
1073 acf930aa pbrook
{
1074 acf930aa pbrook
    m68k_set_macsr(env, get_op(PARAM1));
1075 acf930aa pbrook
}