Statistics
| Branch: | Revision:

root / target-mips / op.c @ c570fd16

History | View | Annotate | Download (40 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 c570fd16 ths
#define TN
144 6af0bf9c bellard
#include "op_template.c"
145 6af0bf9c bellard
#undef TN
146 6af0bf9c bellard
147 6ea83fed bellard
#ifdef MIPS_USES_FPU
148 6ea83fed bellard
149 6ea83fed bellard
#define SFREG 0
150 6ea83fed bellard
#define DFREG 0
151 6ea83fed bellard
#include "fop_template.c"
152 6ea83fed bellard
#undef SFREG
153 6ea83fed bellard
#undef DFREG
154 6ea83fed bellard
#define SFREG 1
155 6ea83fed bellard
#include "fop_template.c"
156 6ea83fed bellard
#undef SFREG
157 6ea83fed bellard
#define SFREG 2
158 6ea83fed bellard
#define DFREG 2
159 6ea83fed bellard
#include "fop_template.c"
160 6ea83fed bellard
#undef SFREG
161 6ea83fed bellard
#undef DFREG
162 6ea83fed bellard
#define SFREG 3
163 6ea83fed bellard
#include "fop_template.c"
164 6ea83fed bellard
#undef SFREG
165 6ea83fed bellard
#define SFREG 4
166 6ea83fed bellard
#define DFREG 4
167 6ea83fed bellard
#include "fop_template.c"
168 6ea83fed bellard
#undef SFREG
169 6ea83fed bellard
#undef DFREG
170 6ea83fed bellard
#define SFREG 5
171 6ea83fed bellard
#include "fop_template.c"
172 6ea83fed bellard
#undef SFREG
173 6ea83fed bellard
#define SFREG 6
174 6ea83fed bellard
#define DFREG 6
175 6ea83fed bellard
#include "fop_template.c"
176 6ea83fed bellard
#undef SFREG
177 6ea83fed bellard
#undef DFREG
178 6ea83fed bellard
#define SFREG 7
179 6ea83fed bellard
#include "fop_template.c"
180 6ea83fed bellard
#undef SFREG
181 6ea83fed bellard
#define SFREG 8
182 6ea83fed bellard
#define DFREG 8
183 6ea83fed bellard
#include "fop_template.c"
184 6ea83fed bellard
#undef SFREG
185 6ea83fed bellard
#undef DFREG
186 6ea83fed bellard
#define SFREG 9
187 6ea83fed bellard
#include "fop_template.c"
188 6ea83fed bellard
#undef SFREG
189 6ea83fed bellard
#define SFREG 10
190 6ea83fed bellard
#define DFREG 10
191 6ea83fed bellard
#include "fop_template.c"
192 6ea83fed bellard
#undef SFREG
193 6ea83fed bellard
#undef DFREG
194 6ea83fed bellard
#define SFREG 11
195 6ea83fed bellard
#include "fop_template.c"
196 6ea83fed bellard
#undef SFREG
197 6ea83fed bellard
#define SFREG 12
198 6ea83fed bellard
#define DFREG 12
199 6ea83fed bellard
#include "fop_template.c"
200 6ea83fed bellard
#undef SFREG
201 6ea83fed bellard
#undef DFREG
202 6ea83fed bellard
#define SFREG 13
203 6ea83fed bellard
#include "fop_template.c"
204 6ea83fed bellard
#undef SFREG
205 6ea83fed bellard
#define SFREG 14
206 6ea83fed bellard
#define DFREG 14
207 6ea83fed bellard
#include "fop_template.c"
208 6ea83fed bellard
#undef SFREG
209 6ea83fed bellard
#undef DFREG
210 6ea83fed bellard
#define SFREG 15
211 6ea83fed bellard
#include "fop_template.c"
212 6ea83fed bellard
#undef SFREG
213 6ea83fed bellard
#define SFREG 16
214 6ea83fed bellard
#define DFREG 16
215 6ea83fed bellard
#include "fop_template.c"
216 6ea83fed bellard
#undef SFREG
217 6ea83fed bellard
#undef DFREG
218 6ea83fed bellard
#define SFREG 17
219 6ea83fed bellard
#include "fop_template.c"
220 6ea83fed bellard
#undef SFREG
221 6ea83fed bellard
#define SFREG 18
222 6ea83fed bellard
#define DFREG 18
223 6ea83fed bellard
#include "fop_template.c"
224 6ea83fed bellard
#undef SFREG
225 6ea83fed bellard
#undef DFREG
226 6ea83fed bellard
#define SFREG 19
227 6ea83fed bellard
#include "fop_template.c"
228 6ea83fed bellard
#undef SFREG
229 6ea83fed bellard
#define SFREG 20
230 6ea83fed bellard
#define DFREG 20
231 6ea83fed bellard
#include "fop_template.c"
232 6ea83fed bellard
#undef SFREG
233 6ea83fed bellard
#undef DFREG
234 6ea83fed bellard
#define SFREG 21
235 6ea83fed bellard
#include "fop_template.c"
236 6ea83fed bellard
#undef SFREG
237 6ea83fed bellard
#define SFREG 22
238 6ea83fed bellard
#define DFREG 22
239 6ea83fed bellard
#include "fop_template.c"
240 6ea83fed bellard
#undef SFREG
241 6ea83fed bellard
#undef DFREG
242 6ea83fed bellard
#define SFREG 23
243 6ea83fed bellard
#include "fop_template.c"
244 6ea83fed bellard
#undef SFREG
245 6ea83fed bellard
#define SFREG 24
246 6ea83fed bellard
#define DFREG 24
247 6ea83fed bellard
#include "fop_template.c"
248 6ea83fed bellard
#undef SFREG
249 6ea83fed bellard
#undef DFREG
250 6ea83fed bellard
#define SFREG 25
251 6ea83fed bellard
#include "fop_template.c"
252 6ea83fed bellard
#undef SFREG
253 6ea83fed bellard
#define SFREG 26
254 6ea83fed bellard
#define DFREG 26
255 6ea83fed bellard
#include "fop_template.c"
256 6ea83fed bellard
#undef SFREG
257 6ea83fed bellard
#undef DFREG
258 6ea83fed bellard
#define SFREG 27
259 6ea83fed bellard
#include "fop_template.c"
260 6ea83fed bellard
#undef SFREG
261 6ea83fed bellard
#define SFREG 28
262 6ea83fed bellard
#define DFREG 28
263 6ea83fed bellard
#include "fop_template.c"
264 6ea83fed bellard
#undef SFREG
265 6ea83fed bellard
#undef DFREG
266 6ea83fed bellard
#define SFREG 29
267 6ea83fed bellard
#include "fop_template.c"
268 6ea83fed bellard
#undef SFREG
269 6ea83fed bellard
#define SFREG 30
270 6ea83fed bellard
#define DFREG 30
271 6ea83fed bellard
#include "fop_template.c"
272 6ea83fed bellard
#undef SFREG
273 6ea83fed bellard
#undef DFREG
274 6ea83fed bellard
#define SFREG 31
275 6ea83fed bellard
#include "fop_template.c"
276 6ea83fed bellard
#undef SFREG
277 6ea83fed bellard
278 6ea83fed bellard
#define FTN
279 6ea83fed bellard
#include "fop_template.c"
280 6ea83fed bellard
#undef FTN
281 6ea83fed bellard
282 6ea83fed bellard
#endif
283 6ea83fed bellard
284 6af0bf9c bellard
void op_dup_T0 (void)
285 6af0bf9c bellard
{
286 6af0bf9c bellard
    T2 = T0;
287 6af0bf9c bellard
    RETURN();
288 6af0bf9c bellard
}
289 6af0bf9c bellard
290 6af0bf9c bellard
void op_load_HI (void)
291 6af0bf9c bellard
{
292 6af0bf9c bellard
    T0 = env->HI;
293 6af0bf9c bellard
    RETURN();
294 6af0bf9c bellard
}
295 6af0bf9c bellard
296 6af0bf9c bellard
void op_store_HI (void)
297 6af0bf9c bellard
{
298 6af0bf9c bellard
    env->HI = T0;
299 6af0bf9c bellard
    RETURN();
300 6af0bf9c bellard
}
301 6af0bf9c bellard
302 6af0bf9c bellard
void op_load_LO (void)
303 6af0bf9c bellard
{
304 6af0bf9c bellard
    T0 = env->LO;
305 6af0bf9c bellard
    RETURN();
306 6af0bf9c bellard
}
307 6af0bf9c bellard
308 6af0bf9c bellard
void op_store_LO (void)
309 6af0bf9c bellard
{
310 6af0bf9c bellard
    env->LO = T0;
311 6af0bf9c bellard
    RETURN();
312 6af0bf9c bellard
}
313 6af0bf9c bellard
314 6af0bf9c bellard
/* Load and store */
315 6af0bf9c bellard
#define MEMSUFFIX _raw
316 6af0bf9c bellard
#include "op_mem.c"
317 6af0bf9c bellard
#undef MEMSUFFIX
318 6af0bf9c bellard
#if !defined(CONFIG_USER_ONLY)
319 6af0bf9c bellard
#define MEMSUFFIX _user
320 6af0bf9c bellard
#include "op_mem.c"
321 6af0bf9c bellard
#undef MEMSUFFIX
322 6af0bf9c bellard
323 6af0bf9c bellard
#define MEMSUFFIX _kernel
324 6af0bf9c bellard
#include "op_mem.c"
325 6af0bf9c bellard
#undef MEMSUFFIX
326 6af0bf9c bellard
#endif
327 6af0bf9c bellard
328 6af0bf9c bellard
/* Arithmetic */
329 6af0bf9c bellard
void op_add (void)
330 6af0bf9c bellard
{
331 c570fd16 ths
    T0 = SIGN_EXTEND32((int32_t)T0 + (int32_t)T1);
332 6af0bf9c bellard
    RETURN();
333 6af0bf9c bellard
}
334 6af0bf9c bellard
335 6af0bf9c bellard
void op_addo (void)
336 6af0bf9c bellard
{
337 6af0bf9c bellard
    target_ulong tmp;
338 6af0bf9c bellard
339 c570fd16 ths
    tmp = (int32_t)T0;
340 c570fd16 ths
    T0 = (int32_t)T0 + (int32_t)T1;
341 76e050c2 bellard
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
342 c570fd16 ths
        /* operands of same sign, result different sign */
343 4ad40f36 bellard
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
344 6af0bf9c bellard
    }
345 c570fd16 ths
    T0 = SIGN_EXTEND32(T0);
346 6af0bf9c bellard
    RETURN();
347 6af0bf9c bellard
}
348 6af0bf9c bellard
349 6af0bf9c bellard
void op_sub (void)
350 6af0bf9c bellard
{
351 c570fd16 ths
    T0 = SIGN_EXTEND32((int32_t)T0 - (int32_t)T1);
352 6af0bf9c bellard
    RETURN();
353 6af0bf9c bellard
}
354 6af0bf9c bellard
355 6af0bf9c bellard
void op_subo (void)
356 6af0bf9c bellard
{
357 6af0bf9c bellard
    target_ulong tmp;
358 6af0bf9c bellard
359 c570fd16 ths
    tmp = (int32_t)T0;
360 6af0bf9c bellard
    T0 = (int32_t)T0 - (int32_t)T1;
361 76e050c2 bellard
    if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
362 c570fd16 ths
        /* operands of different sign, first operand and result different sign */
363 4ad40f36 bellard
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
364 6af0bf9c bellard
    }
365 c570fd16 ths
    T0 = SIGN_EXTEND32(T0);
366 6af0bf9c bellard
    RETURN();
367 6af0bf9c bellard
}
368 6af0bf9c bellard
369 6af0bf9c bellard
void op_mul (void)
370 6af0bf9c bellard
{
371 c570fd16 ths
    T0 = SIGN_EXTEND32((int32_t)T0 * (int32_t)T1);
372 6af0bf9c bellard
    RETURN();
373 6af0bf9c bellard
}
374 6af0bf9c bellard
375 6af0bf9c bellard
void op_div (void)
376 6af0bf9c bellard
{
377 6af0bf9c bellard
    if (T1 != 0) {
378 c570fd16 ths
        env->LO = SIGN_EXTEND32((int32_t)T0 / (int32_t)T1);
379 c570fd16 ths
        env->HI = SIGN_EXTEND32((int32_t)T0 % (int32_t)T1);
380 6af0bf9c bellard
    }
381 6af0bf9c bellard
    RETURN();
382 6af0bf9c bellard
}
383 6af0bf9c bellard
384 6af0bf9c bellard
void op_divu (void)
385 6af0bf9c bellard
{
386 6af0bf9c bellard
    if (T1 != 0) {
387 c570fd16 ths
        env->LO = SIGN_EXTEND32((uint32_t)T0 / (uint32_t)T1);
388 c570fd16 ths
        env->HI = SIGN_EXTEND32((uint32_t)T0 % (uint32_t)T1);
389 c570fd16 ths
    }
390 c570fd16 ths
    RETURN();
391 c570fd16 ths
}
392 c570fd16 ths
393 c570fd16 ths
#ifdef MIPS_HAS_MIPS64
394 c570fd16 ths
/* Arithmetic */
395 c570fd16 ths
void op_dadd (void)
396 c570fd16 ths
{
397 c570fd16 ths
    T0 += T1;
398 c570fd16 ths
    RETURN();
399 c570fd16 ths
}
400 c570fd16 ths
401 c570fd16 ths
void op_daddo (void)
402 c570fd16 ths
{
403 c570fd16 ths
    target_long tmp;
404 c570fd16 ths
405 c570fd16 ths
    tmp = T0;
406 c570fd16 ths
    T0 += T1;
407 c570fd16 ths
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
408 c570fd16 ths
        /* operands of same sign, result different sign */
409 c570fd16 ths
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
410 c570fd16 ths
    }
