Statistics
| Branch: | Revision:

root / target-m68k / op.c @ 86cc1ce0

History | View | Annotate | Download (12.3 kB)

1 e6e5906b pbrook
/*
2 e6e5906b pbrook
 *  m68k micro operations
3 e6e5906b pbrook
 * 
4 e6e5906b pbrook
 *  Copyright (c) 2006 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 e6e5906b pbrook
    if (qreg == QREG_T0) {
52 e6e5906b pbrook
        return T0;
53 e6e5906b pbrook
    } else if (qreg < TARGET_NUM_QREGS) {
54 e6e5906b pbrook
        return *(uint32_t *)(((long)env) + qreg_offsets[qreg]);
55 e6e5906b pbrook
    } else {
56 e6e5906b pbrook
        return env->qregs[qreg - TARGET_NUM_QREGS];
57 e6e5906b pbrook
    }
58 e6e5906b pbrook
}
59 e6e5906b pbrook
60 e6e5906b pbrook
void set_op(int qreg, uint32_t val)
61 e6e5906b pbrook
{
62 e6e5906b pbrook
    if (qreg == QREG_T0) {
63 e6e5906b pbrook
        T0 = val;
64 e6e5906b pbrook
    } else if (qreg < TARGET_NUM_QREGS) {
65 e6e5906b pbrook
        *(uint32_t *)(((long)env) + qreg_offsets[qreg]) = val;
66 e6e5906b pbrook
    } else {
67 e6e5906b pbrook
        env->qregs[qreg - TARGET_NUM_QREGS] = 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 e6e5906b pbrook
#define OP(name) void OPPROTO 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 e6e5906b pbrook
OP(addx_cc)
174 e6e5906b pbrook
{
175 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
176 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
177 e6e5906b pbrook
    uint32_t res;
178 e6e5906b pbrook
    if (env->cc_x) {
179 e6e5906b pbrook
        env->cc_x = (op1 <= op2);
180 e6e5906b pbrook
        env->cc_op = CC_OP_SUBX;
181 e6e5906b pbrook
        res = op1 - (op2 + 1);
182 e6e5906b pbrook
    } else {
183 e6e5906b pbrook
        env->cc_x = (op1 < op2);
184 e6e5906b pbrook
        env->cc_op = CC_OP_SUB;
185 e6e5906b pbrook
        res = op1 - op2;
186 e6e5906b pbrook
    }
187 e6e5906b pbrook
    set_op(PARAM1, res);
188 e6e5906b pbrook
    FORCE_RET();
189 e6e5906b pbrook
}
190 e6e5906b pbrook
191 e6e5906b pbrook
OP(subx_cc)
192 e6e5906b pbrook
{
193 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
194 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
195 e6e5906b pbrook
    uint32_t res;
196 e6e5906b pbrook
    if (env->cc_x) {
197 e6e5906b pbrook
        res = op1 + op2 + 1;
198 e6e5906b pbrook
        env->cc_x = (res <= op2);
199 e6e5906b pbrook
        env->cc_op = CC_OP_ADDX;
200 e6e5906b pbrook
    } else {
201 e6e5906b pbrook
        res = op1 + op2;
202 e6e5906b pbrook
        env->cc_x = (res < op2);
203 e6e5906b pbrook
        env->cc_op = CC_OP_ADD;
204 e6e5906b pbrook
    }
205 e6e5906b pbrook
    set_op(PARAM1, res);
206 e6e5906b pbrook
    FORCE_RET();
207 e6e5906b pbrook
}
208 e6e5906b pbrook
209 e6e5906b pbrook
/* Logic ops.  */
210 e6e5906b pbrook
211 e6e5906b pbrook
OP(and32)
212 e6e5906b pbrook
{
213 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
214 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
215 e6e5906b pbrook
    set_op(PARAM1, op2 & op3);
216 e6e5906b pbrook
    FORCE_RET();
217 e6e5906b pbrook
}
218 e6e5906b pbrook
219 e6e5906b pbrook
OP(or32)
220 e6e5906b pbrook
{
221 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
222 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
223 e6e5906b pbrook
    set_op(PARAM1, op2 | op3);
224 e6e5906b pbrook
    FORCE_RET();
225 e6e5906b pbrook
}
226 e6e5906b pbrook
227 e6e5906b pbrook
OP(xor32)
228 e6e5906b pbrook
{
229 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
230 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
231 e6e5906b pbrook
    set_op(PARAM1, op2 ^ op3);
232 e6e5906b pbrook
    FORCE_RET();
233 e6e5906b pbrook
}
234 e6e5906b pbrook
235 e6e5906b pbrook
/* Shifts.  */
236 e6e5906b pbrook
OP(shl32)
237 e6e5906b pbrook
{
238 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
239 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
240 e6e5906b pbrook
    uint32_t result;
241 e6e5906b pbrook
    result = op2 << op3;
242 e6e5906b pbrook
    set_op(PARAM1, result);
243 e6e5906b pbrook
    FORCE_RET();
244 e6e5906b pbrook
}
245 e6e5906b pbrook
246 e6e5906b pbrook
OP(shl_cc)
247 e6e5906b pbrook
{
248 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
249 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
250 e6e5906b pbrook
    uint32_t result;
251 e6e5906b pbrook
    result = op1 << op2;
252 e6e5906b pbrook
    set_op(PARAM1, result);
253 e6e5906b pbrook
    env->cc_x = (op1 << (op2 - 1)) & 1;
254 e6e5906b pbrook
    FORCE_RET();
255 e6e5906b pbrook
}
256 e6e5906b pbrook
257 e6e5906b pbrook
OP(shr32)
258 e6e5906b pbrook
{
259 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
260 e6e5906b pbrook
    uint32_t op3 = get_op(PARAM3);
261 e6e5906b pbrook
    uint32_t result;
262 e6e5906b pbrook
    result = op2 >> op3;
263 e6e5906b pbrook
    set_op(PARAM1, result);
264 e6e5906b pbrook
    FORCE_RET();
265 e6e5906b pbrook
}
266 e6e5906b pbrook
267 e6e5906b pbrook
OP(shr_cc)
268 e6e5906b pbrook
{
269 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
270 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
271 e6e5906b pbrook
    uint32_t result;
272 e6e5906b pbrook
    result = op1 >> op2;
273 e6e5906b pbrook
    set_op(PARAM1, result);
274 e6e5906b pbrook
    env->cc_x = (op1 >> (op2 - 1)) & 1;
275 e6e5906b pbrook
    FORCE_RET();
276 e6e5906b pbrook
}
277 e6e5906b pbrook
278 e6e5906b pbrook
OP(sar_cc)
279 e6e5906b pbrook
{
280 e6e5906b pbrook
    int32_t op1 = get_op(PARAM1);
281 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
282 e6e5906b pbrook
    uint32_t result;
283 e6e5906b pbrook
    result = op1 >> op2;
284 e6e5906b pbrook
    set_op(PARAM1, result);
285 e6e5906b pbrook
    env->cc_x = (op1 >> (op2 - 1)) & 1;
286 e6e5906b pbrook
    FORCE_RET();
287 e6e5906b pbrook
}
288 e6e5906b pbrook
289 e6e5906b pbrook
/* Value extend.  */
290 e6e5906b pbrook
291 e6e5906b pbrook
OP(ext8u32)
292 e6e5906b pbrook
{
293 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
294 e6e5906b pbrook
    set_op(PARAM1, (uint8_t)op2);
295 e6e5906b pbrook
    FORCE_RET();
296 e6e5906b pbrook
}
297 e6e5906b pbrook
298 e6e5906b pbrook
OP(ext8s32)
299 e6e5906b pbrook
{
300 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
301 e6e5906b pbrook
    set_op(PARAM1, (int8_t)op2);
302 e6e5906b pbrook
    FORCE_RET();
303 e6e5906b pbrook
}
304 e6e5906b pbrook
305 e6e5906b pbrook
OP(ext16u32)
306 e6e5906b pbrook
{
307 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
308 e6e5906b pbrook
    set_op(PARAM1, (uint16_t)op2);
309 e6e5906b pbrook
    FORCE_RET();
310 e6e5906b pbrook
}
311 e6e5906b pbrook
312 e6e5906b pbrook
OP(ext16s32)
313 e6e5906b pbrook
{
314 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
315 e6e5906b pbrook
    set_op(PARAM1, (int16_t)op2);
316 e6e5906b pbrook
    FORCE_RET();
317 e6e5906b pbrook
}
318 e6e5906b pbrook
319 e6e5906b pbrook
/* Load/store ops.  */
320 e6e5906b pbrook
OP(ld8u32)
321 e6e5906b pbrook
{
322 e6e5906b pbrook
    uint32_t addr = get_op(PARAM2);
323 e6e5906b pbrook
    set_op(PARAM1, ldub(addr));
324 e6e5906b pbrook
    FORCE_RET();
325 e6e5906b pbrook
}
326 e6e5906b pbrook
327 e6e5906b pbrook
OP(ld8s32)
328 e6e5906b pbrook
{
329 e6e5906b pbrook
    uint32_t addr = get_op(PARAM2);
330 e6e5906b pbrook
    set_op(PARAM1, ldsb(addr));
331 e6e5906b pbrook
    FORCE_RET();
332 e6e5906b pbrook
}
333 e6e5906b pbrook
334 e6e5906b pbrook
OP(ld16u32)
335 e6e5906b pbrook
{
336 e6e5906b pbrook
    uint32_t addr = get_op(PARAM2);
337 e6e5906b pbrook
    set_op(PARAM1, lduw(addr));
338 e6e5906b pbrook
    FORCE_RET();
339 e6e5906b pbrook
}
340 e6e5906b pbrook
341 e6e5906b pbrook
OP(ld16s32)
342 e6e5906b pbrook
{
343 e6e5906b pbrook
    uint32_t addr = get_op(PARAM2);
344 e6e5906b pbrook
    set_op(PARAM1, ldsw(addr));
345 e6e5906b pbrook
    FORCE_RET();
346 e6e5906b pbrook
}
347 e6e5906b pbrook
348 e6e5906b pbrook
OP(ld32)
349 e6e5906b pbrook
{
350 e6e5906b pbrook
    uint32_t addr = get_op(PARAM2);
351 e6e5906b pbrook
    set_op(PARAM1, ldl(addr));
352 e6e5906b pbrook
    FORCE_RET();
353 e6e5906b pbrook
}
354 e6e5906b pbrook
355 e6e5906b pbrook
OP(st8)
356 e6e5906b pbrook
{
357 e6e5906b pbrook
    uint32_t addr = get_op(PARAM1);
358 e6e5906b pbrook
    stb(addr, get_op(PARAM2));
359 e6e5906b pbrook
    FORCE_RET();
360 e6e5906b pbrook
}
361 e6e5906b pbrook
362 e6e5906b pbrook
OP(st16)
363 e6e5906b pbrook
{
364 e6e5906b pbrook
    uint32_t addr = get_op(PARAM1);
365 e6e5906b pbrook
    stw(addr, get_op(PARAM2));
366 e6e5906b pbrook
    FORCE_RET();
367 e6e5906b pbrook
}
368 e6e5906b pbrook
369 e6e5906b pbrook
OP(st32)
370 e6e5906b pbrook
{
371 e6e5906b pbrook
    uint32_t addr = get_op(PARAM1);
372 e6e5906b pbrook
    stl(addr, get_op(PARAM2));
373 e6e5906b pbrook
    FORCE_RET();
374 e6e5906b pbrook
}
375 e6e5906b pbrook
376 e6e5906b pbrook
OP(ldf64)
377 e6e5906b pbrook
{
378 e6e5906b pbrook
    uint32_t addr = get_op(PARAM2);
379 e6e5906b pbrook
    set_opf64(PARAM1, ldfq(addr));
380 e6e5906b pbrook
    FORCE_RET();
381 e6e5906b pbrook
}
382 e6e5906b pbrook
383 e6e5906b pbrook
OP(stf64)
384 e6e5906b pbrook
{
385 e6e5906b pbrook
    uint32_t addr = get_op(PARAM1);
386 e6e5906b pbrook
    stfq(addr, get_opf64(PARAM2));
387 e6e5906b pbrook
    FORCE_RET();
388 e6e5906b pbrook
}
389 e6e5906b pbrook
390 e6e5906b pbrook
OP(flush_flags)
391 e6e5906b pbrook
{
392 e6e5906b pbrook
    int cc_op  = PARAM1;
393 e6e5906b pbrook
    if (cc_op == CC_OP_DYNAMIC)
394 e6e5906b pbrook
        cc_op = env->cc_op;
395 e6e5906b pbrook
    cpu_m68k_flush_flags(env, cc_op);
396 e6e5906b pbrook
    FORCE_RET();
397 e6e5906b pbrook
}
398 e6e5906b pbrook
399 e6e5906b pbrook
OP(divu)
400 e6e5906b pbrook
{
401 e6e5906b pbrook
    uint32_t num;
402 e6e5906b pbrook
    uint32_t den;
403 e6e5906b pbrook
    uint32_t quot;
404 e6e5906b pbrook
    uint32_t rem;
405 e6e5906b pbrook
    uint32_t flags;
406 e6e5906b pbrook
    
407 e6e5906b pbrook
    num = env->div1;
408 e6e5906b pbrook
    den = env->div2;
409 e6e5906b pbrook
    /* ??? This needs to make sure the throwing location is accurate.  */
410 e6e5906b pbrook
    if (den == 0)
411 e6e5906b pbrook
        RAISE_EXCEPTION(EXCP_DIV0);
412 e6e5906b pbrook
    quot = num / den;
413 e6e5906b pbrook
    rem = num % den;
414 e6e5906b pbrook
    flags = 0;
415 2d37be61 pbrook
    /* Avoid using a PARAM1 of zero.  This breaks dyngen because it uses
416 2d37be61 pbrook
       the address of a symbol, and gcc knows symbols can't have address
417 2d37be61 pbrook
       zero.  */
418 2d37be61 pbrook
    if (PARAM1 == 2 && quot > 0xffff)
419 e6e5906b pbrook
        flags |= CCF_V;
420 e6e5906b pbrook
    if (quot == 0)
421 e6e5906b pbrook
        flags |= CCF_Z;
422 e6e5906b pbrook
    else if ((int32_t)quot < 0)
423 e6e5906b pbrook
        flags |= CCF_N;
424 e6e5906b pbrook
    env->div1 = quot;
425 e6e5906b pbrook
    env->div2 = rem;
426 e6e5906b pbrook
    env->cc_dest = flags;
427 e6e5906b pbrook
    FORCE_RET();
428 e6e5906b pbrook
}
429 e6e5906b pbrook
430 e6e5906b pbrook
OP(divs)
431 e6e5906b pbrook
{
432 e6e5906b pbrook
    int32_t num;
433 e6e5906b pbrook
    int32_t den;
434 e6e5906b pbrook
    int32_t quot;
435 e6e5906b pbrook
    int32_t rem;
436 e6e5906b pbrook
    int32_t flags;
437 e6e5906b pbrook
    
438 e6e5906b pbrook
    num = env->div1;
439 e6e5906b pbrook
    den = env->div2;
440 e6e5906b pbrook
    if (den == 0)
441 e6e5906b pbrook
        RAISE_EXCEPTION(EXCP_DIV0);
442 e6e5906b pbrook
    quot = num / den;
443 e6e5906b pbrook
    rem = num % den;
444 e6e5906b pbrook
    flags = 0;
445 2d37be61 pbrook
    if (PARAM1 == 2 && quot != (int16_t)quot)
446 e6e5906b pbrook
        flags |= CCF_V;
447 e6e5906b pbrook
    if (quot == 0)
448 e6e5906b pbrook
        flags |= CCF_Z;
449 e6e5906b pbrook
    else if (quot < 0)
450 e6e5906b pbrook
        flags |= CCF_N;
451 e6e5906b pbrook
    env->div1 = quot;
452 e6e5906b pbrook
    env->div2 = rem;
453 e6e5906b pbrook
    env->cc_dest = flags;
454 e6e5906b pbrook
    FORCE_RET();
455 e6e5906b pbrook
}
456 e6e5906b pbrook
457 e6e5906b pbrook
OP(raise_exception)
458 e6e5906b pbrook
{
459 e6e5906b pbrook
    RAISE_EXCEPTION(PARAM1);
460 e6e5906b pbrook
    FORCE_RET();
461 e6e5906b pbrook
}
462 e6e5906b pbrook
463 e6e5906b pbrook
/* Floating point comparison sets flags differently to other instructions.  */
464 e6e5906b pbrook
465 e6e5906b pbrook
OP(sub_cmpf64)
466 e6e5906b pbrook
{
467 e6e5906b pbrook
    float64 src0;
468 e6e5906b pbrook
    float64 src1;
469 e6e5906b pbrook
    src0 = get_opf64(PARAM2);
470 e6e5906b pbrook
    src1 = get_opf64(PARAM3);
471 e6e5906b pbrook
    set_opf64(PARAM1, helper_sub_cmpf64(env, src0, src1));
472 e6e5906b pbrook
    FORCE_RET();
473 e6e5906b pbrook
}
474 e6e5906b pbrook
475 e6e5906b pbrook
OP(update_xflag_tst)
476 e6e5906b pbrook
{
477 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
478 e6e5906b pbrook
    env->cc_x = op1;
479 e6e5906b pbrook
    FORCE_RET();
480 e6e5906b pbrook
}
481 e6e5906b pbrook
482 e6e5906b pbrook
OP(update_xflag_lt)
483 e6e5906b pbrook
{
484 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
485 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
486 e6e5906b pbrook
    env->cc_x = (op1 < op2);
487 e6e5906b pbrook
    FORCE_RET();
488 e6e5906b pbrook
}
489 e6e5906b pbrook
490 e6e5906b pbrook
OP(get_xflag)
491 e6e5906b pbrook
{
492 e6e5906b pbrook
    set_op(PARAM1, env->cc_x);
493 e6e5906b pbrook
    FORCE_RET();
494 e6e5906b pbrook
}
495 e6e5906b pbrook
496 e6e5906b pbrook
OP(logic_cc)
497 e6e5906b pbrook
{
498 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
499 e6e5906b pbrook
    env->cc_dest = op1;
500 e6e5906b pbrook
    FORCE_RET();
501 e6e5906b pbrook
}
502 e6e5906b pbrook
503 e6e5906b pbrook
OP(update_cc_add)
504 e6e5906b pbrook
{
505 e6e5906b pbrook
    uint32_t op1 = get_op(PARAM1);
506 e6e5906b pbrook
    uint32_t op2 = get_op(PARAM2);
507 e6e5906b pbrook
    env->cc_dest = op1;
508 e6e5906b pbrook
    env->cc_src = op2;
509 e6e5906b pbrook
    FORCE_RET();
510 e6e5906b pbrook
}
511 e6e5906b pbrook
512 e6e5906b pbrook
OP(fp_result)
513 e6e5906b pbrook
{
514 e6e5906b pbrook
    env->fp_result = get_opf64(PARAM1);
515 e6e5906b pbrook
    FORCE_RET();
516 e6e5906b pbrook
}
517 e6e5906b pbrook
518 e6e5906b pbrook
OP(jmp)
519 e6e5906b pbrook
{
520 e6e5906b pbrook
    GOTO_LABEL_PARAM(1);
521 e6e5906b pbrook
}
522 e6e5906b pbrook
523 e6e5906b pbrook
/* These ops involve a function call, which probably requires a stack frame
524 e6e5906b pbrook
   and breaks things on some hosts.  */
