Statistics
| Branch: | Revision:

root / target-mips / op.c @ 3e382bc8

History | View | Annotate | Download (23.1 kB)

1 6af0bf9c bellard
/*
2 6af0bf9c bellard
 *  MIPS emulation micro-operations for qemu.
3 6af0bf9c bellard
 * 
4 6af0bf9c bellard
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5 6ea83fed bellard
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6 6af0bf9c bellard
 *
7 6af0bf9c bellard
 * This library is free software; you can redistribute it and/or
8 6af0bf9c bellard
 * modify it under the terms of the GNU Lesser General Public
9 6af0bf9c bellard
 * License as published by the Free Software Foundation; either
10 6af0bf9c bellard
 * version 2 of the License, or (at your option) any later version.
11 6af0bf9c bellard
 *
12 6af0bf9c bellard
 * This library is distributed in the hope that it will be useful,
13 6af0bf9c bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 6af0bf9c bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 6af0bf9c bellard
 * Lesser General Public License for more details.
16 6af0bf9c bellard
 *
17 6af0bf9c bellard
 * You should have received a copy of the GNU Lesser General Public
18 6af0bf9c bellard
 * License along with this library; if not, write to the Free Software
19 6af0bf9c bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 6af0bf9c bellard
 */
21 6af0bf9c bellard
22 6af0bf9c bellard
#include "config.h"
23 6af0bf9c bellard
#include "exec.h"
24 6af0bf9c bellard
25 1b351e52 bellard
#ifndef CALL_FROM_TB0
26 1b351e52 bellard
#define CALL_FROM_TB0(func) func();
27 1b351e52 bellard
#endif
28 1b351e52 bellard
#ifndef CALL_FROM_TB1
29 1b351e52 bellard
#define CALL_FROM_TB1(func, arg0) func(arg0);
30 1b351e52 bellard
#endif
31 1b351e52 bellard
#ifndef CALL_FROM_TB1_CONST16
32 1b351e52 bellard
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0);
33 1b351e52 bellard
#endif
34 1b351e52 bellard
#ifndef CALL_FROM_TB2
35 1b351e52 bellard
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1);
36 1b351e52 bellard
#endif
37 1b351e52 bellard
#ifndef CALL_FROM_TB2_CONST16
38 1b351e52 bellard
#define CALL_FROM_TB2_CONST16(func, arg0, arg1)     \
39 1b351e52 bellard
CALL_FROM_TB2(func, arg0, arg1);
40 1b351e52 bellard
#endif
41 1b351e52 bellard
#ifndef CALL_FROM_TB3
42 1b351e52 bellard
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2);
43 1b351e52 bellard
#endif
44 1b351e52 bellard
#ifndef CALL_FROM_TB4
45 1b351e52 bellard
#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
46 1b351e52 bellard
        func(arg0, arg1, arg2, arg3);