411 c570fd16 ths
    RETURN();
412 c570fd16 ths
}
413 c570fd16 ths
414 c570fd16 ths
void op_dsub (void)
415 c570fd16 ths
{
416 c570fd16 ths
    T0 -= T1;
417 c570fd16 ths
    RETURN();
418 c570fd16 ths
}
419 c570fd16 ths
420 c570fd16 ths
void op_dsubo (void)
421 c570fd16 ths
{
422 c570fd16 ths
    target_long tmp;
423 c570fd16 ths
424 c570fd16 ths
    tmp = T0;
425 c570fd16 ths
    T0 = (int64_t)T0 - (int64_t)T1;
426 c570fd16 ths
    if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
427 c570fd16 ths
        /* operands of different sign, first operand and result different sign */
428 c570fd16 ths
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
429 c570fd16 ths
    }
430 c570fd16 ths
    RETURN();
431 c570fd16 ths
}
432 c570fd16 ths
433 c570fd16 ths
void op_dmul (void)
434 c570fd16 ths
{
435 c570fd16 ths
    T0 = (int64_t)T0 * (int64_t)T1;
436 c570fd16 ths
    RETURN();
437 c570fd16 ths
}
438 c570fd16 ths
439 c570fd16 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
440 c570fd16 ths
/* Those might call libgcc functions.  */
441 c570fd16 ths
void op_ddiv (void)
442 c570fd16 ths
{
443 c570fd16 ths
    do_ddiv();
444 c570fd16 ths
    RETURN();
445 c570fd16 ths
}
446 c570fd16 ths
447 c570fd16 ths
void op_ddivu (void)
448 c570fd16 ths
{
449 c570fd16 ths
    do_ddivu();
450 c570fd16 ths
    RETURN();
451 c570fd16 ths
}
452 c570fd16 ths
#else
453 c570fd16 ths
void op_ddiv (void)
454 c570fd16 ths
{
455 c570fd16 ths
    if (T1 != 0) {
456 c570fd16 ths
        env->LO = (int64_t)T0 / (int64_t)T1;
457 c570fd16 ths
        env->HI = (int64_t)T0 % (int64_t)T1;
458 c570fd16 ths
    }
459 c570fd16 ths
    RETURN();
460 c570fd16 ths
}
461 c570fd16 ths
462 c570fd16 ths
void op_ddivu (void)
463 c570fd16 ths
{
464 c570fd16 ths
    if (T1 != 0) {
465 6af0bf9c bellard
        env->LO = T0 / T1;
466 6af0bf9c bellard
        env->HI = T0 % T1;
467 6af0bf9c bellard
    }
468 6af0bf9c bellard
    RETURN();
469 6af0bf9c bellard
}
470 c570fd16 ths
#endif
471 c570fd16 ths
#endif /* MIPS_HAS_MIPS64 */
472 6af0bf9c bellard
473 6af0bf9c bellard
/* Logical */
474 6af0bf9c bellard
void op_and (void)
475 6af0bf9c bellard
{
476 6af0bf9c bellard
    T0 &= T1;
477 6af0bf9c bellard
    RETURN();
478 6af0bf9c bellard
}
479 6af0bf9c bellard
480 6af0bf9c bellard
void op_nor (void)
481 6af0bf9c bellard
{
482 6af0bf9c bellard
    T0 = ~(T0 | T1);
483 6af0bf9c bellard
    RETURN();
484 6af0bf9c bellard
}
485 6af0bf9c bellard
486 6af0bf9c bellard
void op_or (void)
487 6af0bf9c bellard
{
488 6af0bf9c bellard
    T0 |= T1;
489 6af0bf9c bellard
    RETURN();
490 6af0bf9c bellard
}
491 6af0bf9c bellard
492 6af0bf9c bellard
void op_xor (void)
493 6af0bf9c bellard
{
494 6af0bf9c bellard
    T0 ^= T1;
495 6af0bf9c bellard
    RETURN();
496 6af0bf9c bellard
}
497 6af0bf9c bellard
498 6af0bf9c bellard
void op_sll (void)
499 6af0bf9c bellard
{
500 c570fd16 ths
    T0 = SIGN_EXTEND32((uint32_t)T0 << (uint32_t)T1);
501 6af0bf9c bellard
    RETURN();
502 6af0bf9c bellard
}
503 6af0bf9c bellard
504 6af0bf9c bellard
void op_sra (void)
505 6af0bf9c bellard
{
506 c570fd16 ths
    T0 = SIGN_EXTEND32((int32_t)T0 >> (uint32_t)T1);
507 6af0bf9c bellard
    RETURN();
508 6af0bf9c bellard
}
509 6af0bf9c bellard
510 6af0bf9c bellard
void op_srl (void)
511 6af0bf9c bellard
{
512 c570fd16 ths
    T0 = SIGN_EXTEND32((uint32_t)T0 >> (uint32_t)T1);
513 6af0bf9c bellard
    RETURN();
514 6af0bf9c bellard
}
515 6af0bf9c bellard
516 7a387fff ths
void op_rotr (void)
517 7a387fff ths
{
518 7a387fff ths
    target_ulong tmp;
519 7a387fff ths
520 7a387fff ths
    if (T1) {
521 c570fd16 ths
       tmp = SIGN_EXTEND32((uint32_t)T0 << (0x20 - (uint32_t)T1));
522 c570fd16 ths
       T0 = SIGN_EXTEND32((uint32_t)T0 >> (uint32_t)T1) | tmp;
523 7a387fff ths
    } else
524 7a387fff ths
       T0 = T1;
525 7a387fff ths
    RETURN();
526 7a387fff ths
}
527 7a387fff ths
528 6af0bf9c bellard
void op_sllv (void)
529 6af0bf9c bellard
{
530 c570fd16 ths
    T0 = SIGN_EXTEND32((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
531 6af0bf9c bellard
    RETURN();
532 6af0bf9c bellard
}
533 6af0bf9c bellard
534 6af0bf9c bellard
void op_srav (void)
535 6af0bf9c bellard
{
536 c570fd16 ths
    T0 = SIGN_EXTEND32((int32_t)T1 >> (T0 & 0x1F));
537 6af0bf9c bellard
    RETURN();
538 6af0bf9c bellard
}
539 6af0bf9c bellard
540 6af0bf9c bellard
void op_srlv (void)
541 6af0bf9c bellard
{
542 c570fd16 ths
    T0 = SIGN_EXTEND32((uint32_t)T1 >> (T0 & 0x1F));
543 6af0bf9c bellard
    RETURN();
544 6af0bf9c bellard
}
545 6af0bf9c bellard
546 7a387fff ths
void op_rotrv (void)
547 7a387fff ths
{
548 7a387fff ths
    target_ulong tmp;
549 7a387fff ths
550 7a387fff ths
    T0 &= 0x1F;
551 7a387fff ths
    if (T0) {
552 c570fd16 ths
       tmp = SIGN_EXTEND32((uint32_t)T1 << (0x20 - T0));
553 c570fd16 ths
       T0 = SIGN_EXTEND32((uint32_t)T1 >> T0) | tmp;
554 7a387fff ths
    } else
555 7a387fff ths
       T0 = T1;
556 7a387fff ths
    RETURN();
557 7a387fff ths
}
558 7a387fff ths
559 6af0bf9c bellard
void op_clo (void)
560 6af0bf9c bellard
{
561 6af0bf9c bellard
    int n;
562 6af0bf9c bellard
563 c570fd16 ths
    if (T0 == ~((target_ulong)0)) {
564 6af0bf9c bellard
        T0 = 32;
565 6af0bf9c bellard
    } else {
566 6af0bf9c bellard
        for (n = 0; n < 32; n++) {
567 6af0bf9c bellard
            if (!(T0 & (1 << 31)))
568 6af0bf9c bellard
                break;
569 6af0bf9c bellard
            T0 = T0 << 1;
570 6af0bf9c bellard
        }
571 6af0bf9c bellard
        T0 = n;
572 6af0bf9c bellard
    }
573 6af0bf9c bellard
    RETURN();
574 6af0bf9c bellard
}
575 6af0bf9c bellard
576 6af0bf9c bellard
void op_clz (void)
577 6af0bf9c bellard
{
578 6af0bf9c bellard
    int n;
579 6af0bf9c bellard
580 6af0bf9c bellard
    if (T0 == 0) {
581 6af0bf9c bellard
        T0 = 32;
582 6af0bf9c bellard
    } else {
583 6af0bf9c bellard
        for (n = 0; n < 32; n++) {
584 6af0bf9c bellard
            if (T0 & (1 << 31))
585 6af0bf9c bellard
                break;
586 6af0bf9c bellard
            T0 = T0 << 1;
587 6af0bf9c bellard
        }
588 6af0bf9c bellard
        T0 = n;
589 6af0bf9c bellard
    }
590 6af0bf9c bellard
    RETURN();
591 6af0bf9c bellard
}
592 6af0bf9c bellard
593 c570fd16 ths
#ifdef MIPS_HAS_MIPS64
594 c570fd16 ths
595 c570fd16 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
596 c570fd16 ths
/* Those might call libgcc functions.  */
597 c570fd16 ths
void op_dsll (void)
598 6af0bf9c bellard
{
599 c570fd16 ths
    CALL_FROM_TB0(do_dsll);
600 c570fd16 ths
    RETURN();
601 6af0bf9c bellard
}
602 6af0bf9c bellard
603 c570fd16 ths
void op_dsll32 (void)
604 6af0bf9c bellard
{
605 c570fd16 ths
    CALL_FROM_TB0(do_dsll32);
606 c570fd16 ths
    RETURN();
607 6af0bf9c bellard
}
608 6af0bf9c bellard
609 c570fd16 ths
void op_dsra (void)
610 6af0bf9c bellard
{
611 c570fd16 ths
    CALL_FROM_TB0(do_dsra);
612 6af0bf9c bellard
    RETURN();
613 6af0bf9c bellard
}
614 6af0bf9c bellard
615 c570fd16 ths
void op_dsra32 (void)
616 6af0bf9c bellard
{
617 c570fd16 ths
    CALL_FROM_TB0(do_dsra32);
618 6af0bf9c bellard
    RETURN();
619 6af0bf9c bellard
}
620 6af0bf9c bellard
621 c570fd16 ths
void op_dsrl (void)
622 6af0bf9c bellard
{
623 c570fd16 ths
    CALL_FROM_TB0(do_dsrl);
624 c570fd16 ths
    RETURN();
625 c570fd16 ths
}
626 6af0bf9c bellard
627 c570fd16 ths
void op_dsrl32 (void)
628 c570fd16 ths
{
629 c570fd16 ths
    CALL_FROM_TB0(do_dsrl32);
630 6af0bf9c bellard
    RETURN();
631 6af0bf9c bellard
}
632 6af0bf9c bellard
633 c570fd16 ths
void op_drotr (void)
634 6af0bf9c bellard
{
635 c570fd16 ths
    CALL_FROM_TB0(do_drotr);
636 c570fd16 ths
    RETURN();
637 c570fd16 ths
}
638 6af0bf9c bellard
639 c570fd16 ths
void op_drotr32 (void)
640 c570fd16 ths
{
641 c570fd16 ths
    CALL_FROM_TB0(do_drotr32);
642 6af0bf9c bellard
    RETURN();
643 6af0bf9c bellard
}
644 6af0bf9c bellard
645 c570fd16 ths
void op_dsllv (void)
646 6af0bf9c bellard
{
647 c570fd16 ths
    CALL_FROM_TB0(do_dsllv);
648 c570fd16 ths
    RETURN();
649 c570fd16 ths
}
650 6af0bf9c bellard
651 c570fd16 ths
void op_dsrav (void)
652 c570fd16 ths
{
653 c570fd16 ths
    CALL_FROM_TB0(do_dsrav);
654 6af0bf9c bellard
    RETURN();
655 6af0bf9c bellard
}
656 6af0bf9c bellard
657 c570fd16 ths
void op_dsrlv (void)
658 6af0bf9c bellard
{
659 c570fd16 ths
    CALL_FROM_TB0(do_dsrlv);
660 c570fd16 ths
    RETURN();
661 c570fd16 ths
}
662 6af0bf9c bellard
663 c570fd16 ths
void op_drotrv (void)
664 c570fd16 ths
{
665 c570fd16 ths
    CALL_FROM_TB0(do_drotrv);
666 6af0bf9c bellard
    RETURN();
667 6af0bf9c bellard
}
668 c570fd16 ths
669 c570fd16 ths
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
670 c570fd16 ths
671 c570fd16 ths
void op_dsll (void)
672 c570fd16 ths
{
673 c570fd16 ths
    T0 = T0 << T1;
674 c570fd16 ths
    RETURN();
675 c570fd16 ths
}
676 c570fd16 ths
677 c570fd16 ths
void op_dsll32 (void)
678 c570fd16 ths
{
679 c570fd16 ths
    T0 = T0 << (T1 + 32);
680 c570fd16 ths
    RETURN();
681 c570fd16 ths
}
682 c570fd16 ths
683 c570fd16 ths
void op_dsra (void)
684 c570fd16 ths
{
685 c570fd16 ths
    T0 = (int64_t)T0 >> T1;
686 c570fd16 ths
    RETURN();
687 c570fd16 ths
}
688 c570fd16 ths
689 c570fd16 ths
void op_dsra32 (void)
690 c570fd16 ths
{
691 c570fd16 ths
    T0 = (int64_t)T0 >> (T1 + 32);
692 c570fd16 ths
    RETURN();
693 c570fd16 ths
}
694 c570fd16 ths
695 c570fd16 ths
void op_dsrl (void)
696 c570fd16 ths
{
697 c570fd16 ths
    T0 = T0 >> T1;
698 c570fd16 ths
    RETURN();
699 c570fd16 ths
}
700 c570fd16 ths
701 c570fd16 ths
void op_dsrl32 (void)
702 c570fd16 ths
{
703 c570fd16 ths
    T0 = T0 >> (T1 + 32);
704 c570fd16 ths
    RETURN();
705 c570fd16 ths
}
706 c570fd16 ths
707 c570fd16 ths
void op_drotr (void)
708 c570fd16 ths
{
709 c570fd16 ths
    target_ulong tmp;
710 c570fd16 ths
711 c570fd16 ths
    if (T1) {
712 c570fd16 ths
       tmp = T0 << (0x40 - T1);
713 c570fd16 ths
       T0 = (T0 >> T1) | tmp;
714 c570fd16 ths
    } else
715 c570fd16 ths
       T0 = T1;
716 c570fd16 ths
    RETURN();
717 c570fd16 ths
}
718 c570fd16 ths
719 c570fd16 ths
void op_drotr32 (void)
720 c570fd16 ths
{
721 c570fd16 ths
    target_ulong tmp;
722 c570fd16 ths
723 c570fd16 ths
    if (T1) {
724 c570fd16 ths
       tmp = T0 << (0x40 - (32 + T1));
725 c570fd16 ths
       T0 = (T0 >> (32 + T1)) | tmp;
726 c570fd16 ths
    } else
727 c570fd16 ths
       T0 = T1;
728 c570fd16 ths
    RETURN();
729 c570fd16 ths
}
730 c570fd16 ths
731 c570fd16 ths
void op_dsllv (void)
732 c570fd16 ths
{
733 c570fd16 ths
    T0 = T1 << (T0 & 0x3F);
734 c570fd16 ths
    RETURN();
735 c570fd16 ths
}
736 c570fd16 ths
737 c570fd16 ths
void op_dsrav (void)
738 c570fd16 ths
{
739 c570fd16 ths
    T0 = (int64_t)T1 >> (T0 & 0x3F);
740 c570fd16 ths
    RETURN();
741 c570fd16 ths
}
742 c570fd16 ths
743 c570fd16 ths
void op_dsrlv (void)
744 c570fd16 ths
{
745 c570fd16 ths
    T0 = T1 >> (T0 & 0x3F);
746 c570fd16 ths
    RETURN();
747 c570fd16 ths
}
748 c570fd16 ths
749 c570fd16 ths
void op_drotrv (void)
750 c570fd16 ths
{
751 c570fd16 ths
    target_ulong tmp;
752 c570fd16 ths
753 c570fd16 ths
    T0 &= 0x3F;
754 c570fd16 ths
    if (T0) {
755 c570fd16 ths
       tmp = T1 << (0x40 - T0);
756 c570fd16 ths
       T0 = (T1 >> T0) | tmp;
757 c570fd16 ths
    } else
758 c570fd16 ths
       T0 = T1;
759 c570fd16 ths
    RETURN();
760 c570fd16 ths
}
761 c570fd16 ths
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
762 c570fd16 ths
763 c570fd16 ths
void op_dclo (void)
764 c570fd16 ths
{
765 c570fd16 ths
    int n;
766 c570fd16 ths
767 c570fd16 ths
    if (T0 == ~((target_ulong)0)) {
768 c570fd16 ths
        T0 = 64;
769 c570fd16 ths
    } else {
770 c570fd16 ths
        for (n = 0; n < 64; n++) {
771 c570fd16 ths
            if (!(T0 & (1ULL << 63)))
772 c570fd16 ths
                break;
773 c570fd16 ths
            T0 = T0 << 1;
774 c570fd16 ths
        }
775 c570fd16 ths
        T0 = n;
776 c570fd16 ths
    }
777 c570fd16 ths
    RETURN();
778 c570fd16 ths
}
779 c570fd16 ths
780 c570fd16 ths
void op_dclz (void)
781 c570fd16 ths
{
782 c570fd16 ths
    int n;
783 c570fd16 ths
784 c570fd16 ths
    if (T0 == 0) {
785 c570fd16 ths
        T0 = 64;
786 c570fd16 ths
    } else {
787 c570fd16 ths
        for (n = 0; n < 64; n++) {
788 c570fd16 ths
            if (T0 & (1ULL << 63))
789 c570fd16 ths
                break;
790 c570fd16 ths
            T0 = T0 << 1;
791 c570fd16 ths
        }
792 c570fd16 ths
        T0 = n;
793 c570fd16 ths
    }
794 c570fd16 ths
    RETURN();
795 c570fd16 ths
}
796 c570fd16 ths
#endif
797 c570fd16 ths
798 c570fd16 ths
/* 64 bits arithmetic */
799 c570fd16 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
800 6af0bf9c bellard
void op_mult (void)
801 6af0bf9c bellard
{
802 6af0bf9c bellard
    CALL_FROM_TB0(do_mult);
803 6af0bf9c bellard
    RETURN();
804 6af0bf9c bellard
}
805 6af0bf9c bellard
806 6af0bf9c bellard
void op_multu (void)
807 6af0bf9c bellard
{
808 6af0bf9c bellard
    CALL_FROM_TB0(do_multu);
809 6af0bf9c bellard
    RETURN();
810 6af0bf9c bellard
}
811 6af0bf9c bellard
812 6af0bf9c bellard
void op_madd (void)
813 6af0bf9c bellard
{
814 6af0bf9c bellard
    CALL_FROM_TB0(do_madd);
815 6af0bf9c bellard
    RETURN();
816 6af0bf9c bellard
}
817 6af0bf9c bellard
818 6af0bf9c bellard
void op_maddu (void)
819 6af0bf9c bellard
{
820 6af0bf9c bellard
    CALL_FROM_TB0(do_maddu);
821 6af0bf9c bellard
    RETURN();
822 6af0bf9c bellard
}
823 6af0bf9c bellard
824 6af0bf9c bellard
void op_msub (void)
825 6af0bf9c bellard
{
826 6af0bf9c bellard
    CALL_FROM_TB0(do_msub);
827 6af0bf9c bellard
    RETURN();
828 6af0bf9c bellard
}
829 6af0bf9c bellard
830 6af0bf9c bellard
void op_msubu (void)
831 6af0bf9c bellard
{
832 6af0bf9c bellard
    CALL_FROM_TB0(do_msubu);
833 6af0bf9c bellard
    RETURN();
834 6af0bf9c bellard
}
835 c570fd16 ths
836 c570fd16 ths
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
837 c570fd16 ths
838 c570fd16 ths
static inline uint64_t get_HILO (void)
839 c570fd16 ths
{
840 c570fd16 ths
    return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
841 c570fd16 ths
}
842 c570fd16 ths
843 c570fd16 ths
static inline void set_HILO (uint64_t HILO)
844 c570fd16 ths
{
845 c570fd16 ths
    env->LO = SIGN_EXTEND32(HILO & 0xFFFFFFFF);
846 c570fd16 ths
    env->HI = SIGN_EXTEND32(HILO >> 32);
847 c570fd16 ths
}
848 c570fd16 ths
849 c570fd16 ths
void op_mult (void)
850 c570fd16 ths
{
851 c570fd16 ths
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
852 c570fd16 ths
    RETURN();
853 c570fd16 ths
}
854 c570fd16 ths
855 c570fd16 ths
void op_multu (void)
856 c570fd16 ths
{
857 c570fd16 ths
    set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
858 c570fd16 ths
    RETURN();
859 c570fd16 ths
}
860 c570fd16 ths
861 c570fd16 ths
void op_madd (void)
862 c570fd16 ths
{
863 c570fd16 ths
    int64_t tmp;
864 c570fd16 ths
865 c570fd16 ths
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
866 c570fd16 ths
    set_HILO((int64_t)get_HILO() + tmp);
867 c570fd16 ths
    RETURN();
868 c570fd16 ths
}
869 c570fd16 ths
870 c570fd16 ths
void op_maddu (void)
871 c570fd16 ths
{
872 c570fd16 ths
    uint64_t tmp;
873 c570fd16 ths
874 c570fd16 ths
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
875 c570fd16 ths
    set_HILO(get_HILO() + tmp);
876 c570fd16 ths
    RETURN();
877 c570fd16 ths
}
878 c570fd16 ths
879 c570fd16 ths
void op_msub (void)
880 c570fd16 ths
{
881 c570fd16 ths
    int64_t tmp;
882 c570fd16 ths
883 c570fd16 ths
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
884 c570fd16 ths
    set_HILO((int64_t)get_HILO() - tmp);
885 c570fd16 ths
    RETURN();
886 c570fd16 ths
}
887 c570fd16 ths
888 c570fd16 ths
void op_msubu (void)
889 c570fd16 ths
{
890 c570fd16 ths
    uint64_t tmp;
891 c570fd16 ths
892 c570fd16 ths
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
893 c570fd16 ths
    set_HILO(get_HILO() - tmp);
894 c570fd16 ths
    RETURN();
895 c570fd16 ths
}
896 c570fd16 ths
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
897 c570fd16 ths
898 c570fd16 ths
#ifdef MIPS_HAS_MIPS64
899 c570fd16 ths
void op_dmult (void)
900 c570fd16 ths
{
901 c570fd16 ths
    CALL_FROM_TB0(do_dmult);
902 c570fd16 ths
    RETURN();
903 c570fd16 ths
}
904 c570fd16 ths
905 c570fd16 ths
void op_dmultu (void)
906 c570fd16 ths
{
907 c570fd16 ths
    CALL_FROM_TB0(do_dmultu);
908 c570fd16 ths
    RETURN();
909 c570fd16 ths
}
910 6af0bf9c bellard
#endif
911 6af0bf9c bellard
912 6af0bf9c bellard
/* Conditional moves */
913 6af0bf9c bellard
void op_movn (void)
914 6af0bf9c bellard
{
915 6af0bf9c bellard
    if (T1 != 0)
916 6af0bf9c bellard
        env->gpr[PARAM1] = T0;
917 6af0bf9c bellard
    RETURN();
918 6af0bf9c bellard
}
919 6af0bf9c bellard
920 6af0bf9c bellard
void op_movz (void)
921 6af0bf9c bellard
{
922 6af0bf9c bellard
    if (T1 == 0)
923 6af0bf9c bellard
        env->gpr[PARAM1] = T0;
924 6af0bf9c bellard
    RETURN();
925 6af0bf9c bellard
}
926 6af0bf9c bellard
927 71fb7241 ths
#ifdef MIPS_USES_FPU
928 7a387fff ths
void op_movf (void)
929 7a387fff ths
{
930 7a387fff ths
    if (!(env->fcr31 & PARAM1))
931 7a387fff ths
        env->gpr[PARAM2] = env->gpr[PARAM3];
932 7a387fff ths
    RETURN();
933 7a387fff ths
}
934 7a387fff ths
935 7a387fff ths
void op_movt (void)
936 7a387fff ths
{
937 7a387fff ths
    if (env->fcr31 & PARAM1)
938 7a387fff ths
        env->gpr[PARAM2] = env->gpr[PARAM3];
939 7a387fff ths
    RETURN();
940 7a387fff ths
}
941 71fb7241 ths
#endif
942 7a387fff ths
943 6af0bf9c bellard
/* Tests */
944 6af0bf9c bellard
#define OP_COND(name, cond) \
945 6af0bf9c bellard
void glue(op_, name) (void) \
946 6af0bf9c bellard
{                           \
947 6af0bf9c bellard
    if (cond) {             \
948 6af0bf9c bellard
        T0 = 1;             \
949 6af0bf9c bellard
    } else {                \
950 6af0bf9c bellard
        T0 = 0;             \
951 6af0bf9c bellard
    }                       \
952 6af0bf9c bellard
    RETURN();               \
953 6af0bf9c bellard
}
954 6af0bf9c bellard
955 6af0bf9c bellard
OP_COND(eq, T0 == T1);
956 6af0bf9c bellard
OP_COND(ne, T0 != T1);
957 6af0bf9c bellard
OP_COND(ge, (int32_t)T0 >= (int32_t)T1);
958 6af0bf9c bellard
OP_COND(geu, T0 >= T1);
959 6af0bf9c bellard
OP_COND(lt, (int32_t)T0 < (int32_t)T1);
960 6af0bf9c bellard
OP_COND(ltu, T0 < T1);
961 6af0bf9c bellard
OP_COND(gez, (int32_t)T0 >= 0);
962 6af0bf9c bellard
OP_COND(gtz, (int32_t)T0 > 0);
963 6af0bf9c bellard
OP_COND(lez, (int32_t)T0 <= 0);
964 6af0bf9c bellard
OP_COND(ltz, (int32_t)T0 < 0);
965 6af0bf9c bellard
966 7a387fff ths
/* Branches */
967 6af0bf9c bellard
//#undef USE_DIRECT_JUMP
968 c53be334 bellard
969 c53be334 bellard
void OPPROTO op_goto_tb0(void)
970 c53be334 bellard
{
971 c53be334 bellard
    GOTO_TB(op_goto_tb0, PARAM1, 0);
972 7a387fff ths
    RETURN();
973 c53be334 bellard
}
974 c53be334 bellard
975 c53be334 bellard
void OPPROTO op_goto_tb1(void)
976 c53be334 bellard
{
977 c53be334 bellard
    GOTO_TB(op_goto_tb1, PARAM1, 1);
978 7a387fff ths
    RETURN();
979 c53be334 bellard
}
980 6af0bf9c bellard
981 6af0bf9c bellard
/* Branch to register */
982 6af0bf9c bellard
void op_save_breg_target (void)
983 6af0bf9c bellard
{
984 6af0bf9c bellard
    env->btarget = T2;
985 7a387fff ths
    RETURN();
986 6af0bf9c bellard
}
987 6af0bf9c bellard
988 6af0bf9c bellard
void op_restore_breg_target (void)
989 6af0bf9c bellard
{
990 6af0bf9c bellard
    T2 = env->btarget;
991 7a387fff ths
    RETURN();
992 6af0bf9c bellard
}
993 6af0bf9c bellard
994 6af0bf9c bellard
void op_breg (void)
995 6af0bf9c bellard
{
996 6af0bf9c bellard
    env->PC = T2;
997 6af0bf9c bellard
    RETURN();
998 6af0bf9c bellard
}
999 6af0bf9c bellard
1000 6af0bf9c bellard
void op_save_btarget (void)
1001 6af0bf9c bellard
{
1002 6af0bf9c bellard
    env->btarget = PARAM1;
1003 6af0bf9c bellard
    RETURN();
1004 6af0bf9c bellard
}
1005 6af0bf9c bellard
1006 6af0bf9c bellard
/* Conditional branch */
1007 6af0bf9c bellard
void op_set_bcond (void)
1008 6af0bf9c bellard
{
1009 6af0bf9c bellard
    T2 = T0;
1010 6af0bf9c bellard
    RETURN();
1011 6af0bf9c bellard
}
1012 6af0bf9c bellard
1013 6af0bf9c bellard
void op_save_bcond (void)
1014 6af0bf9c bellard
{
1015 6af0bf9c bellard
    env->bcond = T2;
1016 6af0bf9c bellard
    RETURN();
1017 6af0bf9c bellard
}
1018 6af0bf9c bellard
1019 6af0bf9c bellard
void op_restore_bcond (void)
1020 6af0bf9c bellard
{
1021 6af0bf9c bellard
    T2 = env->bcond;
1022 6af0bf9c bellard
    RETURN();
1023 6af0bf9c bellard
}
1024 6af0bf9c bellard
1025 c53be334 bellard
void op_jnz_T2 (void)
1026 6af0bf9c bellard
{
1027 c53be334 bellard
    if (T2)
1028 c53be334 bellard
        GOTO_LABEL_PARAM(1);
1029 6af0bf9c bellard
    RETURN();
1030 6af0bf9c bellard
}
1031 6af0bf9c bellard
1032 6af0bf9c bellard
/* CP0 functions */
1033 873eb012 ths
void op_mfc0_index (void)
1034 6af0bf9c bellard
{
1035 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_index);
1036 873eb012 ths
    RETURN();
1037 873eb012 ths
}
1038 873eb012 ths
1039 873eb012 ths
void op_mfc0_random (void)
1040 873eb012 ths
{
1041 873eb012 ths
    CALL_FROM_TB0(do_mfc0_random);
1042 873eb012 ths
    RETURN();
1043 873eb012 ths
}
1044 873eb012 ths
1045 873eb012 ths
void op_mfc0_entrylo0 (void)
1046 873eb012 ths
{
1047 873eb012 ths
    T0 = env->CP0_EntryLo0;
1048 873eb012 ths
    RETURN();
1049 873eb012 ths
}
1050 873eb012 ths
1051 873eb012 ths
void op_mfc0_entrylo1 (void)
1052 873eb012 ths
{
1053 873eb012 ths
    T0 = env->CP0_EntryLo1;
1054 873eb012 ths
    RETURN();
1055 873eb012 ths
}
1056 873eb012 ths
1057 873eb012 ths
void op_mfc0_context (void)
1058 873eb012 ths
{
1059 873eb012 ths
    T0 = env->CP0_Context;
1060 873eb012 ths
    RETURN();
1061 873eb012 ths
}
1062 873eb012 ths
1063 873eb012 ths
void op_mfc0_pagemask (void)
1064 873eb012 ths
{
1065 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_PageMask);
1066 873eb012 ths
    RETURN();
1067 873eb012 ths
}
1068 873eb012 ths
1069 7a387fff ths
void op_mfc0_pagegrain (void)
1070 7a387fff ths
{
1071 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_PageGrain);
1072 7a387fff ths
    RETURN();