525 e6e5906b pbrook
OP(jmp_z32)
526 e6e5906b pbrook
{
527 e6e5906b pbrook
    uint32_t arg = get_op(PARAM1);
528 e6e5906b pbrook
    if (arg == 0)
529 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
530 e6e5906b pbrook
    FORCE_RET();
531 e6e5906b pbrook
}
532 e6e5906b pbrook
533 e6e5906b pbrook
OP(jmp_nz32)
534 e6e5906b pbrook
{
535 e6e5906b pbrook
    uint32_t arg = get_op(PARAM1);
536 e6e5906b pbrook
    if (arg != 0)
537 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
538 e6e5906b pbrook
    FORCE_RET();
539 e6e5906b pbrook
}
540 e6e5906b pbrook
541 e6e5906b pbrook
OP(jmp_s32)
542 e6e5906b pbrook
{
543 e6e5906b pbrook
    int32_t arg = get_op(PARAM1);
544 e6e5906b pbrook
    if (arg < 0)
545 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
546 e6e5906b pbrook
    FORCE_RET();
547 e6e5906b pbrook
}
548 e6e5906b pbrook
549 e6e5906b pbrook
OP(jmp_ns32)
550 e6e5906b pbrook
{
551 e6e5906b pbrook
    int32_t arg = get_op(PARAM1);
552 e6e5906b pbrook
    if (arg >= 0)
553 e6e5906b pbrook
        GOTO_LABEL_PARAM(2);
554 e6e5906b pbrook
    FORCE_RET();
555 e6e5906b pbrook
}
556 e6e5906b pbrook
557 e6e5906b pbrook
void OPPROTO op_goto_tb0(void)
558 e6e5906b pbrook
{
559 e6e5906b pbrook
    GOTO_TB(op_goto_tb0, PARAM1, 0);
560 e6e5906b pbrook
}
561 e6e5906b pbrook
562 e6e5906b pbrook
void OPPROTO op_goto_tb1(void)
563 e6e5906b pbrook
{
564 e6e5906b pbrook
    GOTO_TB(op_goto_tb1, PARAM1, 1);
565 e6e5906b pbrook
}
566 e6e5906b pbrook
567 e6e5906b pbrook
OP(exit_tb)
568 e6e5906b pbrook
{
569 e6e5906b pbrook
    EXIT_TB();
570 e6e5906b pbrook
}
571 e6e5906b pbrook
572 e6e5906b pbrook
573 e6e5906b pbrook
/* Floating point.  */
574 e6e5906b pbrook
OP(f64_to_i32)
575 e6e5906b pbrook
{
576 e6e5906b pbrook
    set_op(PARAM1, float64_to_int32(get_opf64(PARAM2), &CPU_FP_STATUS));
577 e6e5906b pbrook
    FORCE_RET();
578 e6e5906b pbrook
}
579 e6e5906b pbrook
580 e6e5906b pbrook
OP(f64_to_f32)
581 e6e5906b pbrook
{
582 e6e5906b pbrook
    union {
583 e6e5906b pbrook
        float32 f;
584 e6e5906b pbrook
        uint32_t i;
585 e6e5906b pbrook
    } u;
586 e6e5906b pbrook
    u.f = float64_to_float32(get_opf64(PARAM2), &CPU_FP_STATUS);
587 e6e5906b pbrook
    set_op(PARAM1, u.i);
588 e6e5906b pbrook
    FORCE_RET();
589 e6e5906b pbrook
}
590 e6e5906b pbrook
591 e6e5906b pbrook
OP(i32_to_f64)
592 e6e5906b pbrook
{
593 e6e5906b pbrook
    set_opf64(PARAM1, int32_to_float64(get_op(PARAM2), &CPU_FP_STATUS));
594 e6e5906b pbrook
    FORCE_RET();
595 e6e5906b pbrook
}
596 e6e5906b pbrook
597 e6e5906b pbrook
OP(f32_to_f64)
598 e6e5906b pbrook
{
599 e6e5906b pbrook
    union {
600 e6e5906b pbrook
        float32 f;
601 e6e5906b pbrook
        uint32_t i;
602 e6e5906b pbrook
    } u;
603 e6e5906b pbrook
    u.i = get_op(PARAM2);
604 e6e5906b pbrook
    set_opf64(PARAM1, float32_to_float64(u.f, &CPU_FP_STATUS));
605 e6e5906b pbrook
    FORCE_RET();
606 e6e5906b pbrook
}
607 e6e5906b pbrook
608 e6e5906b pbrook
OP(absf64)
609 e6e5906b pbrook
{
610 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
611 e6e5906b pbrook
    set_opf64(PARAM1, float64_abs(op0));
612 e6e5906b pbrook
    FORCE_RET();
613 e6e5906b pbrook
}
614 e6e5906b pbrook
615 e6e5906b pbrook
OP(chsf64)
616 e6e5906b pbrook
{
617 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
618 e6e5906b pbrook
    set_opf64(PARAM1, float64_chs(op0));
619 e6e5906b pbrook
    FORCE_RET();
620 e6e5906b pbrook
}
621 e6e5906b pbrook
622 e6e5906b pbrook
OP(sqrtf64)
623 e6e5906b pbrook
{
624 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
625 e6e5906b pbrook
    set_opf64(PARAM1, float64_sqrt(op0, &CPU_FP_STATUS));
626 e6e5906b pbrook
    FORCE_RET();
627 e6e5906b pbrook
}
628 e6e5906b pbrook
629 e6e5906b pbrook
OP(addf64)
630 e6e5906b pbrook
{
631 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
632 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
633 e6e5906b pbrook
    set_opf64(PARAM1, float64_add(op0, op1, &CPU_FP_STATUS));
634 e6e5906b pbrook
    FORCE_RET();
635 e6e5906b pbrook
}
636 e6e5906b pbrook
637 e6e5906b pbrook
OP(subf64)
638 e6e5906b pbrook
{
639 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
640 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
641 e6e5906b pbrook
    set_opf64(PARAM1, float64_sub(op0, op1, &CPU_FP_STATUS));
642 e6e5906b pbrook
    FORCE_RET();
643 e6e5906b pbrook
}
644 e6e5906b pbrook
645 e6e5906b pbrook
OP(mulf64)
646 e6e5906b pbrook
{
647 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
648 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
649 e6e5906b pbrook
    set_opf64(PARAM1, float64_mul(op0, op1, &CPU_FP_STATUS));
650 e6e5906b pbrook
    FORCE_RET();
651 e6e5906b pbrook
}
652 e6e5906b pbrook
653 e6e5906b pbrook
OP(divf64)
654 e6e5906b pbrook
{
655 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
656 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
657 e6e5906b pbrook
    set_opf64(PARAM1, float64_div(op0, op1, &CPU_FP_STATUS));
658 e6e5906b pbrook
    FORCE_RET();
659 e6e5906b pbrook
}
660 e6e5906b pbrook
661 e6e5906b pbrook
OP(iround_f64)
662 e6e5906b pbrook
{
663 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
664 e6e5906b pbrook
    set_opf64(PARAM1, float64_round_to_int(op0, &CPU_FP_STATUS));
665 e6e5906b pbrook
    FORCE_RET();
666 e6e5906b pbrook
}
667 e6e5906b pbrook
668 e6e5906b pbrook
OP(itrunc_f64)
669 e6e5906b pbrook
{
670 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
671 e6e5906b pbrook
    set_opf64(PARAM1, float64_trunc_to_int(op0, &CPU_FP_STATUS));
672 e6e5906b pbrook
    FORCE_RET();
673 e6e5906b pbrook
}
674 e6e5906b pbrook
675 e6e5906b pbrook
OP(compare_quietf64)
676 e6e5906b pbrook
{
677 e6e5906b pbrook
    float64 op0 = get_opf64(PARAM2);
678 e6e5906b pbrook
    float64 op1 = get_opf64(PARAM3);
679 e6e5906b pbrook
    set_op(PARAM1, float64_compare_quiet(op0, op1, &CPU_FP_STATUS));
680 e6e5906b pbrook
    FORCE_RET();
681 e6e5906b pbrook
}