47 1b351e52 bellard
#endif
48 1b351e52 bellard
49 6af0bf9c bellard
#define REG 1
50 6af0bf9c bellard
#include "op_template.c"
51 6af0bf9c bellard
#undef REG
52 6af0bf9c bellard
#define REG 2
53 6af0bf9c bellard
#include "op_template.c"
54 6af0bf9c bellard
#undef REG
55 6af0bf9c bellard
#define REG 3
56 6af0bf9c bellard
#include "op_template.c"
57 6af0bf9c bellard
#undef REG
58 6af0bf9c bellard
#define REG 4
59 6af0bf9c bellard
#include "op_template.c"
60 6af0bf9c bellard
#undef REG
61 6af0bf9c bellard
#define REG 5
62 6af0bf9c bellard
#include "op_template.c"
63 6af0bf9c bellard
#undef REG
64 6af0bf9c bellard
#define REG 6
65 6af0bf9c bellard
#include "op_template.c"
66 6af0bf9c bellard
#undef REG
67 6af0bf9c bellard
#define REG 7
68 6af0bf9c bellard
#include "op_template.c"
69 6af0bf9c bellard
#undef REG
70 6af0bf9c bellard
#define REG 8
71 6af0bf9c bellard
#include "op_template.c"
72 6af0bf9c bellard
#undef REG
73 6af0bf9c bellard
#define REG 9
74 6af0bf9c bellard
#include "op_template.c"
75 6af0bf9c bellard
#undef REG
76 6af0bf9c bellard
#define REG 10
77 6af0bf9c bellard
#include "op_template.c"
78 6af0bf9c bellard
#undef REG
79 6af0bf9c bellard
#define REG 11
80 6af0bf9c bellard
#include "op_template.c"
81 6af0bf9c bellard
#undef REG
82 6af0bf9c bellard
#define REG 12
83 6af0bf9c bellard
#include "op_template.c"
84 6af0bf9c bellard
#undef REG
85 6af0bf9c bellard
#define REG 13
86 6af0bf9c bellard
#include "op_template.c"
87 6af0bf9c bellard
#undef REG
88 6af0bf9c bellard
#define REG 14
89 6af0bf9c bellard
#include "op_template.c"
90 6af0bf9c bellard
#undef REG
91 6af0bf9c bellard
#define REG 15
92 6af0bf9c bellard
#include "op_template.c"
93 6af0bf9c bellard
#undef REG
94 6af0bf9c bellard
#define REG 16
95 6af0bf9c bellard
#include "op_template.c"
96 6af0bf9c bellard
#undef REG
97 6af0bf9c bellard
#define REG 17
98 6af0bf9c bellard
#include "op_template.c"
99 6af0bf9c bellard
#undef REG
100 6af0bf9c bellard
#define REG 18
101 6af0bf9c bellard
#include "op_template.c"
102 6af0bf9c bellard
#undef REG
103 6af0bf9c bellard
#define REG 19
104 6af0bf9c bellard
#include "op_template.c"
105 6af0bf9c bellard
#undef REG
106 6af0bf9c bellard
#define REG 20
107 6af0bf9c bellard
#include "op_template.c"
108 6af0bf9c bellard
#undef REG
109 6af0bf9c bellard
#define REG 21
110 6af0bf9c bellard
#include "op_template.c"
111 6af0bf9c bellard
#undef REG
112 6af0bf9c bellard
#define REG 22
113 6af0bf9c bellard
#include "op_template.c"
114 6af0bf9c bellard
#undef REG
115 6af0bf9c bellard
#define REG 23
116 6af0bf9c bellard
#include "op_template.c"
117 6af0bf9c bellard
#undef REG
118 6af0bf9c bellard
#define REG 24
119 6af0bf9c bellard
#include "op_template.c"
120 6af0bf9c bellard
#undef REG
121 6af0bf9c bellard
#define REG 25
122 6af0bf9c bellard
#include "op_template.c"
123 6af0bf9c bellard
#undef REG
124 6af0bf9c bellard
#define REG 26
125 6af0bf9c bellard
#include "op_template.c"
126 6af0bf9c bellard
#undef REG
127 6af0bf9c bellard
#define REG 27
128 6af0bf9c bellard
#include "op_template.c"
129 6af0bf9c bellard
#undef REG
130 6af0bf9c bellard
#define REG 28
131 6af0bf9c bellard
#include "op_template.c"
132 6af0bf9c bellard
#undef REG
133 6af0bf9c bellard
#define REG 29
134 6af0bf9c bellard
#include "op_template.c"
135 6af0bf9c bellard
#undef REG
136 6af0bf9c bellard
#define REG 30
137 6af0bf9c bellard
#include "op_template.c"
138 6af0bf9c bellard
#undef REG
139 6af0bf9c bellard
#define REG 31
140 6af0bf9c bellard
#include "op_template.c"
141 6af0bf9c bellard
#undef REG
142 6af0bf9c bellard
143 6af0bf9c bellard
#define TN T0
144 6af0bf9c bellard
#include "op_template.c"
145 6af0bf9c bellard
#undef TN
146 6af0bf9c bellard
#define TN T1
147 6af0bf9c bellard
#include "op_template.c"
148 6af0bf9c bellard
#undef TN
149 6af0bf9c bellard
#define TN T2
150 6af0bf9c bellard
#include "op_template.c"
151 6af0bf9c bellard
#undef TN
152 6af0bf9c bellard
153 6ea83fed bellard
#ifdef MIPS_USES_FPU
154 6ea83fed bellard
155 6ea83fed bellard
#define SFREG 0
156 6ea83fed bellard
#define DFREG 0
157 6ea83fed bellard
#include "fop_template.c"
158 6ea83fed bellard
#undef SFREG
159 6ea83fed bellard
#undef DFREG
160 6ea83fed bellard
#define SFREG 1
161 6ea83fed bellard
#include "fop_template.c"
162 6ea83fed bellard
#undef SFREG
163 6ea83fed bellard
#define SFREG 2
164 6ea83fed bellard
#define DFREG 2
165 6ea83fed bellard
#include "fop_template.c"
166 6ea83fed bellard
#undef SFREG
167 6ea83fed bellard
#undef DFREG
168 6ea83fed bellard
#define SFREG 3
169 6ea83fed bellard
#include "fop_template.c"
170 6ea83fed bellard
#undef SFREG
171 6ea83fed bellard
#define SFREG 4
172 6ea83fed bellard
#define DFREG 4
173 6ea83fed bellard
#include "fop_template.c"
174 6ea83fed bellard
#undef SFREG
175 6ea83fed bellard
#undef DFREG
176 6ea83fed bellard
#define SFREG 5
177 6ea83fed bellard
#include "fop_template.c"
178 6ea83fed bellard
#undef SFREG
179 6ea83fed bellard
#define SFREG 6
180 6ea83fed bellard
#define DFREG 6
181 6ea83fed bellard
#include "fop_template.c"
182 6ea83fed bellard
#undef SFREG
183 6ea83fed bellard
#undef DFREG
184 6ea83fed bellard
#define SFREG 7
185 6ea83fed bellard
#include "fop_template.c"
186 6ea83fed bellard
#undef SFREG
187 6ea83fed bellard
#define SFREG 8
188 6ea83fed bellard
#define DFREG 8
189 6ea83fed bellard
#include "fop_template.c"
190 6ea83fed bellard
#undef SFREG
191 6ea83fed bellard
#undef DFREG
192 6ea83fed bellard
#define SFREG 9
193 6ea83fed bellard
#include "fop_template.c"
194 6ea83fed bellard
#undef SFREG
195 6ea83fed bellard
#define SFREG 10
196 6ea83fed bellard
#define DFREG 10
197 6ea83fed bellard
#include "fop_template.c"
198 6ea83fed bellard
#undef SFREG
199 6ea83fed bellard
#undef DFREG
200 6ea83fed bellard
#define SFREG 11
201 6ea83fed bellard
#include "fop_template.c"
202 6ea83fed bellard
#undef SFREG
203 6ea83fed bellard
#define SFREG 12
204 6ea83fed bellard
#define DFREG 12
205 6ea83fed bellard
#include "fop_template.c"
206 6ea83fed bellard
#undef SFREG
207 6ea83fed bellard
#undef DFREG
208 6ea83fed bellard
#define SFREG 13
209 6ea83fed bellard
#include "fop_template.c"
210 6ea83fed bellard
#undef SFREG
211 6ea83fed bellard
#define SFREG 14
212 6ea83fed bellard
#define DFREG 14
213 6ea83fed bellard
#include "fop_template.c"
214 6ea83fed bellard
#undef SFREG
215 6ea83fed bellard
#undef DFREG
216 6ea83fed bellard
#define SFREG 15
217 6ea83fed bellard
#include "fop_template.c"
218 6ea83fed bellard
#undef SFREG
219 6ea83fed bellard
#define SFREG 16
220 6ea83fed bellard
#define DFREG 16
221 6ea83fed bellard
#include "fop_template.c"
222 6ea83fed bellard
#undef SFREG
223 6ea83fed bellard
#undef DFREG
224 6ea83fed bellard
#define SFREG 17
225 6ea83fed bellard
#include "fop_template.c"
226 6ea83fed bellard
#undef SFREG
227 6ea83fed bellard
#define SFREG 18
228 6ea83fed bellard
#define DFREG 18
229 6ea83fed bellard
#include "fop_template.c"
230 6ea83fed bellard
#undef SFREG
231 6ea83fed bellard
#undef DFREG
232 6ea83fed bellard
#define SFREG 19
233 6ea83fed bellard
#include "fop_template.c"
234 6ea83fed bellard
#undef SFREG
235 6ea83fed bellard
#define SFREG 20
236 6ea83fed bellard
#define DFREG 20
237 6ea83fed bellard
#include "fop_template.c"
238 6ea83fed bellard
#undef SFREG
239 6ea83fed bellard
#undef DFREG
240 6ea83fed bellard
#define SFREG 21
241 6ea83fed bellard
#include "fop_template.c"
242 6ea83fed bellard
#undef SFREG
243 6ea83fed bellard
#define SFREG 22
244 6ea83fed bellard
#define DFREG 22
245 6ea83fed bellard
#include "fop_template.c"
246 6ea83fed bellard
#undef SFREG
247 6ea83fed bellard
#undef DFREG
248 6ea83fed bellard
#define SFREG 23
249 6ea83fed bellard
#include "fop_template.c"
250 6ea83fed bellard
#undef SFREG
251 6ea83fed bellard
#define SFREG 24
252 6ea83fed bellard
#define DFREG 24
253 6ea83fed bellard
#include "fop_template.c"
254 6ea83fed bellard
#undef SFREG
255 6ea83fed bellard
#undef DFREG
256 6ea83fed bellard
#define SFREG 25
257 6ea83fed bellard
#include "fop_template.c"
258 6ea83fed bellard
#undef SFREG
259 6ea83fed bellard
#define SFREG 26
260 6ea83fed bellard
#define DFREG 26
261 6ea83fed bellard
#include "fop_template.c"
262 6ea83fed bellard
#undef SFREG
263 6ea83fed bellard
#undef DFREG
264 6ea83fed bellard
#define SFREG 27
265 6ea83fed bellard
#include "fop_template.c"
266 6ea83fed bellard
#undef SFREG
267 6ea83fed bellard
#define SFREG 28
268 6ea83fed bellard
#define DFREG 28
269 6ea83fed bellard
#include "fop_template.c"
270 6ea83fed bellard
#undef SFREG
271 6ea83fed bellard
#undef DFREG
272 6ea83fed bellard
#define SFREG 29
273 6ea83fed bellard
#include "fop_template.c"
274 6ea83fed bellard
#undef SFREG
275 6ea83fed bellard
#define SFREG 30
276 6ea83fed bellard
#define DFREG 30
277 6ea83fed bellard
#include "fop_template.c"
278 6ea83fed bellard
#undef SFREG
279 6ea83fed bellard
#undef DFREG
280 6ea83fed bellard
#define SFREG 31
281 6ea83fed bellard
#include "fop_template.c"
282 6ea83fed bellard
#undef SFREG
283 6ea83fed bellard
284 6ea83fed bellard
#define FTN
285 6ea83fed bellard
#include "fop_template.c"
286 6ea83fed bellard
#undef FTN
287 6ea83fed bellard
288 6ea83fed bellard
#endif
289 6ea83fed bellard
290 6af0bf9c bellard
void op_dup_T0 (void)
291 6af0bf9c bellard
{
292 6af0bf9c bellard
    T2 = T0;
293 6af0bf9c bellard
    RETURN();
294 6af0bf9c bellard
}
295 6af0bf9c bellard
296 6af0bf9c bellard
void op_load_HI (void)
297 6af0bf9c bellard
{
298 6af0bf9c bellard
    T0 = env->HI;
299 6af0bf9c bellard
    RETURN();
300 6af0bf9c bellard
}
301 6af0bf9c bellard
302 6af0bf9c bellard
void op_store_HI (void)
303 6af0bf9c bellard
{
304 6af0bf9c bellard
    env->HI = T0;
305 6af0bf9c bellard
    RETURN();
306 6af0bf9c bellard
}
307 6af0bf9c bellard
308 6af0bf9c bellard
void op_load_LO (void)
309 6af0bf9c bellard
{
310 6af0bf9c bellard
    T0 = env->LO;
311 6af0bf9c bellard
    RETURN();
312 6af0bf9c bellard
}
313 6af0bf9c bellard
314 6af0bf9c bellard
void op_store_LO (void)
315 6af0bf9c bellard
{
316 6af0bf9c bellard
    env->LO = T0;
317 6af0bf9c bellard
    RETURN();
318 6af0bf9c bellard
}
319 6af0bf9c bellard
320 6af0bf9c bellard
/* Load and store */
321 6af0bf9c bellard
#define MEMSUFFIX _raw
322 6af0bf9c bellard
#include "op_mem.c"
323 6af0bf9c bellard
#undef MEMSUFFIX
324 6af0bf9c bellard
#if !defined(CONFIG_USER_ONLY)
325 6af0bf9c bellard
#define MEMSUFFIX _user
326 6af0bf9c bellard
#include "op_mem.c"
327 6af0bf9c bellard
#undef MEMSUFFIX
328 6af0bf9c bellard
329 6af0bf9c bellard
#define MEMSUFFIX _kernel
330 6af0bf9c bellard
#include "op_mem.c"
331 6af0bf9c bellard
#undef MEMSUFFIX
332 6af0bf9c bellard
#endif
333 6af0bf9c bellard
334 6af0bf9c bellard
/* Arithmetic */
335 6af0bf9c bellard
void op_add (void)
336 6af0bf9c bellard
{
337 6af0bf9c bellard
    T0 += T1;
338 6af0bf9c bellard
    RETURN();
339 6af0bf9c bellard
}
340 6af0bf9c bellard
341 6af0bf9c bellard
void op_addo (void)
342 6af0bf9c bellard
{
343 6af0bf9c bellard
    target_ulong tmp;
344 6af0bf9c bellard
345 6af0bf9c bellard
    tmp = T0;
346 6af0bf9c bellard
    T0 += T1;
347 76e050c2 bellard
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
348 76e050c2 bellard
       /* operands of same sign, result different sign */
349 4ad40f36 bellard
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
350 6af0bf9c bellard
    }