1073 7a387fff ths
}
1074 7a387fff ths
1075 873eb012 ths
void op_mfc0_wired (void)
1076 873eb012 ths
{
1077 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Wired);
1078 873eb012 ths
    RETURN();
1079 873eb012 ths
}
1080 873eb012 ths
1081 7a387fff ths
void op_mfc0_hwrena (void)
1082 7a387fff ths
{
1083 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_HWREna);
1084 7a387fff ths
    RETURN();
1085 7a387fff ths
}
1086 7a387fff ths
1087 873eb012 ths
void op_mfc0_badvaddr (void)
1088 873eb012 ths
{
1089 873eb012 ths
    T0 = env->CP0_BadVAddr;
1090 873eb012 ths
    RETURN();
1091 873eb012 ths
}
1092 873eb012 ths
1093 873eb012 ths
void op_mfc0_count (void)
1094 873eb012 ths
{
1095 873eb012 ths
    CALL_FROM_TB0(do_mfc0_count);
1096 873eb012 ths
    RETURN();
1097 873eb012 ths
}
1098 873eb012 ths
1099 873eb012 ths
void op_mfc0_entryhi (void)
1100 873eb012 ths
{
1101 873eb012 ths
    T0 = env->CP0_EntryHi;
1102 873eb012 ths
    RETURN();
1103 873eb012 ths
}
1104 873eb012 ths
1105 873eb012 ths
void op_mfc0_compare (void)
1106 873eb012 ths
{
1107 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Compare);
1108 873eb012 ths
    RETURN();
1109 873eb012 ths
}
1110 873eb012 ths
1111 873eb012 ths
void op_mfc0_status (void)
1112 873eb012 ths
{
1113 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Status);
1114 873eb012 ths
    if (env->hflags & MIPS_HFLAG_UM)
1115 873eb012 ths
        T0 |= (1 << CP0St_UM);
1116 873eb012 ths
    if (env->hflags & MIPS_HFLAG_ERL)
1117 873eb012 ths
        T0 |= (1 << CP0St_ERL);
1118 873eb012 ths
    if (env->hflags & MIPS_HFLAG_EXL)
1119 873eb012 ths
        T0 |= (1 << CP0St_EXL);
1120 873eb012 ths
    RETURN();
1121 873eb012 ths
}
1122 873eb012 ths
1123 7a387fff ths
void op_mfc0_intctl (void)
1124 7a387fff ths
{
1125 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_IntCtl);
1126 7a387fff ths
    RETURN();
1127 7a387fff ths
}
1128 7a387fff ths
1129 7a387fff ths
void op_mfc0_srsctl (void)
1130 7a387fff ths
{
1131 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_SRSCtl);
1132 7a387fff ths
    RETURN();
1133 7a387fff ths
}
1134 7a387fff ths
1135 873eb012 ths
void op_mfc0_cause (void)
1136 873eb012 ths
{
1137 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Cause);
1138 873eb012 ths
    RETURN();
1139 873eb012 ths
}
1140 873eb012 ths
1141 873eb012 ths
void op_mfc0_epc (void)
1142 873eb012 ths
{
1143 873eb012 ths
    T0 = env->CP0_EPC;
1144 873eb012 ths
    RETURN();
1145 873eb012 ths
}
1146 873eb012 ths
1147 873eb012 ths
void op_mfc0_prid (void)
1148 873eb012 ths
{
1149 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_PRid);
1150 873eb012 ths
    RETURN();
1151 873eb012 ths
}
1152 873eb012 ths
1153 7a387fff ths
void op_mfc0_ebase (void)
1154 7a387fff ths
{
1155 7a387fff ths
    T0 = env->CP0_EBase;
1156 7a387fff ths
    RETURN();
1157 7a387fff ths
}
1158 7a387fff ths
1159 873eb012 ths
void op_mfc0_config0 (void)
1160 873eb012 ths
{
1161 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Config0);
1162 873eb012 ths
    RETURN();
1163 873eb012 ths
}
1164 873eb012 ths
1165 873eb012 ths
void op_mfc0_config1 (void)
1166 873eb012 ths
{
1167 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Config1);
1168 873eb012 ths
    RETURN();
1169 873eb012 ths
}
1170 873eb012 ths
1171 7a387fff ths
void op_mfc0_config2 (void)
1172 7a387fff ths
{
1173 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Config2);
1174 7a387fff ths
    RETURN();
1175 7a387fff ths
}
1176 7a387fff ths
1177 7a387fff ths
void op_mfc0_config3 (void)
1178 7a387fff ths
{
1179 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Config3);
1180 7a387fff ths
    RETURN();
1181 7a387fff ths
}
1182 7a387fff ths
1183 873eb012 ths
void op_mfc0_lladdr (void)
1184 873eb012 ths
{
1185 873eb012 ths
    T0 = env->CP0_LLAddr >> 4;
1186 873eb012 ths
    RETURN();
1187 873eb012 ths
}
1188 873eb012 ths
1189 7a387fff ths
void op_mfc0_watchlo0 (void)
1190 873eb012 ths
{
1191 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_WatchLo);
1192 873eb012 ths
    RETURN();
1193 873eb012 ths
}
1194 873eb012 ths
1195 7a387fff ths
void op_mfc0_watchhi0 (void)
1196 873eb012 ths
{
1197 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_WatchHi);
1198 873eb012 ths
    RETURN();
1199 873eb012 ths
}
1200 873eb012 ths
1201 7a387fff ths
void op_mfc0_xcontext (void)
1202 7a387fff ths
{
1203 7a387fff ths
    T0 = env->CP0_XContext;
1204 7a387fff ths
    RETURN();
1205 7a387fff ths
}
1206 7a387fff ths
1207 7a387fff ths
void op_mfc0_framemask (void)
1208 7a387fff ths
{
1209 7a387fff ths
    T0 = env->CP0_Framemask;
1210 7a387fff ths
    RETURN();
1211 7a387fff ths
}
1212 7a387fff ths
1213 873eb012 ths
void op_mfc0_debug (void)
1214 873eb012 ths
{
1215 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Debug);
1216 873eb012 ths
    if (env->hflags & MIPS_HFLAG_DM)
1217 873eb012 ths
        T0 |= 1 << CP0DB_DM;
1218 873eb012 ths
    RETURN();