351 6af0bf9c bellard
    RETURN();
352 6af0bf9c bellard
}
353 6af0bf9c bellard
354 6af0bf9c bellard
void op_sub (void)
355 6af0bf9c bellard
{
356 6af0bf9c bellard
    T0 -= T1;
357 6af0bf9c bellard
    RETURN();
358 6af0bf9c bellard
}
359 6af0bf9c bellard
360 6af0bf9c bellard
void op_subo (void)
361 6af0bf9c bellard
{
362 6af0bf9c bellard
    target_ulong tmp;
363 6af0bf9c bellard
364 6af0bf9c bellard
    tmp = T0;
365 6af0bf9c bellard
    T0 = (int32_t)T0 - (int32_t)T1;
366 76e050c2 bellard
    if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
367 76e050c2 bellard
       /* operands of different sign, first operand and result different sign */
368 4ad40f36 bellard
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
369 6af0bf9c bellard
    }
370 6af0bf9c bellard
    RETURN();
371 6af0bf9c bellard
}
372 6af0bf9c bellard
373 6af0bf9c bellard
void op_mul (void)
374 6af0bf9c bellard
{
375 6af0bf9c bellard
    T0 = (int32_t)T0 * (int32_t)T1;
376 6af0bf9c bellard
    RETURN();
377 6af0bf9c bellard
}
378 6af0bf9c bellard
379 6af0bf9c bellard
void op_div (void)
380 6af0bf9c bellard
{
381 6af0bf9c bellard
    if (T1 != 0) {
382 6af0bf9c bellard
        env->LO = (int32_t)T0 / (int32_t)T1;
383 6af0bf9c bellard
        env->HI = (int32_t)T0 % (int32_t)T1;
384 6af0bf9c bellard
    }
385 6af0bf9c bellard
    RETURN();
386 6af0bf9c bellard
}
387 6af0bf9c bellard
388 6af0bf9c bellard
void op_divu (void)
389 6af0bf9c bellard
{
390 6af0bf9c bellard
    if (T1 != 0) {
391 6af0bf9c bellard
        env->LO = T0 / T1;
392 6af0bf9c bellard
        env->HI = T0 % T1;
393 6af0bf9c bellard
    }
394 6af0bf9c bellard
    RETURN();
395 6af0bf9c bellard
}
396 6af0bf9c bellard
397 6af0bf9c bellard
/* Logical */
398 6af0bf9c bellard
void op_and (void)
399 6af0bf9c bellard
{
400 6af0bf9c bellard
    T0 &= T1;
401 6af0bf9c bellard
    RETURN();
402 6af0bf9c bellard
}
403 6af0bf9c bellard
404 6af0bf9c bellard
void op_nor (void)
405 6af0bf9c bellard
{
406 6af0bf9c bellard
    T0 = ~(T0 | T1);
407 6af0bf9c bellard
    RETURN();
408 6af0bf9c bellard
}
409 6af0bf9c bellard
410 6af0bf9c bellard
void op_or (void)
411 6af0bf9c bellard
{
412 6af0bf9c bellard
    T0 |= T1;
413 6af0bf9c bellard
    RETURN();
414 6af0bf9c bellard
}
415 6af0bf9c bellard
416 6af0bf9c bellard
void op_xor (void)
417 6af0bf9c bellard
{
418 6af0bf9c bellard
    T0 ^= T1;
419 6af0bf9c bellard
    RETURN();
420 6af0bf9c bellard
}
421 6af0bf9c bellard
422 6af0bf9c bellard
void op_sll (void)
423 6af0bf9c bellard
{
424 6af0bf9c bellard
    T0 = T0 << T1;
425 6af0bf9c bellard
    RETURN();
426 6af0bf9c bellard
}
427 6af0bf9c bellard
428 6af0bf9c bellard
void op_sra (void)
429 6af0bf9c bellard
{
430 6af0bf9c bellard
    T0 = (int32_t)T0 >> T1;
431 6af0bf9c bellard
    RETURN();
432 6af0bf9c bellard
}
433 6af0bf9c bellard
434 6af0bf9c bellard
void op_srl (void)
435 6af0bf9c bellard
{
436 6af0bf9c bellard
    T0 = T0 >> T1;
437 6af0bf9c bellard
    RETURN();
438 6af0bf9c bellard
}
439 6af0bf9c bellard
440 6af0bf9c bellard
void op_sllv (void)
441 6af0bf9c bellard
{
442 6af0bf9c bellard
    T0 = T1 << (T0 & 0x1F);
443 6af0bf9c bellard
    RETURN();
444 6af0bf9c bellard
}
445 6af0bf9c bellard
446 6af0bf9c bellard
void op_srav (void)
447 6af0bf9c bellard
{
448 6af0bf9c bellard
    T0 = (int32_t)T1 >> (T0 & 0x1F);
449 6af0bf9c bellard
    RETURN();
450 6af0bf9c bellard
}
451 6af0bf9c bellard
452 6af0bf9c bellard
void op_srlv (void)
453 6af0bf9c bellard
{
454 6af0bf9c bellard
    T0 = T1 >> (T0 & 0x1F);
455 6af0bf9c bellard
    RETURN();
456 6af0bf9c bellard
}
457 6af0bf9c bellard
458 6af0bf9c bellard
void op_clo (void)
459 6af0bf9c bellard
{
460 6af0bf9c bellard
    int n;
461 6af0bf9c bellard
462 6af0bf9c bellard
    if (T0 == (target_ulong)-1) {
463 6af0bf9c bellard
        T0 = 32;
464 6af0bf9c bellard
    } else {
465 6af0bf9c bellard
        for (n = 0; n < 32; n++) {
466 6af0bf9c bellard
            if (!(T0 & (1 << 31)))
467 6af0bf9c bellard
                break;
468 6af0bf9c bellard
            T0 = T0 << 1;
469 6af0bf9c bellard
        }
470 6af0bf9c bellard
        T0 = n;
471 6af0bf9c bellard
    }
472 6af0bf9c bellard
    RETURN();
473 6af0bf9c bellard
}
474 6af0bf9c bellard
475 6af0bf9c bellard
void op_clz (void)
476 6af0bf9c bellard
{
477 6af0bf9c bellard
    int n;
478 6af0bf9c bellard
479 6af0bf9c bellard
    if (T0 == 0) {
480 6af0bf9c bellard
        T0 = 32;
481 6af0bf9c bellard
    } else {
482 6af0bf9c bellard
        for (n = 0; n < 32; n++) {
483 6af0bf9c bellard
            if (T0 & (1 << 31))
484 6af0bf9c bellard
                break;
485 6af0bf9c bellard
            T0 = T0 << 1;
486 6af0bf9c bellard
        }
487 6af0bf9c bellard
        T0 = n;
488 6af0bf9c bellard
    }
489 6af0bf9c bellard
    RETURN();
490 6af0bf9c bellard
}
491 6af0bf9c bellard
492 6af0bf9c bellard
/* 64 bits arithmetic */
493 6af0bf9c bellard
#if (HOST_LONG_BITS == 64)
494 6af0bf9c bellard
static inline uint64_t get_HILO (void)
495 6af0bf9c bellard
{
496 6af0bf9c bellard
    return ((uint64_t)env->HI << 32) | (uint64_t)env->LO;
497 6af0bf9c bellard
}
498 6af0bf9c bellard
499 6af0bf9c bellard
static inline void set_HILO (uint64_t HILO)
500 6af0bf9c bellard
{
501 6af0bf9c bellard
    env->LO = HILO & 0xFFFFFFFF;
502 6af0bf9c bellard
    env->HI = HILO >> 32;
503 6af0bf9c bellard
}
504 6af0bf9c bellard
505 6af0bf9c bellard
void op_mult (void)
506 6af0bf9c bellard
{
507 4ad40f36 bellard
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
508 6af0bf9c bellard
    RETURN();
509 6af0bf9c bellard
}
510 6af0bf9c bellard
511 6af0bf9c bellard
void op_multu (void)
512 6af0bf9c bellard
{
513 6af0bf9c bellard
    set_HILO((uint64_t)T0 * (uint64_t)T1);
514 6af0bf9c bellard
    RETURN();
515 6af0bf9c bellard
}
516 6af0bf9c bellard
517 6af0bf9c bellard
void op_madd (void)
518 6af0bf9c bellard
{
519 6af0bf9c bellard
    int64_t tmp;
520 6af0bf9c bellard
521 4ad40f36 bellard
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
522 6af0bf9c bellard
    set_HILO((int64_t)get_HILO() + tmp);
523 6af0bf9c bellard
    RETURN();
524 6af0bf9c bellard
}
525 6af0bf9c bellard
526 6af0bf9c bellard
void op_maddu (void)
527 6af0bf9c bellard
{
528 6af0bf9c bellard
    uint64_t tmp;
529 6af0bf9c bellard
530 6af0bf9c bellard
    tmp = ((uint64_t)T0 * (uint64_t)T1);
531 6af0bf9c bellard
    set_HILO(get_HILO() + tmp);
532 6af0bf9c bellard
    RETURN();
533 6af0bf9c bellard
}
534 6af0bf9c bellard
535 6af0bf9c bellard
void op_msub (void)
536 6af0bf9c bellard
{
537 6af0bf9c bellard
    int64_t tmp;
538 6af0bf9c bellard
539 4ad40f36 bellard
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
540 6af0bf9c bellard
    set_HILO((int64_t)get_HILO() - tmp);
541 6af0bf9c bellard
    RETURN();
542 6af0bf9c bellard
}
543 6af0bf9c bellard
544 6af0bf9c bellard
void op_msubu (void)
545 6af0bf9c bellard
{
546 6af0bf9c bellard
    uint64_t tmp;
547 6af0bf9c bellard
548 6af0bf9c bellard
    tmp = ((uint64_t)T0 * (uint64_t)T1);
549 6af0bf9c bellard
    set_HILO(get_HILO() - tmp);
550 6af0bf9c bellard
    RETURN();
551 6af0bf9c bellard
}
552 6af0bf9c bellard
#else
553 6af0bf9c bellard
void op_mult (void)
554 6af0bf9c bellard
{
555 6af0bf9c bellard
    CALL_FROM_TB0(do_mult);
556 6af0bf9c bellard
    RETURN();
557 6af0bf9c bellard
}
558 6af0bf9c bellard
559 6af0bf9c bellard
void op_multu (void)
560 6af0bf9c bellard
{
561 6af0bf9c bellard
    CALL_FROM_TB0(do_multu);
562 6af0bf9c bellard
    RETURN();
563 6af0bf9c bellard
}
564 6af0bf9c bellard
565 6af0bf9c bellard
void op_madd (void)
566 6af0bf9c bellard
{
567 6af0bf9c bellard
    CALL_FROM_TB0(do_madd);
568 6af0bf9c bellard
    RETURN();
569 6af0bf9c bellard
}
570 6af0bf9c bellard
571 6af0bf9c bellard
void op_maddu (void)
572 6af0bf9c bellard
{
573 6af0bf9c bellard
    CALL_FROM_TB0(do_maddu);
574 6af0bf9c bellard
    RETURN();
575 6af0bf9c bellard
}
576 6af0bf9c bellard
577 6af0bf9c bellard
void op_msub (void)
578 6af0bf9c bellard
{
579 6af0bf9c bellard
    CALL_FROM_TB0(do_msub);
580 6af0bf9c bellard
    RETURN();
581 6af0bf9c bellard
}
582 6af0bf9c bellard
583 6af0bf9c bellard
void op_msubu (void)
584 6af0bf9c bellard
{
585 6af0bf9c bellard
    CALL_FROM_TB0(do_msubu);
586 6af0bf9c bellard
    RETURN();
587 6af0bf9c bellard
}
588 6af0bf9c bellard
#endif
589 6af0bf9c bellard
590 6af0bf9c bellard
/* Conditional moves */
591 6af0bf9c bellard
void op_movn (void)
592 6af0bf9c bellard
{
593 6af0bf9c bellard
    if (T1 != 0)
594 6af0bf9c bellard
        env->gpr[PARAM1] = T0;
595 6af0bf9c bellard
    RETURN();
596 6af0bf9c bellard
}
597 6af0bf9c bellard
598 6af0bf9c bellard
void op_movz (void)
599 6af0bf9c bellard
{
600 6af0bf9c bellard
    if (T1 == 0)
601 6af0bf9c bellard
        env->gpr[PARAM1] = T0;
602 6af0bf9c bellard
    RETURN();
603 6af0bf9c bellard
}
604 6af0bf9c bellard
605 6af0bf9c bellard
/* Tests */
606 6af0bf9c bellard
#define OP_COND(name, cond) \
607 6af0bf9c bellard
void glue(op_, name) (void) \
608 6af0bf9c bellard
{                           \
609 6af0bf9c bellard
    if (cond) {             \
610 6af0bf9c bellard
        T0 = 1;             \
611 6af0bf9c bellard
    } else {                \
612 6af0bf9c bellard
        T0 = 0;             \
613 6af0bf9c bellard
    }                       \
614 6af0bf9c bellard
    RETURN();               \
615 6af0bf9c bellard
}
616 6af0bf9c bellard
617 6af0bf9c bellard
OP_COND(eq, T0 == T1);
618 6af0bf9c bellard
OP_COND(ne, T0 != T1);
619 6af0bf9c bellard
OP_COND(ge, (int32_t)T0 >= (int32_t)T1);
620 6af0bf9c bellard
OP_COND(geu, T0 >= T1);
621 6af0bf9c bellard
OP_COND(lt, (int32_t)T0 < (int32_t)T1);
622 6af0bf9c bellard
OP_COND(ltu, T0 < T1);
623 6af0bf9c bellard
OP_COND(gez, (int32_t)T0 >= 0);
624 6af0bf9c bellard
OP_COND(gtz, (int32_t)T0 > 0);
625 6af0bf9c bellard
OP_COND(lez, (int32_t)T0 <= 0);
626 6af0bf9c bellard
OP_COND(ltz, (int32_t)T0 < 0);
627 6af0bf9c bellard
628 6af0bf9c bellard
/* Branchs */
629 6af0bf9c bellard
//#undef USE_DIRECT_JUMP
630 c53be334 bellard
631 c53be334 bellard
void OPPROTO op_goto_tb0(void)
632 c53be334 bellard
{
633 c53be334 bellard
    GOTO_TB(op_goto_tb0, PARAM1, 0);
634 c53be334 bellard
}
635 c53be334 bellard
636 c53be334 bellard
void OPPROTO op_goto_tb1(void)
637 c53be334 bellard
{
638 c53be334 bellard
    GOTO_TB(op_goto_tb1, PARAM1, 1);
639 c53be334 bellard
}
640 6af0bf9c bellard
641 6af0bf9c bellard
/* Branch to register */
642 6af0bf9c bellard
void op_save_breg_target (void)
643 6af0bf9c bellard
{
644 6af0bf9c bellard
    env->btarget = T2;
645 6af0bf9c bellard
}
646 6af0bf9c bellard
647 6af0bf9c bellard
void op_restore_breg_target (void)
648 6af0bf9c bellard
{
649 6af0bf9c bellard
    T2 = env->btarget;
650 6af0bf9c bellard
}
651 6af0bf9c bellard
652 6af0bf9c bellard
void op_breg (void)
653 6af0bf9c bellard
{
654 6af0bf9c bellard
    env->PC = T2;
655 6af0bf9c bellard
    RETURN();
656 6af0bf9c bellard
}
657 6af0bf9c bellard
658 6af0bf9c bellard
void op_save_btarget (void)
659 6af0bf9c bellard
{
660 6af0bf9c bellard
    env->btarget = PARAM1;
661 6af0bf9c bellard
    RETURN();
662 6af0bf9c bellard
}
663 6af0bf9c bellard
664 6af0bf9c bellard
/* Conditional branch */
665 6af0bf9c bellard
void op_set_bcond (void)
666 6af0bf9c bellard
{
667 6af0bf9c bellard
    T2 = T0;
668 6af0bf9c bellard
    RETURN();
669 6af0bf9c bellard
}
670 6af0bf9c bellard
671 6af0bf9c bellard
void op_save_bcond (void)
672 6af0bf9c bellard
{
673 6af0bf9c bellard
    env->bcond = T2;
674 6af0bf9c bellard
    RETURN();
675 6af0bf9c bellard
}
676 6af0bf9c bellard
677 6af0bf9c bellard
void op_restore_bcond (void)
678 6af0bf9c bellard
{
679 6af0bf9c bellard
    T2 = env->bcond;
680 6af0bf9c bellard
    RETURN();
681 6af0bf9c bellard
}
682 6af0bf9c bellard
683 c53be334 bellard
void op_jnz_T2 (void)
684 6af0bf9c bellard
{
685 c53be334 bellard
    if (T2)
686 c53be334 bellard
        GOTO_LABEL_PARAM(1);
687 6af0bf9c bellard
    RETURN();
688 6af0bf9c bellard
}
689 6af0bf9c bellard
690 6af0bf9c bellard
/* CP0 functions */
691 6af0bf9c bellard
void op_mfc0 (void)
692 6af0bf9c bellard
{
693 6af0bf9c bellard
    CALL_FROM_TB2(do_mfc0, PARAM1, PARAM2);
694 6af0bf9c bellard
    RETURN();
695 6af0bf9c bellard
}
696 6af0bf9c bellard
697 6af0bf9c bellard
void op_mtc0 (void)
698 6af0bf9c bellard
{
699 6af0bf9c bellard
    CALL_FROM_TB2(do_mtc0, PARAM1, PARAM2);
700 6af0bf9c bellard
    RETURN();
701 6af0bf9c bellard
}
702 6af0bf9c bellard
703 6ea83fed bellard
#ifdef MIPS_USES_FPU
704 6ea83fed bellard
705 6ea83fed bellard
#if 0
706 6ea83fed bellard
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
707 6ea83fed bellard
#else
708 6ea83fed bellard
# define DEBUG_FPU_STATE() do { } while(0)
709 6ea83fed bellard
#endif
710 6ea83fed bellard
711 6ea83fed bellard
void op_cp1_enabled(void)
712 6ea83fed bellard
{
713 6ea83fed bellard
    if (!(env->CP0_Status & (1 << CP0St_CU1))) {
714 6ea83fed bellard
        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
715 6ea83fed bellard
    }
716 6ea83fed bellard
    RETURN();
717 6ea83fed bellard
}
718 6ea83fed bellard
719 6ea83fed bellard
/* CP1 functions */
720 6ea83fed bellard
void op_cfc1 (void)
721 6ea83fed bellard
{
722 6ea83fed bellard
    if (T1 == 0) {
723 6ea83fed bellard
        T0 = env->fcr0;
724 6ea83fed bellard
    }
725 6ea83fed bellard
    else {
726 6ea83fed bellard
        /* fetch fcr31, masking unused bits */
727 6ea83fed bellard
        T0 = env->fcr31 & 0x0183FFFF;
728 6ea83fed bellard
    }
729 6ea83fed bellard
    DEBUG_FPU_STATE();
730 6ea83fed bellard
    RETURN();
731 6ea83fed bellard
}
732 6ea83fed bellard
733 6ea83fed bellard
/* convert MIPS rounding mode in FCR31 to IEEE library */
734 6ea83fed bellard
unsigned int ieee_rm[] = { 
735 6ea83fed bellard
    float_round_nearest_even,
736 6ea83fed bellard
    float_round_to_zero,
737 6ea83fed bellard
    float_round_up,
738 6ea83fed bellard
    float_round_down
739 6ea83fed bellard
};
740 6ea83fed bellard
741 6ea83fed bellard
#define RESTORE_ROUNDING_MODE \
742 6ea83fed bellard
    set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