1219 873eb012 ths
}
1220 873eb012 ths
1221 873eb012 ths
void op_mfc0_depc (void)
1222 873eb012 ths
{
1223 873eb012 ths
    T0 = env->CP0_DEPC;
1224 873eb012 ths
    RETURN();
1225 873eb012 ths
}
1226 873eb012 ths
1227 7a387fff ths
void op_mfc0_performance0 (void)
1228 7a387fff ths
{
1229 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_Performance0);
1230 7a387fff ths
    RETURN();
1231 7a387fff ths
}
1232 7a387fff ths
1233 873eb012 ths
void op_mfc0_taglo (void)
1234 873eb012 ths
{
1235 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_TagLo);
1236 873eb012 ths
    RETURN();
1237 873eb012 ths
}
1238 873eb012 ths
1239 873eb012 ths
void op_mfc0_datalo (void)
1240 873eb012 ths
{
1241 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_DataLo);
1242 873eb012 ths
    RETURN();
1243 873eb012 ths
}
1244 873eb012 ths
1245 7a387fff ths
void op_mfc0_taghi (void)
1246 7a387fff ths
{
1247 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_TagHi);
1248 7a387fff ths
    RETURN();
1249 7a387fff ths
}
1250 7a387fff ths
1251 7a387fff ths
void op_mfc0_datahi (void)
1252 7a387fff ths
{
1253 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_DataHi);
1254 7a387fff ths
    RETURN();
1255 7a387fff ths
}
1256 7a387fff ths
1257 873eb012 ths
void op_mfc0_errorepc (void)
1258 873eb012 ths
{
1259 873eb012 ths
    T0 = env->CP0_ErrorEPC;
1260 873eb012 ths
    RETURN();
1261 873eb012 ths
}
1262 873eb012 ths
1263 873eb012 ths
void op_mfc0_desave (void)
1264 873eb012 ths
{
1265 c570fd16 ths
    T0 = SIGN_EXTEND32(env->CP0_DESAVE);
1266 6af0bf9c bellard
    RETURN();
1267 6af0bf9c bellard
}
1268 6af0bf9c bellard
1269 8c0fdd85 ths
void op_mtc0_index (void)
1270 6af0bf9c bellard
{
1271 7a387fff ths
    env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1));
1272 8c0fdd85 ths
    RETURN();
1273 8c0fdd85 ths
}
1274 8c0fdd85 ths
1275 8c0fdd85 ths
void op_mtc0_entrylo0 (void)
1276 8c0fdd85 ths
{
1277 7a387fff ths
    /* Large physaddr not implemented */
1278 7a387fff ths
    /* 1k pages not implemented */
1279 c570fd16 ths
    env->CP0_EntryLo0 = T0 & SIGN_EXTEND32(0x3FFFFFFFUL);
1280 8c0fdd85 ths
    RETURN();
1281 8c0fdd85 ths
}
1282 8c0fdd85 ths
1283 8c0fdd85 ths
void op_mtc0_entrylo1 (void)
1284 8c0fdd85 ths
{
1285 7a387fff ths
    /* Large physaddr not implemented */
1286 7a387fff ths
    /* 1k pages not implemented */
1287 c570fd16 ths
    env->CP0_EntryLo1 = T0 & SIGN_EXTEND32(0x3FFFFFFFUL);
1288 8c0fdd85 ths
    RETURN();
1289 8c0fdd85 ths
}
1290 8c0fdd85 ths
1291 8c0fdd85 ths
void op_mtc0_context (void)
1292 8c0fdd85 ths
{
1293 7a387fff ths
    env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0);
1294 8c0fdd85 ths
    RETURN();
1295 8c0fdd85 ths
}
1296 8c0fdd85 ths
1297 8c0fdd85 ths
void op_mtc0_pagemask (void)
1298 8c0fdd85 ths
{
1299 7a387fff ths
    /* 1k pages not implemented */
1300 7a387fff ths
    env->CP0_PageMask = T0 & 0x1FFFE000;
1301 7a387fff ths
    RETURN();
1302 7a387fff ths
}
1303 7a387fff ths
1304 7a387fff ths
void op_mtc0_pagegrain (void)
1305 7a387fff ths
{
1306 7a387fff ths
    /* SmartMIPS not implemented */
1307 7a387fff ths
    /* Large physaddr not implemented */
1308 7a387fff ths
    /* 1k pages not implemented */
1309 7a387fff ths
    env->CP0_PageGrain = 0;
1310 8c0fdd85 ths
    RETURN();
1311 8c0fdd85 ths
}
1312 8c0fdd85 ths
1313 8c0fdd85 ths
void op_mtc0_wired (void)
1314 8c0fdd85 ths
{
1315 7a387fff ths
    env->CP0_Wired = T0 & (MIPS_TLB_NB - 1);
1316 7a387fff ths
    RETURN();
1317 7a387fff ths
}
1318 7a387fff ths
1319 7a387fff ths
void op_mtc0_hwrena (void)
1320 7a387fff ths
{
1321 7a387fff ths
    env->CP0_HWREna = T0 & 0x0000000F;
1322 8c0fdd85 ths
    RETURN();
1323 8c0fdd85 ths
}
1324 8c0fdd85 ths
1325 8c0fdd85 ths
void op_mtc0_count (void)
1326 8c0fdd85 ths
{
1327 8c0fdd85 ths
    CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1328 8c0fdd85 ths
    RETURN();
1329 8c0fdd85 ths
}
1330 8c0fdd85 ths
1331 8c0fdd85 ths
void op_mtc0_entryhi (void)
1332 8c0fdd85 ths
{
1333 8c0fdd85 ths
    uint32_t old, val;
1334 8c0fdd85 ths
1335 7a387fff ths
    /* 1k pages not implemented */
1336 7a387fff ths
    /* Ignore MIPS64 TLB for now */
1337 c570fd16 ths
    val = T0 & SIGN_EXTEND32(0xFFFFE0FF);
1338 8c0fdd85 ths
    old = env->CP0_EntryHi;
1339 8c0fdd85 ths
    env->CP0_EntryHi = val;
1340 8c0fdd85 ths
    /* If the ASID changes, flush qemu's TLB.  */
1341 8c0fdd85 ths
    if ((old & 0xFF) != (val & 0xFF))
1342 8c0fdd85 ths
        CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1343 8c0fdd85 ths
    RETURN();
1344 8c0fdd85 ths
}
1345 8c0fdd85 ths
1346 8c0fdd85 ths
void op_mtc0_compare (void)
1347 8c0fdd85 ths
{
1348 8c0fdd85 ths
    CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1349 8c0fdd85 ths
    RETURN();
1350 8c0fdd85 ths
}
1351 8c0fdd85 ths
1352 8c0fdd85 ths
void op_mtc0_status (void)
1353 8c0fdd85 ths
{
1354 8c0fdd85 ths
    uint32_t val, old, mask;
1355 8c0fdd85 ths
1356 c570fd16 ths
    val = T0 & SIGN_EXTEND32(0xFA78FF01);
1357 8c0fdd85 ths
    old = env->CP0_Status;
1358 8c0fdd85 ths
    if (T0 & (1 << CP0St_UM))
1359 8c0fdd85 ths
        env->hflags |= MIPS_HFLAG_UM;
1360 8c0fdd85 ths
    else
1361 8c0fdd85 ths
        env->hflags &= ~MIPS_HFLAG_UM;
1362 8c0fdd85 ths
    if (T0 & (1 << CP0St_ERL))
1363 8c0fdd85 ths
        env->hflags |= MIPS_HFLAG_ERL;
1364 8c0fdd85 ths
    else
1365 8c0fdd85 ths
        env->hflags &= ~MIPS_HFLAG_ERL;
1366 8c0fdd85 ths
    if (T0 & (1 << CP0St_EXL))
1367 8c0fdd85 ths
        env->hflags |= MIPS_HFLAG_EXL;
1368 8c0fdd85 ths
    else
1369 8c0fdd85 ths
        env->hflags &= ~MIPS_HFLAG_EXL;
1370 8c0fdd85 ths
    env->CP0_Status = val;
1371 8c0fdd85 ths
    /* If we unmasked an asserted IRQ, raise it */
1372 8c0fdd85 ths
    mask = 0x0000FF00;
1373 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM)
1374 8c0fdd85 ths
       CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1375 8c0fdd85 ths
    if ((val & (1 << CP0St_IE)) && !(old & (1 << CP0St_IE)) &&
1376 8c0fdd85 ths
        !(env->hflags & MIPS_HFLAG_EXL) &&
1377 8c0fdd85 ths
        !(env->hflags & MIPS_HFLAG_ERL) &&
1378 8c0fdd85 ths
        !(env->hflags & MIPS_HFLAG_DM) &&
1379 8c0fdd85 ths
        (env->CP0_Status & env->CP0_Cause & mask)) {
1380 8c0fdd85 ths
        env->interrupt_request |= CPU_INTERRUPT_HARD;
1381 8c0fdd85 ths
       if (logfile)
1382 8c0fdd85 ths
           CALL_FROM_TB0(do_mtc0_status_irqraise_debug);
1383 8c0fdd85 ths
    } else if (!(val & (1 << CP0St_IE)) && (old & (1 << CP0St_IE))) {
1384 8c0fdd85 ths
        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
1385 8c0fdd85 ths
    }
1386 8c0fdd85 ths
    RETURN();
1387 8c0fdd85 ths
}
1388 8c0fdd85 ths
1389 7a387fff ths
void op_mtc0_intctl (void)
1390 7a387fff ths
{
1391 7a387fff ths
    /* vectored interrupts not implemented */
1392 7a387fff ths
    env->CP0_IntCtl = 0;
1393 7a387fff ths
    RETURN();
1394 7a387fff ths
}
1395 7a387fff ths
1396 7a387fff ths
void op_mtc0_srsctl (void)
1397 7a387fff ths
{
1398 7a387fff ths
    /* shadow registers not implemented */
1399 7a387fff ths
    env->CP0_SRSCtl = 0;
1400 7a387fff ths
    RETURN();
1401 7a387fff ths
}
1402 7a387fff ths
1403 8c0fdd85 ths
void op_mtc0_cause (void)
1404 8c0fdd85 ths
{
1405 8c0fdd85 ths
    uint32_t val, old;
1406 8c0fdd85 ths
1407 c570fd16 ths
    val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300);
1408 8c0fdd85 ths
    old = env->CP0_Cause;
1409 8c0fdd85 ths
    env->CP0_Cause = val;
1410 8c0fdd85 ths
#if 0
1411 8c0fdd85 ths
    {
1412 8c0fdd85 ths
        int i, mask;
1413 8c0fdd85 ths
       /* Check if we ever asserted a software IRQ */
1414 8c0fdd85 ths
        for (i = 0; i < 2; i++) {
1415 8c0fdd85 ths
            mask = 0x100 << i;
1416 8c0fdd85 ths
            if ((val & mask) & !(old & mask))
1417 8c0fdd85 ths
                CALL_FROM_TB1(mips_set_irq, i);
1418 8c0fdd85 ths
        }
1419 8c0fdd85 ths
    }
1420 8c0fdd85 ths
#endif
1421 8c0fdd85 ths
    RETURN();
1422 8c0fdd85 ths
}
1423 8c0fdd85 ths
1424 8c0fdd85 ths
void op_mtc0_epc (void)
1425 8c0fdd85 ths
{
1426 8c0fdd85 ths
    env->CP0_EPC = T0;
1427 8c0fdd85 ths
    RETURN();
1428 8c0fdd85 ths
}
1429 8c0fdd85 ths
1430 7a387fff ths
void op_mtc0_ebase (void)
1431 7a387fff ths
{
1432 7a387fff ths
    /* vectored interrupts not implemented */
1433 7a387fff ths
    /* Multi-CPU not implemented */
1434 c570fd16 ths
    env->CP0_EBase = SIGN_EXTEND32(0x80000000) | (T0 & 0x3FFFF000);
1435 7a387fff ths
    RETURN();
1436 7a387fff ths
}
1437 7a387fff ths
1438 8c0fdd85 ths
void op_mtc0_config0 (void)
1439 8c0fdd85 ths
{
1440 8c0fdd85 ths
#if defined(MIPS_USES_R4K_TLB)
1441 7a387fff ths
     /* Fixed mapping MMU not implemented */
1442 7a387fff ths
    env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF88) | (T0 & 0x00000001);
1443 8c0fdd85 ths
#else
1444 7a387fff ths
    env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF88) | (T0 & 0x00000001);
1445 8c0fdd85 ths
#endif
1446 8c0fdd85 ths
    RETURN();
1447 8c0fdd85 ths
}
1448 8c0fdd85 ths
1449 7a387fff ths
void op_mtc0_config2 (void)
1450 7a387fff ths
{
1451 7a387fff ths
    /* tertiary/secondary caches not implemented */
1452 7a387fff ths
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1453 7a387fff ths
    RETURN();
1454 7a387fff ths
}
1455 7a387fff ths
1456 7a387fff ths
void op_mtc0_watchlo0 (void)
1457 8c0fdd85 ths
{
1458 8c0fdd85 ths
    env->CP0_WatchLo = T0;
1459 8c0fdd85 ths
    RETURN();
1460 8c0fdd85 ths
}
1461 8c0fdd85 ths
1462 7a387fff ths
void op_mtc0_watchhi0 (void)
1463 8c0fdd85 ths
{
1464 8c0fdd85 ths
    env->CP0_WatchHi = T0 & 0x40FF0FF8;
1465 8c0fdd85 ths
    RETURN();
1466 8c0fdd85 ths
}
1467 8c0fdd85 ths
1468 7a387fff ths
void op_mtc0_xcontext (void)
1469 7a387fff ths
{
1470 7a387fff ths
    env->CP0_XContext = T0; /* XXX */
1471 7a387fff ths
    RETURN();
1472 7a387fff ths
}
1473 7a387fff ths
1474 7a387fff ths
void op_mtc0_framemask (void)
1475 7a387fff ths
{
1476 7a387fff ths
    env->CP0_Framemask = T0; /* XXX */
1477 7a387fff ths
    RETURN();
1478 7a387fff ths
}
1479 7a387fff ths
1480 8c0fdd85 ths
void op_mtc0_debug (void)
1481 8c0fdd85 ths
{
1482 8c0fdd85 ths
    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1483 8c0fdd85 ths
    if (T0 & (1 << CP0DB_DM))
1484 8c0fdd85 ths
        env->hflags |= MIPS_HFLAG_DM;
1485 8c0fdd85 ths
    else
1486 8c0fdd85 ths
        env->hflags &= ~MIPS_HFLAG_DM;
1487 8c0fdd85 ths
    RETURN();
1488 8c0fdd85 ths
}
1489 8c0fdd85 ths
1490 8c0fdd85 ths
void op_mtc0_depc (void)
1491 8c0fdd85 ths
{
1492 8c0fdd85 ths
    env->CP0_DEPC = T0;
1493 8c0fdd85 ths
    RETURN();
1494 8c0fdd85 ths
}
1495 8c0fdd85 ths
1496 7a387fff ths
void op_mtc0_performance0 (void)
1497 7a387fff ths
{
1498 7a387fff ths
    env->CP0_Performance0 = T0; /* XXX */
1499 7a387fff ths
    RETURN();
1500 7a387fff ths
}
1501 7a387fff ths
1502 8c0fdd85 ths
void op_mtc0_taglo (void)
1503 8c0fdd85 ths
{
1504 c570fd16 ths
    env->CP0_TagLo = T0 & SIGN_EXTEND32(0xFFFFFCF6);
1505 8c0fdd85 ths
    RETURN();
1506 8c0fdd85 ths
}
1507 8c0fdd85 ths
1508 7a387fff ths
void op_mtc0_datalo (void)
1509 7a387fff ths
{
1510 7a387fff ths
    env->CP0_DataLo = T0; /* XXX */
1511 7a387fff ths
    RETURN();
1512 7a387fff ths
}
1513 7a387fff ths
1514 7a387fff ths
void op_mtc0_taghi (void)
1515 7a387fff ths
{
1516 7a387fff ths
    env->CP0_TagHi = T0; /* XXX */
1517 7a387fff ths
    RETURN();
1518 7a387fff ths
}
1519 7a387fff ths
1520 7a387fff ths
void op_mtc0_datahi (void)
1521 7a387fff ths
{
1522 7a387fff ths
    env->CP0_DataHi = T0; /* XXX */
1523 7a387fff ths
    RETURN();
1524 7a387fff ths
}
1525 7a387fff ths
1526 8c0fdd85 ths
void op_mtc0_errorepc (void)
1527 8c0fdd85 ths
{
1528 8c0fdd85 ths
    env->CP0_ErrorEPC = T0;
1529 8c0fdd85 ths
    RETURN();
1530 8c0fdd85 ths
}
1531 8c0fdd85 ths
1532 8c0fdd85 ths
void op_mtc0_desave (void)
1533 8c0fdd85 ths
{
1534 8c0fdd85 ths
    env->CP0_DESAVE = T0;
1535 6af0bf9c bellard
    RETURN();
1536 6af0bf9c bellard
}
1537 6af0bf9c bellard
1538 6ea83fed bellard
#ifdef MIPS_USES_FPU
1539 6ea83fed bellard
1540 6ea83fed bellard
#if 0
1541 6ea83fed bellard
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1542 6ea83fed bellard
#else
1543 6ea83fed bellard
# define DEBUG_FPU_STATE() do { } while(0)
1544 6ea83fed bellard
#endif
1545 6ea83fed bellard
1546 6ea83fed bellard
void op_cp1_enabled(void)
1547 6ea83fed bellard
{
1548 6ea83fed bellard
    if (!(env->CP0_Status & (1 << CP0St_CU1))) {
1549 6ea83fed bellard
        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
1550 6ea83fed bellard
    }
1551 6ea83fed bellard
    RETURN();
1552 6ea83fed bellard
}
1553 6ea83fed bellard
1554 6ea83fed bellard
/* CP1 functions */
1555 6ea83fed bellard
void op_cfc1 (void)
1556 6ea83fed bellard
{
1557 6ea83fed bellard
    if (T1 == 0) {
1558 6ea83fed bellard
        T0 = env->fcr0;
1559 6ea83fed bellard
    }
1560 6ea83fed bellard
    else {
1561 6ea83fed bellard
        /* fetch fcr31, masking unused bits */
1562 6ea83fed bellard
        T0 = env->fcr31 & 0x0183FFFF;
1563 6ea83fed bellard
    }
1564 6ea83fed bellard
    DEBUG_FPU_STATE();
1565 6ea83fed bellard
    RETURN();
1566 6ea83fed bellard
}
1567 6ea83fed bellard
1568 6ea83fed bellard
/* convert MIPS rounding mode in FCR31 to IEEE library */
1569 6ea83fed bellard
unsigned int ieee_rm[] = { 
1570 6ea83fed bellard
    float_round_nearest_even,
1571 6ea83fed bellard
    float_round_to_zero,
1572 6ea83fed bellard
    float_round_up,
1573 6ea83fed bellard
    float_round_down
1574 6ea83fed bellard
};
1575 6ea83fed bellard
1576 6ea83fed bellard
#define RESTORE_ROUNDING_MODE \
1577 6ea83fed bellard
    set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
1578 6ea83fed bellard
1579 6ea83fed bellard
void op_ctc1 (void)
1580 6ea83fed bellard
{
1581 6ea83fed bellard
    if (T1 == 0) {
1582 6ea83fed bellard
        /* XXX should this throw an exception?
1583 6ea83fed bellard
         * don't write to FCR0.
1584 6ea83fed bellard
         * env->fcr0 = T0; 
1585 6ea83fed bellard
         */
1586 6ea83fed bellard
    }
1587 6ea83fed bellard
    else {
1588 6ea83fed bellard
        /* store new fcr31, masking unused bits */  
1589 6ea83fed bellard
        env->fcr31 = T0 & 0x0183FFFF;
1590 6ea83fed bellard
1591 6ea83fed bellard
        /* set rounding mode */
1592 6ea83fed bellard
        RESTORE_ROUNDING_MODE;
1593 6ea83fed bellard
1594 6ea83fed bellard
#ifndef CONFIG_SOFTFLOAT
1595 6ea83fed bellard
        /* no floating point exception for native float */
1596 6ea83fed bellard
        SET_FP_ENABLE(env->fcr31, 0);
1597 6ea83fed bellard
#endif
1598 6ea83fed bellard
    }
1599 6ea83fed bellard
    DEBUG_FPU_STATE();
1600 6ea83fed bellard
    RETURN();
1601 6ea83fed bellard
}
1602 6ea83fed bellard
1603 6ea83fed bellard
void op_mfc1 (void)
1604 6ea83fed bellard
{
1605 6ea83fed bellard
    T0 = WT0;
1606 6ea83fed bellard
    DEBUG_FPU_STATE();
1607 6ea83fed bellard
    RETURN();
1608 6ea83fed bellard
}
1609 6ea83fed bellard
1610 6ea83fed bellard
void op_mtc1 (void)
1611 6ea83fed bellard
{
1612 6ea83fed bellard
    WT0 = T0;
1613 6ea83fed bellard
    DEBUG_FPU_STATE();
1614 6ea83fed bellard
    RETURN();
1615 6ea83fed bellard
}
1616 6ea83fed bellard
1617 6ea83fed bellard
/* Float support.
1618 6ea83fed bellard
   Single precition routines have a "s" suffix, double precision a
1619 6ea83fed bellard
   "d" suffix.  */
1620 6ea83fed bellard
1621 6ea83fed bellard
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1622 6ea83fed bellard
1623 dd016883 bellard
FLOAT_OP(cvtd, s)
1624 dd016883 bellard
{
1625 dd016883 bellard
    FDT2 = float32_to_float64(WT0, &env->fp_status);
1626 dd016883 bellard
    DEBUG_FPU_STATE();
1627 dd016883 bellard
    RETURN();
1628 dd016883 bellard
}
1629 6ea83fed bellard
FLOAT_OP(cvtd, w)
1630 6ea83fed bellard
{
1631 6ea83fed bellard
    FDT2 = int32_to_float64(WT0, &env->fp_status);
1632 6ea83fed bellard
    DEBUG_FPU_STATE();
1633 6ea83fed bellard
    RETURN();
1634 6ea83fed bellard
}
1635 dd016883 bellard
FLOAT_OP(cvts, d)
1636 dd016883 bellard
{
1637 417f38f0 pbrook
    FST2 = float64_to_float32(FDT0, &env->fp_status);
1638 dd016883 bellard
    DEBUG_FPU_STATE();
1639 dd016883 bellard
    RETURN();
1640 dd016883 bellard
}
1641 6ea83fed bellard
FLOAT_OP(cvts, w)
1642 6ea83fed bellard
{
1643 6ea83fed bellard
    FST2 = int32_to_float32(WT0, &env->fp_status);
1644 6ea83fed bellard
    DEBUG_FPU_STATE();
1645 6ea83fed bellard
    RETURN();
1646 6ea83fed bellard
}
1647 6ea83fed bellard
FLOAT_OP(cvtw, s)
1648 6ea83fed bellard
{
1649 6ea83fed bellard
    WT2 = float32_to_int32(FST0, &env->fp_status);
1650 6ea83fed bellard
    DEBUG_FPU_STATE();
1651 6ea83fed bellard
    RETURN();
1652 6ea83fed bellard
}
1653 6ea83fed bellard
FLOAT_OP(cvtw, d)
1654 6ea83fed bellard
{
1655 6ea83fed bellard
    WT2 = float64_to_int32(FDT0, &env->fp_status);
1656 6ea83fed bellard
    DEBUG_FPU_STATE();
1657 6ea83fed bellard
    RETURN();
1658 6ea83fed bellard
}
1659 6ea83fed bellard
1660 6ea83fed bellard
FLOAT_OP(roundw, d)
1661 6ea83fed bellard
{
1662 6ea83fed bellard
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1663 6ea83fed bellard
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
1664 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
1665 6ea83fed bellard
1666 6ea83fed bellard
    DEBUG_FPU_STATE();
1667 6ea83fed bellard
    RETURN();
1668 6ea83fed bellard
}
1669 6ea83fed bellard
FLOAT_OP(roundw, s)
1670 6ea83fed bellard
{
1671 6ea83fed bellard
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1672 6ea83fed bellard
    WT2 = float32_round_to_int(FST0, &env->fp_status);
1673 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
1674 6ea83fed bellard
    DEBUG_FPU_STATE();
1675 6ea83fed bellard
    RETURN();
1676 6ea83fed bellard
}
1677 6ea83fed bellard
1678 6ea83fed bellard
FLOAT_OP(truncw, d)
1679 6ea83fed bellard
{
1680 6ea83fed bellard
    WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
1681 6ea83fed bellard
    DEBUG_FPU_STATE();
1682 6ea83fed bellard
    RETURN();
1683 6ea83fed bellard
}
1684 6ea83fed bellard
FLOAT_OP(truncw, s)
1685 6ea83fed bellard
{
1686 6ea83fed bellard
    WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
1687 6ea83fed bellard
    DEBUG_FPU_STATE();
1688 6ea83fed bellard
    RETURN();
1689 6ea83fed bellard
}
1690 6ea83fed bellard
1691 6ea83fed bellard
FLOAT_OP(ceilw, d)
1692 6ea83fed bellard
{
1693 6ea83fed bellard
    set_float_rounding_mode(float_round_up, &env->fp_status);
1694 6ea83fed bellard
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
1695 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
1696 6ea83fed bellard
1697 6ea83fed bellard
    DEBUG_FPU_STATE();
1698 6ea83fed bellard
    RETURN();
1699 6ea83fed bellard
}
1700 6ea83fed bellard
FLOAT_OP(ceilw, s)
1701 6ea83fed bellard
{
1702 6ea83fed bellard
    set_float_rounding_mode(float_round_up, &env->fp_status);
1703 6ea83fed bellard
    WT2 = float32_round_to_int(FST0, &env->fp_status);
1704 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
1705 6ea83fed bellard
    DEBUG_FPU_STATE();
1706 6ea83fed bellard
    RETURN();
1707 6ea83fed bellard
}
1708 6ea83fed bellard
1709 6ea83fed bellard
FLOAT_OP(floorw, d)
1710 6ea83fed bellard
{
1711 6ea83fed bellard
    set_float_rounding_mode(float_round_down, &env->fp_status);
1712 6ea83fed bellard
    WT2 = float64_round_to_int(FDT0, &env->fp_status);
1713 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
1714 6ea83fed bellard
1715 6ea83fed bellard
    DEBUG_FPU_STATE();
1716 6ea83fed bellard
    RETURN();
1717 6ea83fed bellard
}
1718 6ea83fed bellard
FLOAT_OP(floorw, s)
1719 6ea83fed bellard
{
1720 6ea83fed bellard
    set_float_rounding_mode(float_round_down, &env->fp_status);
1721 6ea83fed bellard
    WT2 = float32_round_to_int(FST0, &env->fp_status);
1722 6ea83fed bellard
    RESTORE_ROUNDING_MODE;
1723 6ea83fed bellard
    DEBUG_FPU_STATE();
1724 6ea83fed bellard
    RETURN();
1725 6ea83fed bellard
}
1726 6ea83fed bellard
1727 6ea83fed bellard
/* binary operations */
1728 6ea83fed bellard
#define FLOAT_BINOP(name) \
1729 6ea83fed bellard
FLOAT_OP(name, d)         \
1730 6ea83fed bellard
{                         \
1731 6ea83fed bellard
    FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);    \