743 6ea83fed bellard
744 6ea83fed bellard
void op_ctc1 (void)
745 6ea83fed bellard
{
746 6ea83fed bellard
    if (T1 == 0) {
747 6ea83fed bellard
        /* XXX should this throw an exception?
748 6ea83fed bellard
         * don't write to FCR0.
749 6ea83fed bellard
         * env->fcr0 = T0; 
750 6ea83fed bellard
         */
751 6ea83fed bellard
    }
752 6ea83fed bellard
    else {
753 6ea83fed bellard
        /* store new fcr31, masking unused bits */  
754 6ea83fed bellard
        env->fcr31 = T0 & 0x0183FFFF;
755 6ea83fed bellard
756 6ea83fed bellard
        /* set rounding mode */
757 6ea83fed bellard
        RESTORE_ROUNDING_MODE;
758 6ea83fed bellard
759 6ea83fed bellard
#ifndef CONFIG_SOFTFLOAT
760 6ea83fed bellard
        /* no floating point exception for native float */
761 6ea83fed bellard
        SET_FP_ENABLE(env->fcr31, 0);
762 6ea83fed bellard
#endif
763 6ea83fed bellard
    }
764 6ea83fed bellard
    DEBUG_FPU_STATE();
765 6ea83fed bellard
    RETURN();
766 6ea83fed bellard
}
767 6ea83fed bellard
768 6ea83fed bellard
void op_mfc1 (void)
769 6ea83fed bellard
{
770 6ea83fed bellard
    T0 = WT0;
771 6ea83fed bellard
    DEBUG_FPU_STATE();
772 6ea83fed bellard
    RETURN();
773 6ea83fed bellard
}
774 6ea83fed bellard
775 6ea83fed bellard
void op_mtc1 (void)
776 6ea83fed bellard
{
777 6ea83fed bellard
    WT0 = T0;
778 6ea83fed bellard
    DEBUG_FPU_STATE();
779 6ea83fed bellard
    RETURN();
780 6ea83fed bellard
}
781 6ea83fed bellard
782 6ea83fed bellard
/* Float support.
783 6ea83fed bellard
   Single precition routines have a "s" suffix, double precision a
784 6ea83fed bellard
   "d" suffix.  */