1732 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1733 6ea83fed bellard
}                         \
1734 6ea83fed bellard
FLOAT_OP(name, s)         \
1735 6ea83fed bellard
{                         \
1736 6ea83fed bellard
    FST2 = float32_ ## name (FST0, FST1, &env->fp_status);    \
1737 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1738 6ea83fed bellard
}
1739 6ea83fed bellard
FLOAT_BINOP(add)
1740 6ea83fed bellard
FLOAT_BINOP(sub)
1741 6ea83fed bellard
FLOAT_BINOP(mul)
1742 6ea83fed bellard
FLOAT_BINOP(div)
1743 6ea83fed bellard
#undef FLOAT_BINOP
1744 6ea83fed bellard
1745 6ea83fed bellard
/* unary operations, modifying fp status  */
1746 6ea83fed bellard
#define FLOAT_UNOP(name)  \
1747 6ea83fed bellard
FLOAT_OP(name, d)         \
1748 6ea83fed bellard
{                         \
1749 6ea83fed bellard
    FDT2 = float64_ ## name(FDT0, &env->fp_status);   \
1750 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1751 6ea83fed bellard
}                         \
1752 6ea83fed bellard
FLOAT_OP(name, s)         \
1753 6ea83fed bellard
{                         \
1754 6ea83fed bellard
    FST2 = float32_ ## name(FST0, &env->fp_status);   \
1755 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1756 6ea83fed bellard
}
1757 6ea83fed bellard
FLOAT_UNOP(sqrt)
1758 6ea83fed bellard
#undef FLOAT_UNOP
1759 6ea83fed bellard
1760 6ea83fed bellard
/* unary operations, not modifying fp status  */
1761 6ea83fed bellard
#define FLOAT_UNOP(name)  \
1762 6ea83fed bellard
FLOAT_OP(name, d)         \
1763 6ea83fed bellard
{                         \
1764 6ea83fed bellard
    FDT2 = float64_ ## name(FDT0);   \
1765 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1766 6ea83fed bellard
}                         \
1767 6ea83fed bellard
FLOAT_OP(name, s)         \
1768 6ea83fed bellard
{                         \
1769 6ea83fed bellard
    FST2 = float32_ ## name(FST0);   \
1770 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1771 6ea83fed bellard
}
1772 6ea83fed bellard
FLOAT_UNOP(abs)
1773 6ea83fed bellard
FLOAT_UNOP(chs)
1774 6ea83fed bellard
#undef FLOAT_UNOP
1775 6ea83fed bellard
1776 6ea83fed bellard
FLOAT_OP(mov, d)
1777 6ea83fed bellard
{
1778 6ea83fed bellard
    FDT2 = FDT0;
1779 6ea83fed bellard
    DEBUG_FPU_STATE();
1780 6ea83fed bellard
    RETURN();
1781 6ea83fed bellard
}
1782 6ea83fed bellard
FLOAT_OP(mov, s)
1783 6ea83fed bellard
{
1784 6ea83fed bellard
    FST2 = FST0;
1785 6ea83fed bellard
    DEBUG_FPU_STATE();
1786 6ea83fed bellard
    RETURN();
1787 6ea83fed bellard
}
1788 6ea83fed bellard
1789 6ea83fed bellard
#ifdef CONFIG_SOFTFLOAT
1790 6ea83fed bellard
#define clear_invalid() do {                                \
1791 6ea83fed bellard
    int flags = get_float_exception_flags(&env->fp_status); \
1792 6ea83fed bellard
    flags &= ~float_flag_invalid;                           \
1793 6ea83fed bellard
    set_float_exception_flags(flags, &env->fp_status);      \