785 6ea83fed bellard
786 6ea83fed bellard
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
787 6ea83fed bellard
788 6ea83fed bellard
FLOAT_OP(cvtd, w)
789 6ea83fed bellard
{
790 6ea83fed bellard
    FDT2 = int32_to_float64(WT0, &env->fp_status);
791 6ea83fed bellard
    DEBUG_FPU_STATE();
792 6ea83fed bellard
    RETURN();
793 6ea83fed bellard
}
794 6ea83fed bellard
FLOAT_OP(cvts, w)
795 6ea83fed bellard
{
796 6ea83fed bellard
    FST2 = int32_to_float32(WT0, &env->fp_status);
797 6ea83fed bellard
    DEBUG_FPU_STATE();
798 6ea83fed bellard
    RETURN();
799 6ea83fed bellard
}
800 6ea83fed bellard
FLOAT_OP(cvtw, s)
801 6ea83fed bellard
{
802 6ea83fed bellard
    WT2 = float32_to_int32(FST0, &env->fp_status);
803 6ea83fed bellard
    DEBUG_FPU_STATE();
804 6ea83fed bellard
    RETURN();
805 6ea83fed bellard
}
806 6ea83fed bellard
FLOAT_OP(cvtw, d)
807 6ea83fed bellard
{
808 6ea83fed bellard
    WT2 = float64_to_int32(FDT0, &env->fp_status);
809 6ea83fed bellard
    DEBUG_FPU_STATE();
810 6ea83fed bellard
    RETURN();
811 6ea83fed bellard
}
812 6ea83fed bellard
813 6ea83fed bellard
FLOAT_OP(roundw, d)
814 6ea83fed bellard
{
815 6ea83fed bellard
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
816 6ea83fed bellard
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
817 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
818 6ea83fed bellard
819 6ea83fed bellard
    DEBUG_FPU_STATE();
820 6ea83fed bellard
    RETURN();
821 6ea83fed bellard
}
822 6ea83fed bellard
FLOAT_OP(roundw, s)
823 6ea83fed bellard
{
824 6ea83fed bellard
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
825 6ea83fed bellard
    WT2 = float32_round_to_int(FST0, &env->fp_status);
826 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
827 6ea83fed bellard
    DEBUG_FPU_STATE();
828 6ea83fed bellard
    RETURN();
829 6ea83fed bellard
}
830 6ea83fed bellard
831 6ea83fed bellard
FLOAT_OP(truncw, d)
832 6ea83fed bellard
{
833 6ea83fed bellard
    WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
834 6ea83fed bellard
    DEBUG_FPU_STATE();
835 6ea83fed bellard
    RETURN();
836 6ea83fed bellard
}
837 6ea83fed bellard
FLOAT_OP(truncw, s)
838 6ea83fed bellard
{
839 6ea83fed bellard
    WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
840 6ea83fed bellard
    DEBUG_FPU_STATE();
841 6ea83fed bellard
    RETURN();
842 6ea83fed bellard
}
843 6ea83fed bellard
844 6ea83fed bellard
FLOAT_OP(ceilw, d)
845 6ea83fed bellard
{
846 6ea83fed bellard
    set_float_rounding_mode(float_round_up, &env->fp_status);
847 6ea83fed bellard
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
848 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
849 6ea83fed bellard
850 6ea83fed bellard
    DEBUG_FPU_STATE();
851 6ea83fed bellard
    RETURN();
852 6ea83fed bellard
}
853 6ea83fed bellard
FLOAT_OP(ceilw, s)
854 6ea83fed bellard
{
855 6ea83fed bellard
    set_float_rounding_mode(float_round_up, &env->fp_status);
856 6ea83fed bellard
    WT2 = float32_round_to_int(FST0, &env->fp_status);
857 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
858 6ea83fed bellard
    DEBUG_FPU_STATE();
859 6ea83fed bellard
    RETURN();
860 6ea83fed bellard
}
861 6ea83fed bellard
862 6ea83fed bellard
FLOAT_OP(floorw, d)
863 6ea83fed bellard
{
864 6ea83fed bellard
    set_float_rounding_mode(float_round_down, &env->fp_status);
865 6ea83fed bellard
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
866 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
867 6ea83fed bellard
868 6ea83fed bellard
    DEBUG_FPU_STATE();
869 6ea83fed bellard
    RETURN();
870 6ea83fed bellard
}
871 6ea83fed bellard
FLOAT_OP(floorw, s)
872 6ea83fed bellard
{
873 6ea83fed bellard
    set_float_rounding_mode(float_round_down, &env->fp_status);
874 6ea83fed bellard
    WT2 = float32_round_to_int(FST0, &env->fp_status);
875 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
876 6ea83fed bellard
    DEBUG_FPU_STATE();
877 6ea83fed bellard
    RETURN();
878 6ea83fed bellard
}
879 6ea83fed bellard
880 6ea83fed bellard
/* binary operations */
881 6ea83fed bellard
#define FLOAT_BINOP(name) \
882 6ea83fed bellard
FLOAT_OP(name, d)         \
883 6ea83fed bellard
{                         \
884 6ea83fed bellard
    FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);    \