1794 6ea83fed bellard
} while(0)
1795 6ea83fed bellard
#else
1796 6ea83fed bellard
#define clear_invalid() do { } while(0)
1797 6ea83fed bellard
#endif
1798 6ea83fed bellard
1799 6ea83fed bellard
extern void dump_fpu_s(CPUState *env);
1800 6ea83fed bellard
1801 6ea83fed bellard
#define FOP_COND(fmt, op, sig, cond)           \
1802 6ea83fed bellard
void op_cmp_ ## fmt ## _ ## op (void)          \
1803 6ea83fed bellard
{                                              \
1804 6ea83fed bellard
    if (cond)                                  \
1805 6ea83fed bellard
        SET_FP_COND(env->fcr31);               \
1806 6ea83fed bellard
    else                                       \
1807 6ea83fed bellard
        CLEAR_FP_COND(env->fcr31);             \
1808 6ea83fed bellard
    if (!sig)                                  \
1809 6ea83fed bellard
        clear_invalid();                       \
1810 6ea83fed bellard
    /*CALL_FROM_TB1(dump_fpu_s, env);*/ \
1811 6ea83fed bellard
    DEBUG_FPU_STATE();                         \
1812 6ea83fed bellard
    RETURN();                                  \
1813 6ea83fed bellard
}
1814 6ea83fed bellard
1815 569f5d66 bellard
int float64_is_unordered(float64 a, float64 b STATUS_PARAM)
1816 6ea83fed bellard
{
1817 6ea83fed bellard
    if (float64_is_nan(a) || float64_is_nan(b)) {
1818 6ea83fed bellard
        float_raise(float_flag_invalid, status);
1819 6ea83fed bellard
        return 1;
1820 6ea83fed bellard
    }
1821 6ea83fed bellard
    else {
1822 6ea83fed bellard
        return 0;
1823 6ea83fed bellard
    }
1824 6ea83fed bellard
}
1825 6ea83fed bellard
1826 6ea83fed bellard
FOP_COND(d, f,   0,                                                      0) 
1827 6ea83fed bellard
FOP_COND(d, un,  0, float64_is_unordered(FDT1, FDT0, &env->fp_status))
1828 6ea83fed bellard
FOP_COND(d, eq,  0,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
1829 6ea83fed bellard
FOP_COND(d, ueq, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1830 6ea83fed bellard
FOP_COND(d, olt, 0,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
1831 6ea83fed bellard
FOP_COND(d, ult, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1832 6ea83fed bellard
FOP_COND(d, ole, 0,                                                      float64_le(FDT0, FDT1, &env->fp_status))
1833 6ea83fed bellard
FOP_COND(d, ule, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
1834 6ea83fed bellard
/* NOTE: the comma operator will make "cond" to eval to false,
1835 6ea83fed bellard
 * but float*_is_unordered() is still called
1836 6ea83fed bellard
 */
1837 6ea83fed bellard
FOP_COND(d, sf,  1,                                                      (float64_is_unordered(FDT0, FDT1, &env->fp_status), 0))
1838 6ea83fed bellard
FOP_COND(d, ngle,1, float64_is_unordered(FDT1, FDT0, &env->fp_status))
1839 6ea83fed bellard
FOP_COND(d, seq, 1,                                                      float64_eq(FDT0, FDT1, &env->fp_status))
1840 6ea83fed bellard
FOP_COND(d, ngl, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1841 6ea83fed bellard
FOP_COND(d, lt,  1,                                                      float64_lt(FDT0, FDT1, &env->fp_status))
1842 6ea83fed bellard
FOP_COND(d, nge, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1843 6ea83fed bellard
FOP_COND(d, le,  1,                                                      float64_le(FDT0, FDT1, &env->fp_status))
1844 6ea83fed bellard
FOP_COND(d, ngt, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
1845 6ea83fed bellard
1846 6ea83fed bellard
flag float32_is_unordered(float32 a, float32 b STATUS_PARAM)
1847 6ea83fed bellard
{
1848 6ea83fed bellard
    extern flag float32_is_nan( float32 a );
1849 6ea83fed bellard
    if (float32_is_nan(a) || float32_is_nan(b)) {
1850 6ea83fed bellard
        float_raise(float_flag_invalid, status);
1851 6ea83fed bellard
        return 1;
1852 6ea83fed bellard
    }
1853 6ea83fed bellard
    else {
1854 6ea83fed bellard
        return 0;
1855 6ea83fed bellard
    }
1856 6ea83fed bellard
}
1857 6ea83fed bellard
1858 6ea83fed bellard
/* NOTE: the comma operator will make "cond" to eval to false,
1859 6ea83fed bellard
 * but float*_is_unordered() is still called
1860 6ea83fed bellard
 */
1861 6ea83fed bellard
FOP_COND(s, f,   0,                                                      0) 
1862 6ea83fed bellard
FOP_COND(s, un,  0, float32_is_unordered(FST1, FST0, &env->fp_status))
1863 6ea83fed bellard
FOP_COND(s, eq,  0,                                                      float32_eq(FST0, FST1, &env->fp_status))
1864 6ea83fed bellard
FOP_COND(s, ueq, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1865 6ea83fed bellard
FOP_COND(s, olt, 0,                                                      float32_lt(FST0, FST1, &env->fp_status))
1866 6ea83fed bellard
FOP_COND(s, ult, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1867 6ea83fed bellard
FOP_COND(s, ole, 0,                                                      float32_le(FST0, FST1, &env->fp_status))
1868 6ea83fed bellard
FOP_COND(s, ule, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
1869 6ea83fed bellard
/* NOTE: the comma operator will make "cond" to eval to false,
1870 6ea83fed bellard
 * but float*_is_unordered() is still called
1871 6ea83fed bellard
 */
1872 6ea83fed bellard
FOP_COND(s, sf,  1,                                                      (float32_is_unordered(FST0, FST1, &env->fp_status), 0))
1873 6ea83fed bellard
FOP_COND(s, ngle,1, float32_is_unordered(FST1, FST0, &env->fp_status))
1874 6ea83fed bellard
FOP_COND(s, seq, 1,                                                      float32_eq(FST0, FST1, &env->fp_status))
1875 6ea83fed bellard
FOP_COND(s, ngl, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1876 6ea83fed bellard
FOP_COND(s, lt,  1,                                                      float32_lt(FST0, FST1, &env->fp_status))
1877 6ea83fed bellard
FOP_COND(s, nge, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1878 6ea83fed bellard
FOP_COND(s, le,  1,                                                      float32_le(FST0, FST1, &env->fp_status))
1879 6ea83fed bellard
FOP_COND(s, ngt, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
1880 6ea83fed bellard
1881 6ea83fed bellard
void op_bc1f (void)
1882 6ea83fed bellard
{
1883 6ea83fed bellard
    T0 = ! IS_FP_COND_SET(env->fcr31);
1884 6ea83fed bellard
    DEBUG_FPU_STATE();
1885 6ea83fed bellard
    RETURN();
1886 6ea83fed bellard
}
1887 6ea83fed bellard
1888 6ea83fed bellard
void op_bc1t (void)
1889 6ea83fed bellard
{
1890 6ea83fed bellard
    T0 = IS_FP_COND_SET(env->fcr31);
1891 6ea83fed bellard
    DEBUG_FPU_STATE();
1892 6ea83fed bellard
    RETURN();
1893 6ea83fed bellard
}
1894 6ea83fed bellard
#endif /* MIPS_USES_FPU */
1895 6ea83fed bellard
1896 6af0bf9c bellard
#if defined(MIPS_USES_R4K_TLB)
1897 6af0bf9c bellard
void op_tlbwi (void)
1898 6af0bf9c bellard
{
1899 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbwi);
1900 6af0bf9c bellard
    RETURN();
1901 6af0bf9c bellard
}
1902 6af0bf9c bellard
1903 6af0bf9c bellard
void op_tlbwr (void)
1904 6af0bf9c bellard
{
1905 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbwr);
1906 6af0bf9c bellard
    RETURN();
1907 6af0bf9c bellard
}
1908 6af0bf9c bellard
1909 6af0bf9c bellard
void op_tlbp (void)
1910 6af0bf9c bellard
{
1911 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbp);
1912 6af0bf9c bellard
    RETURN();
1913 6af0bf9c bellard
}
1914 6af0bf9c bellard
1915 6af0bf9c bellard
void op_tlbr (void)
1916 6af0bf9c bellard
{
1917 6af0bf9c bellard
    CALL_FROM_TB0(do_tlbr);
1918 6af0bf9c bellard
    RETURN();
1919 6af0bf9c bellard
}
1920 6af0bf9c bellard
#endif
1921 6af0bf9c bellard
1922 6af0bf9c bellard
/* Specials */
1923 6af0bf9c bellard
void op_pmon (void)
1924 6af0bf9c bellard
{
1925 6af0bf9c bellard
    CALL_FROM_TB1(do_pmon, PARAM1);
1926 7a387fff ths
    RETURN();
1927 7a387fff ths
}
1928 7a387fff ths
1929 7a387fff ths
void op_di (void)
1930 7a387fff ths
{
1931 7a387fff ths
    uint32_t val;
1932 7a387fff ths
1933 7a387fff ths
    T0 = env->CP0_Status;
1934 7a387fff ths
    val = T0 & ~(1 << CP0St_IE);
1935 7a387fff ths
    if (val != T0) {
1936 7a387fff ths
        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
1937 7a387fff ths
        env->CP0_Status = val;
1938 7a387fff ths
    }
1939 7a387fff ths
    RETURN();
1940 7a387fff ths
}
1941 7a387fff ths
1942 7a387fff ths
void op_ei (void)
1943 7a387fff ths
{
1944 7a387fff ths
    uint32_t val;
1945 7a387fff ths
1946 7a387fff ths
    T0 = env->CP0_Status;
1947 7a387fff ths
    val = T0 | (1 << CP0St_IE);
1948 7a387fff ths
    if (val != T0) {
1949 7a387fff ths
       const uint32_t mask = 0x0000FF00;
1950 7a387fff ths
1951 7a387fff ths
       env->CP0_Status = val;
1952 7a387fff ths
       if (!(env->hflags & MIPS_HFLAG_EXL) &&
1953 7a387fff ths
           !(env->hflags & MIPS_HFLAG_ERL) &&
1954 7a387fff ths
           !(env->hflags & MIPS_HFLAG_DM) &&
1955 7a387fff ths
           (env->CP0_Status & env->CP0_Cause & mask)) {
1956 7a387fff ths
               env->interrupt_request |= CPU_INTERRUPT_HARD;
1957 7a387fff ths
               if (logfile)
1958 7a387fff ths
                   CALL_FROM_TB0(do_mtc0_status_irqraise_debug);
1959 7a387fff ths
       }
1960 7a387fff ths
    }
1961 7a387fff ths
    RETURN();
1962 6af0bf9c bellard
}
1963 6af0bf9c bellard
1964 6af0bf9c bellard
void op_trap (void)
1965 6af0bf9c bellard
{
1966 6af0bf9c bellard
    if (T0) {
1967 4ad40f36 bellard
        CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP);
1968 6af0bf9c bellard
    }
1969 6af0bf9c bellard
    RETURN();
1970 6af0bf9c bellard
}
1971 6af0bf9c bellard
1972 4ad40f36 bellard
void op_debug (void)
1973 4ad40f36 bellard
{
1974 7a387fff ths
    CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
1975 7a387fff ths
    RETURN();
1976 4ad40f36 bellard
}
1977 4ad40f36 bellard
1978 6af0bf9c bellard
void op_set_lladdr (void)
1979 6af0bf9c bellard
{
1980 6af0bf9c bellard
    env->CP0_LLAddr = T2;
1981 7a387fff ths
    RETURN();
1982 6af0bf9c bellard
}
1983 6af0bf9c bellard
1984 6af0bf9c bellard
void debug_eret (void);
1985 6af0bf9c bellard
void op_eret (void)
1986 6af0bf9c bellard
{
1987 6af0bf9c bellard
    CALL_FROM_TB0(debug_eret);
1988 51e11d9e bellard
    if (env->hflags & MIPS_HFLAG_ERL) {
1989 6af0bf9c bellard
        env->PC = env->CP0_ErrorEPC;
1990 51e11d9e bellard
        env->hflags &= ~MIPS_HFLAG_ERL;
1991 3e382bc8 bellard
        env->CP0_Status &= ~(1 << CP0St_ERL);
1992 51e11d9e bellard
    } else {
1993 6af0bf9c bellard
        env->PC = env->CP0_EPC;
1994 51e11d9e bellard
        env->hflags &= ~MIPS_HFLAG_EXL;
1995 3e382bc8 bellard
        env->CP0_Status &= ~(1 << CP0St_EXL);
1996 51e11d9e bellard
    }
1997 6af0bf9c bellard
    env->CP0_LLAddr = 1;
1998 7a387fff ths
    RETURN();
1999 6af0bf9c bellard
}
2000 6af0bf9c bellard
2001 6af0bf9c bellard
void op_deret (void)
2002 6af0bf9c bellard
{
2003 6af0bf9c bellard
    CALL_FROM_TB0(debug_eret);
2004 6af0bf9c bellard
    env->PC = env->CP0_DEPC;
2005 7a387fff ths
    RETURN();
2006 7a387fff ths
}
2007 7a387fff ths
2008 7a387fff ths
void op_rdhwr_cpunum(void)
2009 7a387fff ths
{
2010 7a387fff ths
    if (env->CP0_HWREna & (1 << 0))
2011 7a387fff ths
       T0 = env->CP0_EBase & 0x2ff;
2012 7a387fff ths
    else
2013 7a387fff ths
       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
2014 7a387fff ths
    RETURN();
2015 7a387fff ths
}
2016 7a387fff ths
2017 7a387fff ths
void op_rdhwr_synci_step(void)
2018 7a387fff ths
{
2019 7a387fff ths
    if (env->CP0_HWREna & (1 << 1))
2020 7a387fff ths
       T0 = env->SYNCI_Step;
2021 7a387fff ths
    else
2022 7a387fff ths
       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
2023 7a387fff ths
    RETURN();
2024 7a387fff ths
}
2025 7a387fff ths
2026 7a387fff ths
void op_rdhwr_cc(void)
2027 7a387fff ths
{
2028 7a387fff ths
    if (env->CP0_HWREna & (1 << 2))
2029 7a387fff ths
       T0 = env->CP0_Count;
2030 7a387fff ths
    else
2031 7a387fff ths
       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
2032 7a387fff ths
    RETURN();
2033 7a387fff ths
}
2034 7a387fff ths
2035 7a387fff ths
void op_rdhwr_ccres(void)
2036 7a387fff ths
{
2037 7a387fff ths
    if (env->CP0_HWREna & (1 << 3))
2038 7a387fff ths
       T0 = env->CCRes;
2039 7a387fff ths
    else
2040 7a387fff ths
       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
2041 7a387fff ths
    RETURN();
2042 6af0bf9c bellard
}
2043 6af0bf9c bellard
2044 6af0bf9c bellard
void op_save_state (void)
2045 6af0bf9c bellard
{
2046 6af0bf9c bellard
    env->hflags = PARAM1;
2047 6af0bf9c bellard
    RETURN();
2048 6af0bf9c bellard
}
2049 6af0bf9c bellard
2050 6af0bf9c bellard
void op_save_pc (void)
2051 6af0bf9c bellard
{
2052 6af0bf9c bellard
    env->PC = PARAM1;
2053 6af0bf9c bellard
    RETURN();
2054 6af0bf9c bellard
}
2055 6af0bf9c bellard
2056 6af0bf9c bellard
void op_raise_exception (void)
2057 6af0bf9c bellard
{
2058 6af0bf9c bellard
    CALL_FROM_TB1(do_raise_exception, PARAM1);
2059 6af0bf9c bellard
    RETURN();
2060 6af0bf9c bellard
}
2061 6af0bf9c bellard
2062 6af0bf9c bellard
void op_raise_exception_err (void)
2063 6af0bf9c bellard
{
2064 6af0bf9c bellard
    CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
2065 6af0bf9c bellard
    RETURN();
2066 6af0bf9c bellard
}
2067 6af0bf9c bellard
2068 6af0bf9c bellard
void op_exit_tb (void)
2069 6af0bf9c bellard
{
2070 6af0bf9c bellard
    EXIT_TB();
2071 7a387fff ths
    RETURN();
2072 6af0bf9c bellard
}
2073 6af0bf9c bellard
2074 4ad40f36 bellard
void op_wait (void)
2075 4ad40f36 bellard
{
2076 4ad40f36 bellard
    env->halted = 1;
2077 4ad40f36 bellard
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2078 7a387fff ths
    RETURN();
2079 7a387fff ths
}
2080 7a387fff ths
2081 7a387fff ths
/* Bitfield operations. */
2082 7a387fff ths
void op_ext(void)
2083 7a387fff ths
{
2084 7a387fff ths
    unsigned int pos = PARAM1;
2085 7a387fff ths
    unsigned int size = PARAM2;
2086 7a387fff ths
2087 c570fd16 ths
    T0 = ((uint32_t)T1 >> pos) & ((1 << size) - 1);
2088 7a387fff ths
    RETURN();
2089 7a387fff ths
}
2090 7a387fff ths
2091 7a387fff ths
void op_ins(void)
2092 7a387fff ths
{
2093 7a387fff ths
    unsigned int pos = PARAM1;
2094 7a387fff ths
    unsigned int size = PARAM2;
2095 7a387fff ths
    target_ulong mask = ((1 << size) - 1) << pos;
2096 7a387fff ths
2097 c570fd16 ths
    T0 = (T2 & ~mask) | (((uint32_t)T1 << pos) & mask);
2098 7a387fff ths
    RETURN();
2099 7a387fff ths
}
2100 7a387fff ths
2101 7a387fff ths
void op_wsbh(void)
2102 7a387fff ths
{
2103 7a387fff ths
    T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF);
2104 7a387fff ths
    RETURN();
2105 7a387fff ths
}
2106 7a387fff ths
2107 c570fd16 ths
#ifdef MIPS_HAS_MIPS64
2108 c570fd16 ths
void op_dext(void)
2109 c570fd16 ths
{
2110 c570fd16 ths
    unsigned int pos = PARAM1;
2111 c570fd16 ths
    unsigned int size = PARAM2;
2112 c570fd16 ths
2113 c570fd16 ths
    T0 = (T1 >> pos) & ((1 << size) - 1);
2114 c570fd16 ths
    RETURN();
2115 c570fd16 ths
}
2116 c570fd16 ths
2117 c570fd16 ths
void op_dins(void)
2118 c570fd16 ths
{
2119 c570fd16 ths
    unsigned int pos = PARAM1;
2120 c570fd16 ths
    unsigned int size = PARAM2;
2121 c570fd16 ths
    target_ulong mask = ((1 << size) - 1) << pos;
2122 c570fd16 ths
2123 c570fd16 ths
    T0 = (T2 & ~mask) | ((T1 << pos) & mask);
2124 c570fd16 ths
    RETURN();
2125 c570fd16 ths
}
2126 c570fd16 ths
2127 7a387fff ths
void op_dsbh(void)
2128 7a387fff ths
{
2129 7a387fff ths
    T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2130 7a387fff ths
    RETURN();
2131 7a387fff ths
}
2132 7a387fff ths
2133 7a387fff ths
void op_dshd(void)
2134 7a387fff ths
{
2135 7a387fff ths
    T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2136 7a387fff ths
    RETURN();
2137 7a387fff ths
}
2138 c570fd16 ths
#endif
2139 7a387fff ths
2140 7a387fff ths
void op_seb(void)
2141 7a387fff ths
{
2142 7a387fff ths
    T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
2143 7a387fff ths
    RETURN();
2144 7a387fff ths
}
2145 7a387fff ths
2146 7a387fff ths
void op_seh(void)
2147 7a387fff ths
{
2148 7a387fff ths
    T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
2149 7a387fff ths
    RETURN();
2150 4ad40f36 bellard
}