885 6ea83fed bellard
    DEBUG_FPU_STATE();    \
886 6ea83fed bellard
}                         \
887 6ea83fed bellard
FLOAT_OP(name, s)         \
888 6ea83fed bellard
{                         \
889 6ea83fed bellard
    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);    \
890 6ea83fed bellard
    DEBUG_FPU_STATE();    \
891 6ea83fed bellard
}
892 6ea83fed bellard
FLOAT_BINOP(add)
893 6ea83fed bellard
FLOAT_BINOP(sub)
894 6ea83fed bellard
FLOAT_BINOP(mul)
895 6ea83fed bellard
FLOAT_BINOP(div)
896 6ea83fed bellard
#undef FLOAT_BINOP
897 6ea83fed bellard
898 6ea83fed bellard
/* unary operations, modifying fp status  */
899 6ea83fed bellard
#define FLOAT_UNOP(name)  \
900 6ea83fed bellard
FLOAT_OP(name, d)         \
901 6ea83fed bellard
{                         \
902 6ea83fed bellard
    FDT2 = float64_ ## name(FDT0, &env->fp_status);   \
903 6ea83fed bellard
    DEBUG_FPU_STATE();    \
904 6ea83fed bellard
}                         \
905 6ea83fed bellard
FLOAT_OP(name, s)         \
906 6ea83fed bellard
{                         \
907 6ea83fed bellard
    FST2 = float32_ ## name(FST0, &env->fp_status);   \
908 6ea83fed bellard
    DEBUG_FPU_STATE();    \
909 6ea83fed bellard
}
910 6ea83fed bellard
FLOAT_UNOP(sqrt)
911 6ea83fed bellard
#undef FLOAT_UNOP
912 6ea83fed bellard
913 6ea83fed bellard
/* unary operations, not modifying fp status  */
914 6ea83fed bellard
#define FLOAT_UNOP(name)  \
915 6ea83fed bellard
FLOAT_OP(name, d)         \
916 6ea83fed bellard
{                         \
917 6ea83fed bellard
    FDT2 = float64_ ## name(FDT0);   \
918 6ea83fed bellard
    DEBUG_FPU_STATE();    \
919 6ea83fed bellard
}                         \
920 6ea83fed bellard
FLOAT_OP(name, s)         \
921 6ea83fed bellard
{                         \
922 6ea83fed bellard
    FST2 = float32_ ## name(FST0);   \
923 6ea83fed bellard
    DEBUG_FPU_STATE();    \
924 6ea83fed bellard
}
925 6ea83fed bellard
FLOAT_UNOP(abs)
926 6ea83fed bellard
FLOAT_UNOP(chs)
927 6ea83fed bellard
#undef FLOAT_UNOP
928 6ea83fed bellard
929 6ea83fed bellard
FLOAT_OP(mov, d)
930 6ea83fed bellard
{
931 6ea83fed bellard
    FDT2 = FDT0;
932 6ea83fed bellard
    DEBUG_FPU_STATE();
933 6ea83fed bellard
    RETURN();
934 6ea83fed bellard
}
935 6ea83fed bellard
FLOAT_OP(mov, s)
936 6ea83fed bellard
{
937 6ea83fed bellard
    FST2 = FST0;
938 6ea83fed bellard
    DEBUG_FPU_STATE();
939 6ea83fed bellard
    RETURN();
940 6ea83fed bellard
}
941 6ea83fed bellard
942 6ea83fed bellard
#ifdef CONFIG_SOFTFLOAT
943 6ea83fed bellard
#define clear_invalid() do {                                \
944 6ea83fed bellard
    int flags = get_float_exception_flags(&env->fp_status); \
945 6ea83fed bellard
    flags &= ~float_flag_invalid;                           \
946 6ea83fed bellard
    set_float_exception_flags(flags, &env->fp_status);      \
947 6ea83fed bellard
} while(0)
948 6ea83fed bellard
#else
949 6ea83fed bellard
#define clear_invalid() do { } while(0)
950 6ea83fed bellard
#endif
951 6ea83fed bellard
952 6ea83fed bellard
extern void dump_fpu_s(CPUState *env);
953 6ea83fed bellard
954 6ea83fed bellard
#define FOP_COND(fmt, op, sig, cond)           \
955 6ea83fed bellard
void op_cmp_ ## fmt ## _ ## op (void)          \
956 6ea83fed bellard
{                                              \
957 6ea83fed bellard
    if (cond)                                  \
958 6ea83fed bellard
        SET_FP_COND(env->fcr31);               \
959 6ea83fed bellard
    else                                       \
960 6ea83fed bellard
        CLEAR_FP_COND(env->fcr31);             \
961 6ea83fed bellard
    if (!sig)                                  \
962 6ea83fed bellard
        clear_invalid();                       \
963 6ea83fed bellard
    /*CALL_FROM_TB1(dump_fpu_s, env);*/ \
964 6ea83fed bellard
    DEBUG_FPU_STATE();                         \
965 6ea83fed bellard
    RETURN();                                  \
966 6ea83fed bellard
}
967 6ea83fed bellard
968 6ea83fed bellard
flag float64_is_unordered(float64 a, float64 b STATUS_PARAM)
969 6ea83fed bellard
{
970 6ea83fed bellard
    extern flag float64_is_nan( float64 a );
971 6ea83fed bellard
    if (float64_is_nan(a) || float64_is_nan(b)) {
972 6ea83fed bellard
        float_raise(float_flag_invalid, status);
973 6ea83fed bellard
        return 1;
974 6ea83fed bellard
    }
975 6ea83fed bellard
    else {
976 6ea83fed bellard
        return 0;
977 6ea83fed bellard
    }
978 6ea83fed bellard
}
979 6ea83fed bellard
980 6ea83fed bellard
FOP_COND(d, f,   0,                                                      0) 
981 6ea83fed bellard
FOP_COND(d, un,  0, float64_is_unordered(FDT1, FDT0, &env->fp_status))
982 6ea83fed bellard
FOP_COND(d, eq,  0,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
983 6ea83fed bellard
FOP_COND(d, ueq, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
984 6ea83fed bellard
FOP_COND(d, olt, 0,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
985 6ea83fed bellard
FOP_COND(d, ult, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
986 6ea83fed bellard
FOP_COND(d, ole, 0,                                                      float64_le(FDT0, FDT1, &env->fp_status))
987 6ea83fed bellard
FOP_COND(d, ule, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
988 6ea83fed bellard
/* NOTE: the comma operator will make "cond" to eval to false,
989 6ea83fed bellard
 * but float*_is_unordered() is still called
990 6ea83fed bellard
 */
991 6ea83fed bellard
FOP_COND(d, sf,  1,                                                      (float64_is_unordered(FDT0, FDT1, &env->fp_status), 0))
992 6ea83fed bellard
FOP_COND(d, ngle,1, float64_is_unordered(FDT1, FDT0, &env->fp_status))
993 6ea83fed bellard
FOP_COND(d, seq, 1,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
994 6ea83fed bellard
FOP_COND(d, ngl, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
995 6ea83fed bellard
FOP_COND(d, lt,  1,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
996 6ea83fed bellard
FOP_COND(d, nge, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
997 6ea83fed bellard
FOP_COND(d, le,  1,                                                      float64_le(FDT0, FDT1, &env->fp_status))
998 6ea83fed bellard
FOP_COND(d, ngt, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
999 6ea83fed bellard
1000 6ea83fed bellard
flag float32_is_unordered(float32 a, float32 b STATUS_PARAM)
1001 6ea83fed bellard
{
1002 6ea83fed bellard
    extern flag float32_is_nan( float32 a );
1003 6ea83fed bellard
    if (float32_is_nan(a) || float32_is_nan(b)) {
1004 6ea83fed bellard
        float_raise(float_flag_invalid, status);
1005 6ea83fed bellard
        return 1;
1006 6ea83fed bellard
    }
1007 6ea83fed bellard
    else {
1008 6ea83fed bellard
        return 0;
1009 6ea83fed bellard
    }
1010 6ea83fed bellard
}
1011 6ea83fed bellard
1012 6ea83fed bellard
/* NOTE: the comma operator will make "cond" to eval to false,
1013 6ea83fed bellard
 * but float*_is_unordered() is still called
1014 6ea83fed bellard
 */
1015 6ea83fed bellard
FOP_COND(s, f,   0,                                                      0) 
1016 6ea83fed bellard
FOP_COND(s, un,  0, float32_is_unordered(FST1, FST0, &env->fp_status))
1017 6ea83fed bellard
FOP_COND(s, eq,  0,                                                      float32_eq(FST0, FST1, &env->fp_status))
1018 6ea83fed bellard
FOP_COND(s, ueq, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1019 6ea83fed bellard
FOP_COND(s, olt, 0,                                                      float32_lt(FST0, FST1, &env->fp_status))
1020 6ea83fed bellard
FOP_COND(s, ult, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1021 6ea83fed bellard
FOP_COND(s, ole, 0,                                                      float32_le(FST0, FST1, &env->fp_status))
1022 6ea83fed bellard
FOP_COND(s, ule, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
1023 6ea83fed bellard
/* NOTE: the comma operator will make "cond" to eval to false,
1024 6ea83fed bellard
 * but float*_is_unordered() is still called
1025 6ea83fed bellard
 */
1026 6ea83fed bellard
FOP_COND(s, sf,  1,                                                      (float32_is_unordered(FST0, FST1, &env->fp_status), 0))
1027 6ea83fed bellard
FOP_COND(s, ngle,1, float32_is_unordered(FST1, FST0, &env->fp_status))
1028 6ea83fed bellard
FOP_COND(s, seq, 1,                                                      float32_eq(FST0, FST1, &env->fp_status))
1029 6ea83fed bellard
FOP_COND(s, ngl, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1030 6ea83fed bellard
FOP_COND(s, lt,  1,                                                      float32_lt(FST0, FST1, &env->fp_status))
1031 6ea83fed bellard
FOP_COND(s, nge, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1032 6ea83fed bellard
FOP_COND(s, le,  1,                                                      float32_le(FST0, FST1, &env->fp_status))
1033 6ea83fed bellard
FOP_COND(s, ngt, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
1034 6ea83fed bellard
1035 6ea83fed bellard
void op_bc1f (void)
1036 6ea83fed bellard
{
1037 6ea83fed bellard
    T0 = ! IS_FP_COND_SET(env->fcr31);
1038 6ea83fed bellard
    DEBUG_FPU_STATE();
1039 6ea83fed bellard
    RETURN();
1040 6ea83fed bellard
}
1041 6ea83fed bellard
1042 6ea83fed bellard
void op_bc1t (void)
1043 6ea83fed bellard
{
1044 6ea83fed bellard
    T0 = IS_FP_COND_SET(env->fcr31);
1045 6ea83fed bellard
    DEBUG_FPU_STATE();
1046 6ea83fed bellard
    RETURN();
1047 6ea83fed bellard
}
1048 6ea83fed bellard
#endif /* MIPS_USES_FPU */
1049 6ea83fed bellard
1050 6af0bf9c bellard
#if defined(MIPS_USES_R4K_TLB)
1051 6af0bf9c bellard
void op_tlbwi (void)
1052 6af0bf9c bellard
{
1053 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbwi);
1054 6af0bf9c bellard
    RETURN();
1055 6af0bf9c bellard
}
1056 6af0bf9c bellard
1057 6af0bf9c bellard
void op_tlbwr (void)
1058 6af0bf9c bellard
{
1059 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbwr);
1060 6af0bf9c bellard
    RETURN();
1061 6af0bf9c bellard
}
1062 6af0bf9c bellard
1063 6af0bf9c bellard
void op_tlbp (void)
1064 6af0bf9c bellard
{
1065 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbp);
1066 6af0bf9c bellard
    RETURN();
1067 6af0bf9c bellard
}
1068 6af0bf9c bellard
1069 6af0bf9c bellard
void op_tlbr (void)
1070 6af0bf9c bellard
{
1071 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbr);
1072 6af0bf9c bellard
    RETURN();
1073 6af0bf9c bellard
}
1074 6af0bf9c bellard
#endif
1075 6af0bf9c bellard
1076 6af0bf9c bellard
/* Specials */
1077 6af0bf9c bellard
void op_pmon (void)
1078 6af0bf9c bellard
{
1079 6af0bf9c bellard
    CALL_FROM_TB1(do_pmon, PARAM1);
1080 6af0bf9c bellard
}
1081 6af0bf9c bellard
1082 6af0bf9c bellard
void op_trap (void)
1083 6af0bf9c bellard
{
1084 6af0bf9c bellard
    if (T0) {
1085 4ad40f36 bellard
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP);
1086 6af0bf9c bellard
    }
1087 6af0bf9c bellard
    RETURN();
1088 6af0bf9c bellard
}
1089 6af0bf9c bellard
1090 4ad40f36 bellard
void op_debug (void)
1091 4ad40f36 bellard
{
1092 ce2f4b3c bellard
  CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
1093 4ad40f36 bellard
}
1094 4ad40f36 bellard
1095 6af0bf9c bellard
void op_set_lladdr (void)
1096 6af0bf9c bellard
{
1097 6af0bf9c bellard
    env->CP0_LLAddr = T2;
1098 6af0bf9c bellard
}
1099 6af0bf9c bellard
1100 6af0bf9c bellard
void debug_eret (void);
1101 6af0bf9c bellard
void op_eret (void)
1102 6af0bf9c bellard
{
1103 6af0bf9c bellard
    CALL_FROM_TB0(debug_eret);
1104 51e11d9e bellard
    if (env->hflags & MIPS_HFLAG_ERL) {
1105 6af0bf9c bellard
        env->PC = env->CP0_ErrorEPC;
1106 51e11d9e bellard
        env->hflags &= ~MIPS_HFLAG_ERL;
1107 3e382bc8 bellard
        env->CP0_Status &= ~(1 << CP0St_ERL);
1108 51e11d9e bellard
    } else {
1109 6af0bf9c bellard
        env->PC = env->CP0_EPC;
1110 51e11d9e bellard
        env->hflags &= ~MIPS_HFLAG_EXL;
1111 3e382bc8 bellard
        env->CP0_Status &= ~(1 << CP0St_EXL);
1112 51e11d9e bellard
    }
1113 6af0bf9c bellard
    env->CP0_LLAddr = 1;
1114 6af0bf9c bellard
}
1115 6af0bf9c bellard
1116 6af0bf9c bellard
void op_deret (void)
1117 6af0bf9c bellard
{
1118 6af0bf9c bellard
    CALL_FROM_TB0(debug_eret);
1119 6af0bf9c bellard
    env->PC = env->CP0_DEPC;
1120 6af0bf9c bellard
}
1121 6af0bf9c bellard
1122 6af0bf9c bellard
void op_save_state (void)
1123 6af0bf9c bellard
{
1124 6af0bf9c bellard
    env->hflags = PARAM1;
1125 6af0bf9c bellard
    RETURN();
1126 6af0bf9c bellard
}
1127 6af0bf9c bellard
1128 6af0bf9c bellard
void op_save_pc (void)
1129 6af0bf9c bellard
{
1130 6af0bf9c bellard
    env->PC = PARAM1;
1131 6af0bf9c bellard
    RETURN();
1132 6af0bf9c bellard
}
1133 6af0bf9c bellard
1134 6af0bf9c bellard
void op_raise_exception (void)
1135 6af0bf9c bellard
{
1136 6af0bf9c bellard
    CALL_FROM_TB1(do_raise_exception, PARAM1);
1137 6af0bf9c bellard
    RETURN();
1138 6af0bf9c bellard
}
1139 6af0bf9c bellard
1140 6af0bf9c bellard
void op_raise_exception_err (void)
1141 6af0bf9c bellard
{
1142 6af0bf9c bellard
    CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
1143 6af0bf9c bellard
    RETURN();
1144 6af0bf9c bellard
}
1145 6af0bf9c bellard
1146 6af0bf9c bellard
void op_exit_tb (void)
1147 6af0bf9c bellard
{
1148 6af0bf9c bellard
    EXIT_TB();
1149 6af0bf9c bellard
}
1150 6af0bf9c bellard
1151 4ad40f36 bellard
void op_wait (void)
1152 4ad40f36 bellard
{
1153 4ad40f36 bellard
    env->halted = 1;
1154 4ad40f36 bellard
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
1155 4ad40f36 bellard
}