Statistics
| Branch: | Revision:

root / target-mips / op.c @ 9b9e4393

History | View | Annotate | Download (45 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 93b12ccc ths
 *  Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
7 6af0bf9c bellard
 *
8 6af0bf9c bellard
 * This library is free software; you can redistribute it and/or
9 6af0bf9c bellard
 * modify it under the terms of the GNU Lesser General Public
10 6af0bf9c bellard
 * License as published by the Free Software Foundation; either
11 6af0bf9c bellard
 * version 2 of the License, or (at your option) any later version.
12 6af0bf9c bellard
 *
13 6af0bf9c bellard
 * This library is distributed in the hope that it will be useful,
14 6af0bf9c bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 6af0bf9c bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 6af0bf9c bellard
 * Lesser General Public License for more details.
17 6af0bf9c bellard
 *
18 6af0bf9c bellard
 * You should have received a copy of the GNU Lesser General Public
19 6af0bf9c bellard
 * License along with this library; if not, write to the Free Software
20 6af0bf9c bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 6af0bf9c bellard
 */
22 6af0bf9c bellard
23 6af0bf9c bellard
#include "config.h"
24 6af0bf9c bellard
#include "exec.h"
25 6af0bf9c bellard
26 1b351e52 bellard
#ifndef CALL_FROM_TB0
27 5a5012ec ths
#define CALL_FROM_TB0(func) func()
28 1b351e52 bellard
#endif
29 1b351e52 bellard
#ifndef CALL_FROM_TB1
30 5a5012ec ths
#define CALL_FROM_TB1(func, arg0) func(arg0)
31 1b351e52 bellard
#endif
32 1b351e52 bellard
#ifndef CALL_FROM_TB1_CONST16
33 5a5012ec ths
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
34 1b351e52 bellard
#endif
35 1b351e52 bellard
#ifndef CALL_FROM_TB2
36 5a5012ec ths
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
37 1b351e52 bellard
#endif
38 1b351e52 bellard
#ifndef CALL_FROM_TB2_CONST16
39 1b351e52 bellard
#define CALL_FROM_TB2_CONST16(func, arg0, arg1)     \
40 5a5012ec ths
        CALL_FROM_TB2(func, arg0, arg1)
41 1b351e52 bellard
#endif
42 1b351e52 bellard
#ifndef CALL_FROM_TB3
43 5a5012ec ths
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
44 1b351e52 bellard
#endif
45 1b351e52 bellard
#ifndef CALL_FROM_TB4
46 1b351e52 bellard
#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
47 5a5012ec ths
        func(arg0, arg1, arg2, arg3)
48 1b351e52 bellard
#endif
49 1b351e52 bellard
50 6af0bf9c bellard
#define REG 1
51 6af0bf9c bellard
#include "op_template.c"
52 6af0bf9c bellard
#undef REG
53 6af0bf9c bellard
#define REG 2
54 6af0bf9c bellard
#include "op_template.c"
55 6af0bf9c bellard
#undef REG
56 6af0bf9c bellard
#define REG 3
57 6af0bf9c bellard
#include "op_template.c"
58 6af0bf9c bellard
#undef REG
59 6af0bf9c bellard
#define REG 4
60 6af0bf9c bellard
#include "op_template.c"
61 6af0bf9c bellard
#undef REG
62 6af0bf9c bellard
#define REG 5
63 6af0bf9c bellard
#include "op_template.c"
64 6af0bf9c bellard
#undef REG
65 6af0bf9c bellard
#define REG 6
66 6af0bf9c bellard
#include "op_template.c"
67 6af0bf9c bellard
#undef REG
68 6af0bf9c bellard
#define REG 7
69 6af0bf9c bellard
#include "op_template.c"
70 6af0bf9c bellard
#undef REG
71 6af0bf9c bellard
#define REG 8
72 6af0bf9c bellard
#include "op_template.c"
73 6af0bf9c bellard
#undef REG
74 6af0bf9c bellard
#define REG 9
75 6af0bf9c bellard
#include "op_template.c"
76 6af0bf9c bellard
#undef REG
77 6af0bf9c bellard
#define REG 10
78 6af0bf9c bellard
#include "op_template.c"
79 6af0bf9c bellard
#undef REG
80 6af0bf9c bellard
#define REG 11
81 6af0bf9c bellard
#include "op_template.c"
82 6af0bf9c bellard
#undef REG
83 6af0bf9c bellard
#define REG 12
84 6af0bf9c bellard
#include "op_template.c"
85 6af0bf9c bellard
#undef REG
86 6af0bf9c bellard
#define REG 13
87 6af0bf9c bellard
#include "op_template.c"
88 6af0bf9c bellard
#undef REG
89 6af0bf9c bellard
#define REG 14
90 6af0bf9c bellard
#include "op_template.c"
91 6af0bf9c bellard
#undef REG
92 6af0bf9c bellard
#define REG 15
93 6af0bf9c bellard
#include "op_template.c"
94 6af0bf9c bellard
#undef REG
95 6af0bf9c bellard
#define REG 16
96 6af0bf9c bellard
#include "op_template.c"
97 6af0bf9c bellard
#undef REG
98 6af0bf9c bellard
#define REG 17
99 6af0bf9c bellard
#include "op_template.c"
100 6af0bf9c bellard
#undef REG
101 6af0bf9c bellard
#define REG 18
102 6af0bf9c bellard
#include "op_template.c"
103 6af0bf9c bellard
#undef REG
104 6af0bf9c bellard
#define REG 19
105 6af0bf9c bellard
#include "op_template.c"
106 6af0bf9c bellard
#undef REG
107 6af0bf9c bellard
#define REG 20
108 6af0bf9c bellard
#include "op_template.c"
109 6af0bf9c bellard
#undef REG
110 6af0bf9c bellard
#define REG 21
111 6af0bf9c bellard
#include "op_template.c"
112 6af0bf9c bellard
#undef REG
113 6af0bf9c bellard
#define REG 22
114 6af0bf9c bellard
#include "op_template.c"
115 6af0bf9c bellard
#undef REG
116 6af0bf9c bellard
#define REG 23
117 6af0bf9c bellard
#include "op_template.c"
118 6af0bf9c bellard
#undef REG
119 6af0bf9c bellard
#define REG 24
120 6af0bf9c bellard
#include "op_template.c"
121 6af0bf9c bellard
#undef REG
122 6af0bf9c bellard
#define REG 25
123 6af0bf9c bellard
#include "op_template.c"
124 6af0bf9c bellard
#undef REG
125 6af0bf9c bellard
#define REG 26
126 6af0bf9c bellard
#include "op_template.c"
127 6af0bf9c bellard
#undef REG
128 6af0bf9c bellard
#define REG 27
129 6af0bf9c bellard
#include "op_template.c"
130 6af0bf9c bellard
#undef REG
131 6af0bf9c bellard
#define REG 28
132 6af0bf9c bellard
#include "op_template.c"
133 6af0bf9c bellard
#undef REG
134 6af0bf9c bellard
#define REG 29
135 6af0bf9c bellard
#include "op_template.c"
136 6af0bf9c bellard
#undef REG
137 6af0bf9c bellard
#define REG 30
138 6af0bf9c bellard
#include "op_template.c"
139 6af0bf9c bellard
#undef REG
140 6af0bf9c bellard
#define REG 31
141 6af0bf9c bellard
#include "op_template.c"
142 6af0bf9c bellard
#undef REG
143 6af0bf9c bellard
144 c570fd16 ths
#define TN
145 6af0bf9c bellard
#include "op_template.c"
146 6af0bf9c bellard
#undef TN
147 6af0bf9c bellard
148 5a5012ec ths
#define FREG 0
149 6ea83fed bellard
#include "fop_template.c"
150 5a5012ec ths
#undef FREG
151 5a5012ec ths
#define FREG 1
152 6ea83fed bellard
#include "fop_template.c"
153 5a5012ec ths
#undef FREG
154 5a5012ec ths
#define FREG 2
155 6ea83fed bellard
#include "fop_template.c"
156 5a5012ec ths
#undef FREG
157 5a5012ec ths
#define FREG 3
158 6ea83fed bellard
#include "fop_template.c"
159 5a5012ec ths
#undef FREG
160 5a5012ec ths
#define FREG 4
161 6ea83fed bellard
#include "fop_template.c"
162 5a5012ec ths
#undef FREG
163 5a5012ec ths
#define FREG 5
164 6ea83fed bellard
#include "fop_template.c"
165 5a5012ec ths
#undef FREG
166 5a5012ec ths
#define FREG 6
167 6ea83fed bellard
#include "fop_template.c"
168 5a5012ec ths
#undef FREG
169 5a5012ec ths
#define FREG 7
170 6ea83fed bellard
#include "fop_template.c"
171 5a5012ec ths
#undef FREG
172 5a5012ec ths
#define FREG 8
173 6ea83fed bellard
#include "fop_template.c"
174 5a5012ec ths
#undef FREG
175 5a5012ec ths
#define FREG 9
176 6ea83fed bellard
#include "fop_template.c"
177 5a5012ec ths
#undef FREG
178 5a5012ec ths
#define FREG 10
179 6ea83fed bellard
#include "fop_template.c"
180 5a5012ec ths
#undef FREG
181 5a5012ec ths
#define FREG 11
182 6ea83fed bellard
#include "fop_template.c"
183 5a5012ec ths
#undef FREG
184 5a5012ec ths
#define FREG 12
185 6ea83fed bellard
#include "fop_template.c"
186 5a5012ec ths
#undef FREG
187 5a5012ec ths
#define FREG 13
188 6ea83fed bellard
#include "fop_template.c"
189 5a5012ec ths
#undef FREG
190 5a5012ec ths
#define FREG 14
191 6ea83fed bellard
#include "fop_template.c"
192 5a5012ec ths
#undef FREG
193 5a5012ec ths
#define FREG 15
194 6ea83fed bellard
#include "fop_template.c"
195 5a5012ec ths
#undef FREG
196 5a5012ec ths
#define FREG 16
197 6ea83fed bellard
#include "fop_template.c"
198 5a5012ec ths
#undef FREG
199 5a5012ec ths
#define FREG 17
200 6ea83fed bellard
#include "fop_template.c"
201 5a5012ec ths
#undef FREG
202 5a5012ec ths
#define FREG 18
203 6ea83fed bellard
#include "fop_template.c"
204 5a5012ec ths
#undef FREG
205 5a5012ec ths
#define FREG 19
206 6ea83fed bellard
#include "fop_template.c"
207 5a5012ec ths
#undef FREG
208 5a5012ec ths
#define FREG 20
209 6ea83fed bellard
#include "fop_template.c"
210 5a5012ec ths
#undef FREG
211 5a5012ec ths
#define FREG 21
212 6ea83fed bellard
#include "fop_template.c"
213 5a5012ec ths
#undef FREG
214 5a5012ec ths
#define FREG 22
215 6ea83fed bellard
#include "fop_template.c"
216 5a5012ec ths
#undef FREG
217 5a5012ec ths
#define FREG 23
218 6ea83fed bellard
#include "fop_template.c"
219 5a5012ec ths
#undef FREG
220 5a5012ec ths
#define FREG 24
221 6ea83fed bellard
#include "fop_template.c"
222 5a5012ec ths
#undef FREG
223 5a5012ec ths
#define FREG 25
224 6ea83fed bellard
#include "fop_template.c"
225 5a5012ec ths
#undef FREG
226 5a5012ec ths
#define FREG 26
227 6ea83fed bellard
#include "fop_template.c"
228 5a5012ec ths
#undef FREG
229 5a5012ec ths
#define FREG 27
230 6ea83fed bellard
#include "fop_template.c"
231 5a5012ec ths
#undef FREG
232 5a5012ec ths
#define FREG 28
233 6ea83fed bellard
#include "fop_template.c"
234 5a5012ec ths
#undef FREG
235 5a5012ec ths
#define FREG 29
236 6ea83fed bellard
#include "fop_template.c"
237 5a5012ec ths
#undef FREG
238 5a5012ec ths
#define FREG 30
239 6ea83fed bellard
#include "fop_template.c"
240 5a5012ec ths
#undef FREG
241 5a5012ec ths
#define FREG 31
242 6ea83fed bellard
#include "fop_template.c"
243 5a5012ec ths
#undef FREG
244 6ea83fed bellard
245 6ea83fed bellard
#define FTN
246 6ea83fed bellard
#include "fop_template.c"
247 6ea83fed bellard
#undef FTN
248 6ea83fed bellard
249 6af0bf9c bellard
void op_dup_T0 (void)
250 6af0bf9c bellard
{
251 6af0bf9c bellard
    T2 = T0;
252 6af0bf9c bellard
    RETURN();
253 6af0bf9c bellard
}
254 6af0bf9c bellard
255 6af0bf9c bellard
void op_load_HI (void)
256 6af0bf9c bellard
{
257 6af0bf9c bellard
    T0 = env->HI;
258 6af0bf9c bellard
    RETURN();
259 6af0bf9c bellard
}
260 6af0bf9c bellard
261 6af0bf9c bellard
void op_store_HI (void)
262 6af0bf9c bellard
{
263 6af0bf9c bellard
    env->HI = T0;
264 6af0bf9c bellard
    RETURN();
265 6af0bf9c bellard
}
266 6af0bf9c bellard
267 6af0bf9c bellard
void op_load_LO (void)
268 6af0bf9c bellard
{
269 6af0bf9c bellard
    T0 = env->LO;
270 6af0bf9c bellard
    RETURN();
271 6af0bf9c bellard
}
272 6af0bf9c bellard
273 6af0bf9c bellard
void op_store_LO (void)
274 6af0bf9c bellard
{
275 6af0bf9c bellard
    env->LO = T0;
276 6af0bf9c bellard
    RETURN();
277 6af0bf9c bellard
}
278 6af0bf9c bellard
279 6af0bf9c bellard
/* Load and store */
280 6af0bf9c bellard
#define MEMSUFFIX _raw
281 6af0bf9c bellard
#include "op_mem.c"
282 6af0bf9c bellard
#undef MEMSUFFIX
283 6af0bf9c bellard
#if !defined(CONFIG_USER_ONLY)
284 6af0bf9c bellard
#define MEMSUFFIX _user
285 6af0bf9c bellard
#include "op_mem.c"
286 6af0bf9c bellard
#undef MEMSUFFIX
287 6af0bf9c bellard
288 6af0bf9c bellard
#define MEMSUFFIX _kernel
289 6af0bf9c bellard
#include "op_mem.c"
290 6af0bf9c bellard
#undef MEMSUFFIX
291 6af0bf9c bellard
#endif
292 6af0bf9c bellard
293 a6763a58 ths
/* Addresses computation */
294 a6763a58 ths
void op_addr_add (void)
295 a6763a58 ths
{
296 a6763a58 ths
/* For compatibility with 32-bit code, data reference in user mode
297 a6763a58 ths
   with Status_UX = 0 should be casted to 32-bit and sign extended.
298 a6763a58 ths
   See the MIPS64 PRA manual, section 4.10. */
299 a6763a58 ths
#ifdef TARGET_MIPS64
300 a6763a58 ths
    if ((env->CP0_Status & (1 << CP0St_UM)) &&
301 a6763a58 ths
        !(env->CP0_Status & (1 << CP0St_UX)))
302 a6763a58 ths
        T0 = (int64_t)(int32_t)(T0 + T1);
303 a6763a58 ths
    else
304 a6763a58 ths
#endif
305 a6763a58 ths
        T0 += T1;
306 a6763a58 ths
    RETURN();
307 a6763a58 ths
}
308 a6763a58 ths
309 6af0bf9c bellard
/* Arithmetic */
310 6af0bf9c bellard
void op_add (void)
311 6af0bf9c bellard
{
312 5dc4b744 ths
    T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
313 6af0bf9c bellard
    RETURN();
314 6af0bf9c bellard
}
315 6af0bf9c bellard
316 6af0bf9c bellard
void op_addo (void)
317 6af0bf9c bellard
{
318 6af0bf9c bellard
    target_ulong tmp;
319 6af0bf9c bellard
320 c570fd16 ths
    tmp = (int32_t)T0;
321 c570fd16 ths
    T0 = (int32_t)T0 + (int32_t)T1;
322 76e050c2 bellard
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
323 c570fd16 ths
        /* operands of same sign, result different sign */
324 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
325 6af0bf9c bellard
    }
326 5dc4b744 ths
    T0 = (int32_t)T0;
327 6af0bf9c bellard
    RETURN();
328 6af0bf9c bellard
}
329 6af0bf9c bellard
330 6af0bf9c bellard
void op_sub (void)
331 6af0bf9c bellard
{
332 5dc4b744 ths
    T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
333 6af0bf9c bellard
    RETURN();
334 6af0bf9c bellard
}
335 6af0bf9c bellard
336 6af0bf9c bellard
void op_subo (void)
337 6af0bf9c bellard
{
338 6af0bf9c bellard
    target_ulong tmp;
339 6af0bf9c bellard
340 c570fd16 ths
    tmp = (int32_t)T0;
341 6af0bf9c bellard
    T0 = (int32_t)T0 - (int32_t)T1;
342 76e050c2 bellard
    if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
343 c570fd16 ths
        /* operands of different sign, first operand and result different sign */
344 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
345 6af0bf9c bellard
    }
346 5dc4b744 ths
    T0 = (int32_t)T0;
347 6af0bf9c bellard
    RETURN();
348 6af0bf9c bellard
}
349 6af0bf9c bellard
350 6af0bf9c bellard
void op_mul (void)
351 6af0bf9c bellard
{
352 5dc4b744 ths
    T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
353 6af0bf9c bellard
    RETURN();
354 6af0bf9c bellard
}
355 6af0bf9c bellard
356 80c27194 ths
#if HOST_LONG_BITS < 64
357 80c27194 ths
void op_div (void)
358 80c27194 ths
{
359 80c27194 ths
    CALL_FROM_TB0(do_div);
360 80c27194 ths
    RETURN();
361 80c27194 ths
}
362 80c27194 ths
#else
363 6af0bf9c bellard
void op_div (void)
364 6af0bf9c bellard
{
365 6af0bf9c bellard
    if (T1 != 0) {
366 80c27194 ths
        env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
367 80c27194 ths
        env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
368 6af0bf9c bellard
    }
369 6af0bf9c bellard
    RETURN();
370 6af0bf9c bellard
}
371 80c27194 ths
#endif
372 6af0bf9c bellard
373 6af0bf9c bellard
void op_divu (void)
374 6af0bf9c bellard
{
375 6af0bf9c bellard
    if (T1 != 0) {
376 5dc4b744 ths
        env->LO = (int32_t)((uint32_t)T0 / (uint32_t)T1);
377 5dc4b744 ths
        env->HI = (int32_t)((uint32_t)T0 % (uint32_t)T1);
378 c570fd16 ths
    }
379 c570fd16 ths
    RETURN();
380 c570fd16 ths
}
381 c570fd16 ths
382 60aa19ab ths
#ifdef TARGET_MIPS64
383 c570fd16 ths
/* Arithmetic */
384 c570fd16 ths
void op_dadd (void)
385 c570fd16 ths
{
386 c570fd16 ths
    T0 += T1;
387 c570fd16 ths
    RETURN();
388 c570fd16 ths
}
389 c570fd16 ths
390 c570fd16 ths
void op_daddo (void)
391 c570fd16 ths
{
392 c570fd16 ths
    target_long tmp;
393 c570fd16 ths
394 c570fd16 ths
    tmp = T0;
395 c570fd16 ths
    T0 += T1;
396 c570fd16 ths
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
397 c570fd16 ths
        /* operands of same sign, result different sign */
398 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
399 c570fd16 ths
    }
400 c570fd16 ths
    RETURN();
401 c570fd16 ths
}
402 c570fd16 ths
403 c570fd16 ths
void op_dsub (void)
404 c570fd16 ths
{
405 c570fd16 ths
    T0 -= T1;
406 c570fd16 ths
    RETURN();
407 c570fd16 ths
}
408 c570fd16 ths
409 c570fd16 ths
void op_dsubo (void)
410 c570fd16 ths
{
411 c570fd16 ths
    target_long tmp;
412 c570fd16 ths
413 c570fd16 ths
    tmp = T0;
414 c570fd16 ths
    T0 = (int64_t)T0 - (int64_t)T1;
415 c570fd16 ths
    if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
416 c570fd16 ths
        /* operands of different sign, first operand and result different sign */
417 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
418 c570fd16 ths
    }
419 c570fd16 ths
    RETURN();
420 c570fd16 ths
}
421 c570fd16 ths
422 c570fd16 ths
void op_dmul (void)
423 c570fd16 ths
{
424 c570fd16 ths
    T0 = (int64_t)T0 * (int64_t)T1;
425 c570fd16 ths
    RETURN();
426 c570fd16 ths
}
427 c570fd16 ths
428 c570fd16 ths
/* Those might call libgcc functions.  */
429 c570fd16 ths
void op_ddiv (void)
430 c570fd16 ths
{
431 c570fd16 ths
    do_ddiv();
432 c570fd16 ths
    RETURN();
433 c570fd16 ths
}
434 c570fd16 ths
435 80c27194 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
436 c570fd16 ths
void op_ddivu (void)
437 c570fd16 ths
{
438 c570fd16 ths
    do_ddivu();
439 c570fd16 ths
    RETURN();
440 c570fd16 ths
}
441 c570fd16 ths
#else
442 c570fd16 ths
void op_ddivu (void)
443 c570fd16 ths
{
444 c570fd16 ths
    if (T1 != 0) {
445 6af0bf9c bellard
        env->LO = T0 / T1;
446 6af0bf9c bellard
        env->HI = T0 % T1;
447 6af0bf9c bellard
    }
448 6af0bf9c bellard
    RETURN();
449 6af0bf9c bellard
}
450 c570fd16 ths
#endif
451 60aa19ab ths
#endif /* TARGET_MIPS64 */
452 6af0bf9c bellard
453 6af0bf9c bellard
/* Logical */
454 6af0bf9c bellard
void op_and (void)
455 6af0bf9c bellard
{
456 6af0bf9c bellard
    T0 &= T1;
457 6af0bf9c bellard
    RETURN();
458 6af0bf9c bellard
}
459 6af0bf9c bellard
460 6af0bf9c bellard
void op_nor (void)
461 6af0bf9c bellard
{
462 6af0bf9c bellard
    T0 = ~(T0 | T1);
463 6af0bf9c bellard
    RETURN();
464 6af0bf9c bellard
}
465 6af0bf9c bellard
466 6af0bf9c bellard
void op_or (void)
467 6af0bf9c bellard
{
468 6af0bf9c bellard
    T0 |= T1;
469 6af0bf9c bellard
    RETURN();
470 6af0bf9c bellard
}
471 6af0bf9c bellard
472 6af0bf9c bellard
void op_xor (void)
473 6af0bf9c bellard
{
474 6af0bf9c bellard
    T0 ^= T1;
475 6af0bf9c bellard
    RETURN();
476 6af0bf9c bellard
}
477 6af0bf9c bellard
478 6af0bf9c bellard
void op_sll (void)
479 6af0bf9c bellard
{
480 5a63bcb2 ths
    T0 = (int32_t)((uint32_t)T0 << T1);
481 6af0bf9c bellard
    RETURN();
482 6af0bf9c bellard
}
483 6af0bf9c bellard
484 6af0bf9c bellard
void op_sra (void)
485 6af0bf9c bellard
{
486 5a63bcb2 ths
    T0 = (int32_t)((int32_t)T0 >> T1);
487 6af0bf9c bellard
    RETURN();
488 6af0bf9c bellard
}
489 6af0bf9c bellard
490 6af0bf9c bellard
void op_srl (void)
491 6af0bf9c bellard
{
492 5a63bcb2 ths
    T0 = (int32_t)((uint32_t)T0 >> T1);
493 6af0bf9c bellard
    RETURN();
494 6af0bf9c bellard
}
495 6af0bf9c bellard
496 7a387fff ths
void op_rotr (void)
497 7a387fff ths
{
498 7a387fff ths
    target_ulong tmp;
499 7a387fff ths
500 7a387fff ths
    if (T1) {
501 5a63bcb2 ths
       tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
502 5a63bcb2 ths
       T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
503 5a63bcb2 ths
    }
504 7a387fff ths
    RETURN();
505 7a387fff ths
}
506 7a387fff ths
507 6af0bf9c bellard
void op_sllv (void)
508 6af0bf9c bellard
{
509 5dc4b744 ths
    T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
510 6af0bf9c bellard
    RETURN();
511 6af0bf9c bellard
}
512 6af0bf9c bellard
513 6af0bf9c bellard
void op_srav (void)
514 6af0bf9c bellard
{
515 5dc4b744 ths
    T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
516 6af0bf9c bellard
    RETURN();
517 6af0bf9c bellard
}
518 6af0bf9c bellard
519 6af0bf9c bellard
void op_srlv (void)
520 6af0bf9c bellard
{
521 5dc4b744 ths
    T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
522 6af0bf9c bellard
    RETURN();
523 6af0bf9c bellard
}
524 6af0bf9c bellard
525 7a387fff ths
void op_rotrv (void)
526 7a387fff ths
{
527 7a387fff ths
    target_ulong tmp;
528 7a387fff ths
529 7a387fff ths
    T0 &= 0x1F;
530 7a387fff ths
    if (T0) {
531 5dc4b744 ths
       tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
532 5dc4b744 ths
       T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
533 7a387fff ths
    } else
534 7a387fff ths
       T0 = T1;
535 7a387fff ths
    RETURN();
536 7a387fff ths
}
537 7a387fff ths
538 6af0bf9c bellard
void op_clo (void)
539 6af0bf9c bellard
{
540 6af0bf9c bellard
    int n;
541 6af0bf9c bellard
542 c570fd16 ths
    if (T0 == ~((target_ulong)0)) {
543 6af0bf9c bellard
        T0 = 32;
544 6af0bf9c bellard
    } else {
545 6af0bf9c bellard
        for (n = 0; n < 32; n++) {
546 6af0bf9c bellard
            if (!(T0 & (1 << 31)))
547 6af0bf9c bellard
                break;
548 6af0bf9c bellard
            T0 = T0 << 1;
549 6af0bf9c bellard
        }
550 6af0bf9c bellard
        T0 = n;
551 6af0bf9c bellard
    }
552 6af0bf9c bellard
    RETURN();
553 6af0bf9c bellard
}
554 6af0bf9c bellard
555 6af0bf9c bellard
void op_clz (void)
556 6af0bf9c bellard
{
557 6af0bf9c bellard
    int n;
558 6af0bf9c bellard
559 6af0bf9c bellard
    if (T0 == 0) {
560 6af0bf9c bellard
        T0 = 32;
561 6af0bf9c bellard
    } else {
562 6af0bf9c bellard
        for (n = 0; n < 32; n++) {
563 6af0bf9c bellard
            if (T0 & (1 << 31))
564 6af0bf9c bellard
                break;
565 6af0bf9c bellard
            T0 = T0 << 1;
566 6af0bf9c bellard
        }
567 6af0bf9c bellard
        T0 = n;
568 6af0bf9c bellard
    }
569 6af0bf9c bellard
    RETURN();
570 6af0bf9c bellard
}
571 6af0bf9c bellard
572 60aa19ab ths
#ifdef TARGET_MIPS64
573 c570fd16 ths
574 c570fd16 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
575 c570fd16 ths
/* Those might call libgcc functions.  */
576 c570fd16 ths
void op_dsll (void)
577 6af0bf9c bellard
{
578 c570fd16 ths
    CALL_FROM_TB0(do_dsll);
579 c570fd16 ths
    RETURN();
580 6af0bf9c bellard
}
581 6af0bf9c bellard
582 c570fd16 ths
void op_dsll32 (void)
583 6af0bf9c bellard
{
584 c570fd16 ths
    CALL_FROM_TB0(do_dsll32);
585 c570fd16 ths
    RETURN();
586 6af0bf9c bellard
}
587 6af0bf9c bellard
588 c570fd16 ths
void op_dsra (void)
589 6af0bf9c bellard
{
590 c570fd16 ths
    CALL_FROM_TB0(do_dsra);
591 6af0bf9c bellard
    RETURN();
592 6af0bf9c bellard
}
593 6af0bf9c bellard
594 c570fd16 ths
void op_dsra32 (void)
595 6af0bf9c bellard
{
596 c570fd16 ths
    CALL_FROM_TB0(do_dsra32);
597 6af0bf9c bellard
    RETURN();
598 6af0bf9c bellard
}
599 6af0bf9c bellard
600 c570fd16 ths
void op_dsrl (void)
601 6af0bf9c bellard
{
602 c570fd16 ths
    CALL_FROM_TB0(do_dsrl);
603 c570fd16 ths
    RETURN();
604 c570fd16 ths
}
605 6af0bf9c bellard
606 c570fd16 ths
void op_dsrl32 (void)
607 c570fd16 ths
{
608 c570fd16 ths
    CALL_FROM_TB0(do_dsrl32);
609 6af0bf9c bellard
    RETURN();
610 6af0bf9c bellard
}
611 6af0bf9c bellard
612 c570fd16 ths
void op_drotr (void)
613 6af0bf9c bellard
{
614 c570fd16 ths
    CALL_FROM_TB0(do_drotr);
615 c570fd16 ths
    RETURN();
616 c570fd16 ths
}
617 6af0bf9c bellard
618 c570fd16 ths
void op_drotr32 (void)
619 c570fd16 ths
{
620 c570fd16 ths
    CALL_FROM_TB0(do_drotr32);
621 6af0bf9c bellard
    RETURN();
622 6af0bf9c bellard
}
623 6af0bf9c bellard
624 c570fd16 ths
void op_dsllv (void)
625 6af0bf9c bellard
{
626 c570fd16 ths
    CALL_FROM_TB0(do_dsllv);
627 c570fd16 ths
    RETURN();
628 c570fd16 ths
}
629 6af0bf9c bellard
630 c570fd16 ths
void op_dsrav (void)
631 c570fd16 ths
{
632 c570fd16 ths
    CALL_FROM_TB0(do_dsrav);
633 6af0bf9c bellard
    RETURN();
634 6af0bf9c bellard
}
635 6af0bf9c bellard
636 c570fd16 ths
void op_dsrlv (void)
637 6af0bf9c bellard
{
638 c570fd16 ths
    CALL_FROM_TB0(do_dsrlv);
639 c570fd16 ths
    RETURN();
640 c570fd16 ths
}
641 6af0bf9c bellard
642 c570fd16 ths
void op_drotrv (void)
643 c570fd16 ths
{
644 c570fd16 ths
    CALL_FROM_TB0(do_drotrv);
645 6af0bf9c bellard
    RETURN();
646 6af0bf9c bellard
}
647 c570fd16 ths
648 c570fd16 ths
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
649 c570fd16 ths
650 c570fd16 ths
void op_dsll (void)
651 c570fd16 ths
{
652 c570fd16 ths
    T0 = T0 << T1;
653 c570fd16 ths
    RETURN();
654 c570fd16 ths
}
655 c570fd16 ths
656 c570fd16 ths
void op_dsll32 (void)
657 c570fd16 ths
{
658 c570fd16 ths
    T0 = T0 << (T1 + 32);
659 c570fd16 ths
    RETURN();
660 c570fd16 ths
}
661 c570fd16 ths
662 c570fd16 ths
void op_dsra (void)
663 c570fd16 ths
{
664 c570fd16 ths
    T0 = (int64_t)T0 >> T1;
665 c570fd16 ths
    RETURN();
666 c570fd16 ths
}
667 c570fd16 ths
668 c570fd16 ths
void op_dsra32 (void)
669 c570fd16 ths
{
670 c570fd16 ths
    T0 = (int64_t)T0 >> (T1 + 32);
671 c570fd16 ths
    RETURN();
672 c570fd16 ths
}
673 c570fd16 ths
674 c570fd16 ths
void op_dsrl (void)
675 c570fd16 ths
{
676 c570fd16 ths
    T0 = T0 >> T1;
677 c570fd16 ths
    RETURN();
678 c570fd16 ths
}
679 c570fd16 ths
680 c570fd16 ths
void op_dsrl32 (void)
681 c570fd16 ths
{
682 c570fd16 ths
    T0 = T0 >> (T1 + 32);
683 c570fd16 ths
    RETURN();
684 c570fd16 ths
}
685 c570fd16 ths
686 c570fd16 ths
void op_drotr (void)
687 c570fd16 ths
{
688 c570fd16 ths
    target_ulong tmp;
689 c570fd16 ths
690 c570fd16 ths
    if (T1) {
691 c570fd16 ths
       tmp = T0 << (0x40 - T1);
692 c570fd16 ths
       T0 = (T0 >> T1) | tmp;
693 5a63bcb2 ths
    }
694 c570fd16 ths
    RETURN();
695 c570fd16 ths
}
696 c570fd16 ths
697 c570fd16 ths
void op_drotr32 (void)
698 c570fd16 ths
{
699 c570fd16 ths
    target_ulong tmp;
700 c570fd16 ths
701 c570fd16 ths
    if (T1) {
702 c570fd16 ths
       tmp = T0 << (0x40 - (32 + T1));
703 c570fd16 ths
       T0 = (T0 >> (32 + T1)) | tmp;
704 5a63bcb2 ths
    }
705 c570fd16 ths
    RETURN();
706 c570fd16 ths
}
707 c570fd16 ths
708 c570fd16 ths
void op_dsllv (void)
709 c570fd16 ths
{
710 c570fd16 ths
    T0 = T1 << (T0 & 0x3F);
711 c570fd16 ths
    RETURN();
712 c570fd16 ths
}
713 c570fd16 ths
714 c570fd16 ths
void op_dsrav (void)
715 c570fd16 ths
{
716 c570fd16 ths
    T0 = (int64_t)T1 >> (T0 & 0x3F);
717 c570fd16 ths
    RETURN();
718 c570fd16 ths
}
719 c570fd16 ths
720 c570fd16 ths
void op_dsrlv (void)
721 c570fd16 ths
{
722 c570fd16 ths
    T0 = T1 >> (T0 & 0x3F);
723 c570fd16 ths
    RETURN();
724 c570fd16 ths
}
725 c570fd16 ths
726 c570fd16 ths
void op_drotrv (void)
727 c570fd16 ths
{
728 c570fd16 ths
    target_ulong tmp;
729 c570fd16 ths
730 c570fd16 ths
    T0 &= 0x3F;
731 c570fd16 ths
    if (T0) {
732 c570fd16 ths
       tmp = T1 << (0x40 - T0);
733 c570fd16 ths
       T0 = (T1 >> T0) | tmp;
734 c570fd16 ths
    } else
735 c570fd16 ths
       T0 = T1;
736 c570fd16 ths
    RETURN();
737 c570fd16 ths
}
738 c570fd16 ths
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
739 c570fd16 ths
740 c570fd16 ths
void op_dclo (void)
741 c570fd16 ths
{
742 c570fd16 ths
    int n;
743 c570fd16 ths
744 c570fd16 ths
    if (T0 == ~((target_ulong)0)) {
745 c570fd16 ths
        T0 = 64;
746 c570fd16 ths
    } else {
747 c570fd16 ths
        for (n = 0; n < 64; n++) {
748 c570fd16 ths
            if (!(T0 & (1ULL << 63)))
749 c570fd16 ths
                break;
750 c570fd16 ths
            T0 = T0 << 1;
751 c570fd16 ths
        }
752 c570fd16 ths
        T0 = n;
753 c570fd16 ths
    }
754 c570fd16 ths
    RETURN();
755 c570fd16 ths
}
756 c570fd16 ths
757 c570fd16 ths
void op_dclz (void)
758 c570fd16 ths
{
759 c570fd16 ths
    int n;
760 c570fd16 ths
761 c570fd16 ths
    if (T0 == 0) {
762 c570fd16 ths
        T0 = 64;
763 c570fd16 ths
    } else {
764 c570fd16 ths
        for (n = 0; n < 64; n++) {
765 c570fd16 ths
            if (T0 & (1ULL << 63))
766 c570fd16 ths
                break;
767 c570fd16 ths
            T0 = T0 << 1;
768 c570fd16 ths
        }
769 c570fd16 ths
        T0 = n;
770 c570fd16 ths
    }
771 c570fd16 ths
    RETURN();
772 c570fd16 ths
}
773 c570fd16 ths
#endif
774 c570fd16 ths
775 c570fd16 ths
/* 64 bits arithmetic */
776 c570fd16 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
777 6af0bf9c bellard
void op_mult (void)
778 6af0bf9c bellard
{
779 6af0bf9c bellard
    CALL_FROM_TB0(do_mult);
780 6af0bf9c bellard
    RETURN();
781 6af0bf9c bellard
}
782 6af0bf9c bellard
783 6af0bf9c bellard
void op_multu (void)
784 6af0bf9c bellard
{
785 6af0bf9c bellard
    CALL_FROM_TB0(do_multu);
786 6af0bf9c bellard
    RETURN();
787 6af0bf9c bellard
}
788 6af0bf9c bellard
789 6af0bf9c bellard
void op_madd (void)
790 6af0bf9c bellard
{
791 6af0bf9c bellard
    CALL_FROM_TB0(do_madd);
792 6af0bf9c bellard
    RETURN();
793 6af0bf9c bellard
}
794 6af0bf9c bellard
795 6af0bf9c bellard
void op_maddu (void)
796 6af0bf9c bellard
{
797 6af0bf9c bellard
    CALL_FROM_TB0(do_maddu);
798 6af0bf9c bellard
    RETURN();
799 6af0bf9c bellard
}
800 6af0bf9c bellard
801 6af0bf9c bellard
void op_msub (void)
802 6af0bf9c bellard
{
803 6af0bf9c bellard
    CALL_FROM_TB0(do_msub);
804 6af0bf9c bellard
    RETURN();
805 6af0bf9c bellard
}
806 6af0bf9c bellard
807 6af0bf9c bellard
void op_msubu (void)
808 6af0bf9c bellard
{
809 6af0bf9c bellard
    CALL_FROM_TB0(do_msubu);
810 6af0bf9c bellard
    RETURN();
811 6af0bf9c bellard
}
812 c570fd16 ths
813 c570fd16 ths
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
814 c570fd16 ths
815 c570fd16 ths
static inline uint64_t get_HILO (void)
816 c570fd16 ths
{
817 c570fd16 ths
    return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
818 c570fd16 ths
}
819 c570fd16 ths
820 c570fd16 ths
static inline void set_HILO (uint64_t HILO)
821 c570fd16 ths
{
822 5dc4b744 ths
    env->LO = (int32_t)(HILO & 0xFFFFFFFF);
823 5dc4b744 ths
    env->HI = (int32_t)(HILO >> 32);
824 c570fd16 ths
}
825 c570fd16 ths
826 c570fd16 ths
void op_mult (void)
827 c570fd16 ths
{
828 c570fd16 ths
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
829 c570fd16 ths
    RETURN();
830 c570fd16 ths
}
831 c570fd16 ths
832 c570fd16 ths
void op_multu (void)
833 c570fd16 ths
{
834 c570fd16 ths
    set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
835 c570fd16 ths
    RETURN();
836 c570fd16 ths
}
837 c570fd16 ths
838 c570fd16 ths
void op_madd (void)
839 c570fd16 ths
{
840 c570fd16 ths
    int64_t tmp;
841 c570fd16 ths
842 c570fd16 ths
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
843 c570fd16 ths
    set_HILO((int64_t)get_HILO() + tmp);
844 c570fd16 ths
    RETURN();
845 c570fd16 ths
}
846 c570fd16 ths
847 c570fd16 ths
void op_maddu (void)
848 c570fd16 ths
{
849 c570fd16 ths
    uint64_t tmp;
850 c570fd16 ths
851 c570fd16 ths
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
852 c570fd16 ths
    set_HILO(get_HILO() + tmp);
853 c570fd16 ths
    RETURN();
854 c570fd16 ths
}
855 c570fd16 ths
856 c570fd16 ths
void op_msub (void)
857 c570fd16 ths
{
858 c570fd16 ths
    int64_t tmp;
859 c570fd16 ths
860 c570fd16 ths
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
861 c570fd16 ths
    set_HILO((int64_t)get_HILO() - tmp);
862 c570fd16 ths
    RETURN();
863 c570fd16 ths
}
864 c570fd16 ths
865 c570fd16 ths
void op_msubu (void)
866 c570fd16 ths
{
867 c570fd16 ths
    uint64_t tmp;
868 c570fd16 ths
869 c570fd16 ths
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
870 c570fd16 ths
    set_HILO(get_HILO() - tmp);
871 c570fd16 ths
    RETURN();
872 c570fd16 ths
}
873 c570fd16 ths
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
874 c570fd16 ths
875 60aa19ab ths
#ifdef TARGET_MIPS64
876 c570fd16 ths
void op_dmult (void)
877 c570fd16 ths
{
878 69d35728 ths
    CALL_FROM_TB4(muls64, &(env->HI), &(env->LO), T0, T1);
879 c570fd16 ths
    RETURN();
880 c570fd16 ths
}
881 c570fd16 ths
882 c570fd16 ths
void op_dmultu (void)
883 c570fd16 ths
{
884 69d35728 ths
    CALL_FROM_TB4(mulu64, &(env->HI), &(env->LO), T0, T1);
885 c570fd16 ths
    RETURN();
886 c570fd16 ths
}
887 6af0bf9c bellard
#endif
888 6af0bf9c bellard
889 6af0bf9c bellard
/* Conditional moves */
890 6af0bf9c bellard
void op_movn (void)
891 6af0bf9c bellard
{
892 6af0bf9c bellard
    if (T1 != 0)
893 6af0bf9c bellard
        env->gpr[PARAM1] = T0;
894 6af0bf9c bellard
    RETURN();
895 6af0bf9c bellard
}
896 6af0bf9c bellard
897 6af0bf9c bellard
void op_movz (void)
898 6af0bf9c bellard
{
899 6af0bf9c bellard
    if (T1 == 0)
900 6af0bf9c bellard
        env->gpr[PARAM1] = T0;
901 6af0bf9c bellard
    RETURN();
902 6af0bf9c bellard
}
903 6af0bf9c bellard
904 7a387fff ths
void op_movf (void)
905 7a387fff ths
{
906 7a387fff ths
    if (!(env->fcr31 & PARAM1))
907 5a5012ec ths
        T0 = T1;
908 7a387fff ths
    RETURN();
909 7a387fff ths
}
910 7a387fff ths
911 7a387fff ths
void op_movt (void)
912 7a387fff ths
{
913 7a387fff ths
    if (env->fcr31 & PARAM1)
914 5a5012ec ths
        T0 = T1;
915 7a387fff ths
    RETURN();
916 7a387fff ths
}
917 7a387fff ths
918 6af0bf9c bellard
/* Tests */
919 6af0bf9c bellard
#define OP_COND(name, cond) \
920 6af0bf9c bellard
void glue(op_, name) (void) \
921 6af0bf9c bellard
{                           \
922 6af0bf9c bellard
    if (cond) {             \
923 6af0bf9c bellard
        T0 = 1;             \
924 6af0bf9c bellard
    } else {                \
925 6af0bf9c bellard
        T0 = 0;             \
926 6af0bf9c bellard
    }                       \
927 6af0bf9c bellard
    RETURN();               \
928 6af0bf9c bellard
}
929 6af0bf9c bellard
930 6af0bf9c bellard
OP_COND(eq, T0 == T1);
931 6af0bf9c bellard
OP_COND(ne, T0 != T1);
932 f469b9db ths
OP_COND(ge, (target_long)T0 >= (target_long)T1);
933 6af0bf9c bellard
OP_COND(geu, T0 >= T1);
934 f469b9db ths
OP_COND(lt, (target_long)T0 < (target_long)T1);
935 6af0bf9c bellard
OP_COND(ltu, T0 < T1);
936 f469b9db ths
OP_COND(gez, (target_long)T0 >= 0);
937 f469b9db ths
OP_COND(gtz, (target_long)T0 > 0);
938 f469b9db ths
OP_COND(lez, (target_long)T0 <= 0);
939 f469b9db ths
OP_COND(ltz, (target_long)T0 < 0);
940 6af0bf9c bellard
941 7a387fff ths
/* Branches */
942 c53be334 bellard
void OPPROTO op_goto_tb0(void)
943 c53be334 bellard
{
944 c53be334 bellard
    GOTO_TB(op_goto_tb0, PARAM1, 0);
945 7a387fff ths
    RETURN();
946 c53be334 bellard
}
947 c53be334 bellard
948 c53be334 bellard
void OPPROTO op_goto_tb1(void)
949 c53be334 bellard
{
950 c53be334 bellard
    GOTO_TB(op_goto_tb1, PARAM1, 1);
951 7a387fff ths
    RETURN();
952 c53be334 bellard
}
953 6af0bf9c bellard
954 6af0bf9c bellard
/* Branch to register */
955 6af0bf9c bellard
void op_save_breg_target (void)
956 6af0bf9c bellard
{
957 6af0bf9c bellard
    env->btarget = T2;
958 7a387fff ths
    RETURN();
959 6af0bf9c bellard
}
960 6af0bf9c bellard
961 6af0bf9c bellard
void op_restore_breg_target (void)
962 6af0bf9c bellard
{
963 6af0bf9c bellard
    T2 = env->btarget;
964 7a387fff ths
    RETURN();
965 6af0bf9c bellard
}
966 6af0bf9c bellard
967 6af0bf9c bellard
void op_breg (void)
968 6af0bf9c bellard
{
969 6af0bf9c bellard
    env->PC = T2;
970 6af0bf9c bellard
    RETURN();
971 6af0bf9c bellard
}
972 6af0bf9c bellard
973 6af0bf9c bellard
void op_save_btarget (void)
974 6af0bf9c bellard
{
975 6af0bf9c bellard
    env->btarget = PARAM1;
976 6af0bf9c bellard
    RETURN();
977 6af0bf9c bellard
}
978 6af0bf9c bellard
979 9b9e4393 ths
#ifdef TARGET_MIPS64
980 9b9e4393 ths
void op_save_btarget64 (void)
981 9b9e4393 ths
{
982 9b9e4393 ths
    env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
983 9b9e4393 ths
    RETURN();
984 9b9e4393 ths
}
985 9b9e4393 ths
#endif
986 9b9e4393 ths
987 6af0bf9c bellard
/* Conditional branch */
988 6af0bf9c bellard
void op_set_bcond (void)
989 6af0bf9c bellard
{
990 6af0bf9c bellard
    T2 = T0;
991 6af0bf9c bellard
    RETURN();
992 6af0bf9c bellard
}
993 6af0bf9c bellard
994 6af0bf9c bellard
void op_save_bcond (void)
995 6af0bf9c bellard
{
996 6af0bf9c bellard
    env->bcond = T2;
997 6af0bf9c bellard
    RETURN();
998 6af0bf9c bellard
}
999 6af0bf9c bellard
1000 6af0bf9c bellard
void op_restore_bcond (void)
1001 6af0bf9c bellard
{
1002 6af0bf9c bellard
    T2 = env->bcond;
1003 6af0bf9c bellard
    RETURN();
1004 6af0bf9c bellard
}
1005 6af0bf9c bellard
1006 c53be334 bellard
void op_jnz_T2 (void)
1007 6af0bf9c bellard
{
1008 c53be334 bellard
    if (T2)
1009 c53be334 bellard
        GOTO_LABEL_PARAM(1);
1010 6af0bf9c bellard
    RETURN();
1011 6af0bf9c bellard
}
1012 6af0bf9c bellard
1013 6af0bf9c bellard
/* CP0 functions */
1014 873eb012 ths
void op_mfc0_index (void)
1015 6af0bf9c bellard
{
1016 9c2149c8 ths
    T0 = env->CP0_Index;
1017 873eb012 ths
    RETURN();
1018 873eb012 ths
}
1019 873eb012 ths
1020 873eb012 ths
void op_mfc0_random (void)
1021 873eb012 ths
{
1022 873eb012 ths
    CALL_FROM_TB0(do_mfc0_random);
1023 873eb012 ths
    RETURN();
1024 873eb012 ths
}
1025 873eb012 ths
1026 873eb012 ths
void op_mfc0_entrylo0 (void)
1027 873eb012 ths
{
1028 9c2149c8 ths
    T0 = (int32_t)env->CP0_EntryLo0;
1029 873eb012 ths
    RETURN();
1030 873eb012 ths
}
1031 873eb012 ths
1032 873eb012 ths
void op_mfc0_entrylo1 (void)
1033 873eb012 ths
{
1034 9c2149c8 ths
    T0 = (int32_t)env->CP0_EntryLo1;
1035 873eb012 ths
    RETURN();
1036 873eb012 ths
}
1037 873eb012 ths
1038 873eb012 ths
void op_mfc0_context (void)
1039 873eb012 ths
{
1040 9c2149c8 ths
    T0 = (int32_t)env->CP0_Context;
1041 873eb012 ths
    RETURN();
1042 873eb012 ths
}
1043 873eb012 ths
1044 873eb012 ths
void op_mfc0_pagemask (void)
1045 873eb012 ths
{
1046 9c2149c8 ths
    T0 = env->CP0_PageMask;
1047 873eb012 ths
    RETURN();
1048 873eb012 ths
}
1049 873eb012 ths
1050 7a387fff ths
void op_mfc0_pagegrain (void)
1051 7a387fff ths
{
1052 9c2149c8 ths
    T0 = env->CP0_PageGrain;
1053 7a387fff ths
    RETURN();
1054 7a387fff ths
}
1055 7a387fff ths
1056 873eb012 ths
void op_mfc0_wired (void)
1057 873eb012 ths
{
1058 9c2149c8 ths
    T0 = env->CP0_Wired;
1059 873eb012 ths
    RETURN();
1060 873eb012 ths
}
1061 873eb012 ths
1062 7a387fff ths
void op_mfc0_hwrena (void)
1063 7a387fff ths
{
1064 9c2149c8 ths
    T0 = env->CP0_HWREna;
1065 7a387fff ths
    RETURN();
1066 7a387fff ths
}
1067 7a387fff ths
1068 873eb012 ths
void op_mfc0_badvaddr (void)
1069 873eb012 ths
{
1070 9c2149c8 ths
    T0 = (int32_t)env->CP0_BadVAddr;
1071 873eb012 ths
    RETURN();
1072 873eb012 ths
}
1073 873eb012 ths
1074 873eb012 ths
void op_mfc0_count (void)
1075 873eb012 ths
{
1076 873eb012 ths
    CALL_FROM_TB0(do_mfc0_count);
1077 873eb012 ths
    RETURN();
1078 873eb012 ths
}
1079 873eb012 ths
1080 873eb012 ths
void op_mfc0_entryhi (void)
1081 873eb012 ths
{
1082 9c2149c8 ths
    T0 = (int32_t)env->CP0_EntryHi;
1083 873eb012 ths
    RETURN();
1084 873eb012 ths
}
1085 873eb012 ths
1086 873eb012 ths
void op_mfc0_compare (void)
1087 873eb012 ths
{
1088 9c2149c8 ths
    T0 = env->CP0_Compare;
1089 873eb012 ths
    RETURN();
1090 873eb012 ths
}
1091 873eb012 ths
1092 873eb012 ths
void op_mfc0_status (void)
1093 873eb012 ths
{
1094 9c2149c8 ths
    T0 = env->CP0_Status;
1095 873eb012 ths
    RETURN();
1096 873eb012 ths
}
1097 873eb012 ths
1098 7a387fff ths
void op_mfc0_intctl (void)
1099 7a387fff ths
{
1100 9c2149c8 ths
    T0 = env->CP0_IntCtl;
1101 7a387fff ths
    RETURN();
1102 7a387fff ths
}
1103 7a387fff ths
1104 7a387fff ths
void op_mfc0_srsctl (void)
1105 7a387fff ths
{
1106 9c2149c8 ths
    T0 = env->CP0_SRSCtl;
1107 9c2149c8 ths
    RETURN();
1108 9c2149c8 ths
}
1109 9c2149c8 ths
1110 9c2149c8 ths
void op_mfc0_srsmap (void)
1111 9c2149c8 ths
{
1112 9c2149c8 ths
    T0 = env->CP0_SRSMap;
1113 7a387fff ths
    RETURN();
1114 7a387fff ths
}
1115 7a387fff ths
1116 873eb012 ths
void op_mfc0_cause (void)
1117 873eb012 ths
{
1118 9c2149c8 ths
    T0 = env->CP0_Cause;
1119 873eb012 ths
    RETURN();
1120 873eb012 ths
}
1121 873eb012 ths
1122 873eb012 ths
void op_mfc0_epc (void)
1123 873eb012 ths
{
1124 9c2149c8 ths
    T0 = (int32_t)env->CP0_EPC;
1125 873eb012 ths
    RETURN();
1126 873eb012 ths
}
1127 873eb012 ths
1128 873eb012 ths
void op_mfc0_prid (void)
1129 873eb012 ths
{
1130 9c2149c8 ths
    T0 = env->CP0_PRid;
1131 873eb012 ths
    RETURN();
1132 873eb012 ths
}
1133 873eb012 ths
1134 7a387fff ths
void op_mfc0_ebase (void)
1135 7a387fff ths
{
1136 b29a0341 ths
    T0 = env->CP0_EBase;
1137 7a387fff ths
    RETURN();
1138 7a387fff ths
}
1139 7a387fff ths
1140 873eb012 ths
void op_mfc0_config0 (void)
1141 873eb012 ths
{
1142 9c2149c8 ths
    T0 = env->CP0_Config0;
1143 873eb012 ths
    RETURN();
1144 873eb012 ths
}
1145 873eb012 ths
1146 873eb012 ths
void op_mfc0_config1 (void)
1147 873eb012 ths
{
1148 9c2149c8 ths
    T0 = env->CP0_Config1;
1149 873eb012 ths
    RETURN();
1150 873eb012 ths
}
1151 873eb012 ths
1152 7a387fff ths
void op_mfc0_config2 (void)
1153 7a387fff ths
{
1154 9c2149c8 ths
    T0 = env->CP0_Config2;
1155 7a387fff ths
    RETURN();
1156 7a387fff ths
}
1157 7a387fff ths
1158 7a387fff ths
void op_mfc0_config3 (void)
1159 7a387fff ths
{
1160 9c2149c8 ths
    T0 = env->CP0_Config3;
1161 7a387fff ths
    RETURN();
1162 7a387fff ths
}
1163 7a387fff ths
1164 e397ee33 ths
void op_mfc0_config6 (void)
1165 e397ee33 ths
{
1166 e397ee33 ths
    T0 = env->CP0_Config6;
1167 e397ee33 ths
    RETURN();
1168 e397ee33 ths
}
1169 e397ee33 ths
1170 e397ee33 ths
void op_mfc0_config7 (void)
1171 e397ee33 ths
{
1172 e397ee33 ths
    T0 = env->CP0_Config7;
1173 e397ee33 ths
    RETURN();
1174 e397ee33 ths
}
1175 e397ee33 ths
1176 873eb012 ths
void op_mfc0_lladdr (void)
1177 873eb012 ths
{
1178 9c2149c8 ths
    T0 = (int32_t)env->CP0_LLAddr >> 4;
1179 873eb012 ths
    RETURN();
1180 873eb012 ths
}
1181 873eb012 ths
1182 fd88b6ab ths
void op_mfc0_watchlo (void)
1183 873eb012 ths
{
1184 fd88b6ab ths
    T0 = (int32_t)env->CP0_WatchLo[PARAM1];
1185 873eb012 ths
    RETURN();
1186 873eb012 ths
}
1187 873eb012 ths
1188 fd88b6ab ths
void op_mfc0_watchhi (void)
1189 873eb012 ths
{
1190 fd88b6ab ths
    T0 = env->CP0_WatchHi[PARAM1];
1191 873eb012 ths
    RETURN();
1192 873eb012 ths
}
1193 873eb012 ths
1194 7a387fff ths
void op_mfc0_xcontext (void)
1195 7a387fff ths
{
1196 9c2149c8 ths
    T0 = (int32_t)env->CP0_XContext;
1197 7a387fff ths
    RETURN();
1198 7a387fff ths
}
1199 7a387fff ths
1200 7a387fff ths
void op_mfc0_framemask (void)
1201 7a387fff ths
{
1202 7a387fff ths
    T0 = env->CP0_Framemask;
1203 7a387fff ths
    RETURN();
1204 7a387fff ths
}
1205 7a387fff ths
1206 873eb012 ths
void op_mfc0_debug (void)
1207 873eb012 ths
{
1208 9c2149c8 ths
    T0 = env->CP0_Debug;
1209 873eb012 ths
    if (env->hflags & MIPS_HFLAG_DM)
1210 873eb012 ths
        T0 |= 1 << CP0DB_DM;
1211 873eb012 ths
    RETURN();
1212 873eb012 ths
}
1213 873eb012 ths
1214 873eb012 ths
void op_mfc0_depc (void)
1215 873eb012 ths
{
1216 9c2149c8 ths
    T0 = (int32_t)env->CP0_DEPC;
1217 873eb012 ths
    RETURN();
1218 873eb012 ths
}
1219 873eb012 ths
1220 7a387fff ths
void op_mfc0_performance0 (void)
1221 7a387fff ths
{
1222 9c2149c8 ths
    T0 = env->CP0_Performance0;
1223 7a387fff ths
    RETURN();
1224 7a387fff ths
}
1225 7a387fff ths
1226 873eb012 ths
void op_mfc0_taglo (void)
1227 873eb012 ths
{
1228 9c2149c8 ths
    T0 = env->CP0_TagLo;
1229 873eb012 ths
    RETURN();
1230 873eb012 ths
}
1231 873eb012 ths
1232 873eb012 ths
void op_mfc0_datalo (void)
1233 873eb012 ths
{
1234 9c2149c8 ths
    T0 = env->CP0_DataLo;
1235 873eb012 ths
    RETURN();
1236 873eb012 ths
}
1237 873eb012 ths
1238 7a387fff ths
void op_mfc0_taghi (void)
1239 7a387fff ths
{
1240 9c2149c8 ths
    T0 = env->CP0_TagHi;
1241 7a387fff ths
    RETURN();
1242 7a387fff ths
}
1243 7a387fff ths
1244 7a387fff ths
void op_mfc0_datahi (void)
1245 7a387fff ths
{
1246 9c2149c8 ths
    T0 = env->CP0_DataHi;
1247 7a387fff ths
    RETURN();
1248 7a387fff ths
}
1249 7a387fff ths
1250 873eb012 ths
void op_mfc0_errorepc (void)
1251 873eb012 ths
{
1252 9c2149c8 ths
    T0 = (int32_t)env->CP0_ErrorEPC;
1253 873eb012 ths
    RETURN();
1254 873eb012 ths
}
1255 873eb012 ths
1256 873eb012 ths
void op_mfc0_desave (void)
1257 873eb012 ths
{
1258 9c2149c8 ths
    T0 = env->CP0_DESAVE;
1259 6af0bf9c bellard
    RETURN();
1260 6af0bf9c bellard
}
1261 6af0bf9c bellard
1262 8c0fdd85 ths
void op_mtc0_index (void)
1263 6af0bf9c bellard
{
1264 fcb4a419 ths
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->nb_tlb);
1265 8c0fdd85 ths
    RETURN();
1266 8c0fdd85 ths
}
1267 8c0fdd85 ths
1268 8c0fdd85 ths
void op_mtc0_entrylo0 (void)
1269 8c0fdd85 ths
{
1270 7a387fff ths
    /* Large physaddr not implemented */
1271 7a387fff ths
    /* 1k pages not implemented */
1272 f1b0aa5d ths
    env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1273 8c0fdd85 ths
    RETURN();
1274 8c0fdd85 ths
}
1275 8c0fdd85 ths
1276 8c0fdd85 ths
void op_mtc0_entrylo1 (void)
1277 8c0fdd85 ths
{
1278 7a387fff ths
    /* Large physaddr not implemented */
1279 7a387fff ths
    /* 1k pages not implemented */
1280 f1b0aa5d ths
    env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1281 8c0fdd85 ths
    RETURN();
1282 8c0fdd85 ths
}
1283 8c0fdd85 ths
1284 8c0fdd85 ths
void op_mtc0_context (void)
1285 8c0fdd85 ths
{
1286 534ce69f ths
    env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1287 8c0fdd85 ths
    RETURN();
1288 8c0fdd85 ths
}
1289 8c0fdd85 ths
1290 8c0fdd85 ths
void op_mtc0_pagemask (void)
1291 8c0fdd85 ths
{
1292 7a387fff ths
    /* 1k pages not implemented */
1293 f2e9ebef ths
    env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1294 7a387fff ths
    RETURN();
1295 7a387fff ths
}
1296 7a387fff ths
1297 7a387fff ths
void op_mtc0_pagegrain (void)
1298 7a387fff ths
{
1299 7a387fff ths
    /* SmartMIPS not implemented */
1300 7a387fff ths
    /* Large physaddr not implemented */
1301 7a387fff ths
    /* 1k pages not implemented */
1302 7a387fff ths
    env->CP0_PageGrain = 0;
1303 8c0fdd85 ths
    RETURN();
1304 8c0fdd85 ths
}
1305 8c0fdd85 ths
1306 8c0fdd85 ths
void op_mtc0_wired (void)
1307 8c0fdd85 ths
{
1308 fcb4a419 ths
    env->CP0_Wired = T0 % env->nb_tlb;
1309 7a387fff ths
    RETURN();
1310 7a387fff ths
}
1311 7a387fff ths
1312 7a387fff ths
void op_mtc0_hwrena (void)
1313 7a387fff ths
{
1314 7a387fff ths
    env->CP0_HWREna = T0 & 0x0000000F;
1315 8c0fdd85 ths
    RETURN();
1316 8c0fdd85 ths
}
1317 8c0fdd85 ths
1318 8c0fdd85 ths
void op_mtc0_count (void)
1319 8c0fdd85 ths
{
1320 8c0fdd85 ths
    CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1321 8c0fdd85 ths
    RETURN();
1322 8c0fdd85 ths
}
1323 8c0fdd85 ths
1324 8c0fdd85 ths
void op_mtc0_entryhi (void)
1325 8c0fdd85 ths
{
1326 0feef828 ths
    target_ulong old, val;
1327 8c0fdd85 ths
1328 7a387fff ths
    /* 1k pages not implemented */
1329 100ce988 ths
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1330 100ce988 ths
#ifdef TARGET_MIPS64
1331 100ce988 ths
    val = T0 & 0xC00000FFFFFFFFFFULL;
1332 100ce988 ths
#endif
1333 8c0fdd85 ths
    old = env->CP0_EntryHi;
1334 8c0fdd85 ths
    env->CP0_EntryHi = val;
1335 8c0fdd85 ths
    /* If the ASID changes, flush qemu's TLB.  */
1336 8c0fdd85 ths
    if ((old & 0xFF) != (val & 0xFF))
1337 8c0fdd85 ths
        CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1338 8c0fdd85 ths
    RETURN();
1339 8c0fdd85 ths
}
1340 8c0fdd85 ths
1341 8c0fdd85 ths
void op_mtc0_compare (void)
1342 8c0fdd85 ths
{
1343 8c0fdd85 ths
    CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1344 8c0fdd85 ths
    RETURN();
1345 8c0fdd85 ths
}
1346 8c0fdd85 ths
1347 8c0fdd85 ths
void op_mtc0_status (void)
1348 8c0fdd85 ths
{
1349 4de9b249 ths
    uint32_t val, old;
1350 5a5012ec ths
    uint32_t mask = env->Status_rw_bitmask;
1351 8c0fdd85 ths
1352 f1b0aa5d ths
    /* No reverse endianness, no MDMX/DSP, no 64bit ops
1353 f1b0aa5d ths
       implemented. */
1354 f1b0aa5d ths
    val = T0 & mask;
1355 8c0fdd85 ths
    old = env->CP0_Status;
1356 f41c52f1 ths
    if (!(val & (1 << CP0St_EXL)) &&
1357 f41c52f1 ths
        !(val & (1 << CP0St_ERL)) &&
1358 f41c52f1 ths
        !(env->hflags & MIPS_HFLAG_DM) &&
1359 f41c52f1 ths
        (val & (1 << CP0St_UM)))
1360 f41c52f1 ths
        env->hflags |= MIPS_HFLAG_UM;
1361 5a5012ec ths
    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1362 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
1363 f41c52f1 ths
        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1364 4de9b249 ths
    CALL_FROM_TB1(cpu_mips_update_irq, env);
1365 8c0fdd85 ths
    RETURN();
1366 8c0fdd85 ths
}
1367 8c0fdd85 ths
1368 7a387fff ths
void op_mtc0_intctl (void)
1369 7a387fff ths
{
1370 c090a8f4 ths
    /* vectored interrupts not implemented, timer on int 7,
1371 c090a8f4 ths
       no performance counters. */
1372 c090a8f4 ths
    env->CP0_IntCtl |= T0 & 0x000002e0;
1373 7a387fff ths
    RETURN();
1374 7a387fff ths
}
1375 7a387fff ths
1376 7a387fff ths
void op_mtc0_srsctl (void)
1377 7a387fff ths
{
1378 7a387fff ths
    /* shadow registers not implemented */
1379 7a387fff ths
    env->CP0_SRSCtl = 0;
1380 7a387fff ths
    RETURN();
1381 7a387fff ths
}
1382 7a387fff ths
1383 9c2149c8 ths
void op_mtc0_srsmap (void)
1384 9c2149c8 ths
{
1385 9c2149c8 ths
    /* shadow registers not implemented */
1386 9c2149c8 ths
    env->CP0_SRSMap = 0;
1387 9c2149c8 ths
    RETURN();
1388 9c2149c8 ths
}
1389 9c2149c8 ths
1390 8c0fdd85 ths
void op_mtc0_cause (void)
1391 8c0fdd85 ths
{
1392 39d51eb8 ths
    uint32_t mask = 0x00C00300;
1393 39d51eb8 ths
1394 39d51eb8 ths
    if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
1395 39d51eb8 ths
        mask |= 1 << CP0Ca_DC;
1396 39d51eb8 ths
1397 e58c8ba5 ths
    env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1398 8c0fdd85 ths
1399 4de9b249 ths
    /* Handle the software interrupt as an hardware one, as they
1400 4de9b249 ths
       are very similar */
1401 4de9b249 ths
    if (T0 & CP0Ca_IP_mask) {
1402 4de9b249 ths
        CALL_FROM_TB1(cpu_mips_update_irq, env);
1403 8c0fdd85 ths
    }
1404 8c0fdd85 ths
    RETURN();
1405 8c0fdd85 ths
}
1406 8c0fdd85 ths
1407 8c0fdd85 ths
void op_mtc0_epc (void)
1408 8c0fdd85 ths
{
1409 f1b0aa5d ths
    env->CP0_EPC = T0;
1410 8c0fdd85 ths
    RETURN();
1411 8c0fdd85 ths
}
1412 8c0fdd85 ths
1413 7a387fff ths
void op_mtc0_ebase (void)
1414 7a387fff ths
{
1415 7a387fff ths
    /* vectored interrupts not implemented */
1416 7a387fff ths
    /* Multi-CPU not implemented */
1417 b29a0341 ths
    env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1418 7a387fff ths
    RETURN();
1419 7a387fff ths
}
1420 7a387fff ths
1421 8c0fdd85 ths
void op_mtc0_config0 (void)
1422 8c0fdd85 ths
{
1423 29929e34 ths
    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000001);
1424 8c0fdd85 ths
    RETURN();
1425 8c0fdd85 ths
}
1426 8c0fdd85 ths
1427 7a387fff ths
void op_mtc0_config2 (void)
1428 7a387fff ths
{
1429 7a387fff ths
    /* tertiary/secondary caches not implemented */
1430 7a387fff ths
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1431 7a387fff ths
    RETURN();
1432 7a387fff ths
}
1433 7a387fff ths
1434 fd88b6ab ths
void op_mtc0_watchlo (void)
1435 8c0fdd85 ths
{
1436 4e7a4a4e ths
    /* Watch exceptions for instructions, data loads, data stores
1437 4e7a4a4e ths
       not implemented. */
1438 fd88b6ab ths
    env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1439 8c0fdd85 ths
    RETURN();
1440 8c0fdd85 ths
}
1441 8c0fdd85 ths
1442 fd88b6ab ths
void op_mtc0_watchhi (void)
1443 8c0fdd85 ths
{
1444 fd88b6ab ths
    env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1445 fd88b6ab ths
    env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1446 8c0fdd85 ths
    RETURN();
1447 8c0fdd85 ths
}
1448 8c0fdd85 ths
1449 7a387fff ths
void op_mtc0_framemask (void)
1450 7a387fff ths
{
1451 7a387fff ths
    env->CP0_Framemask = T0; /* XXX */
1452 7a387fff ths
    RETURN();
1453 7a387fff ths
}
1454 7a387fff ths
1455 8c0fdd85 ths
void op_mtc0_debug (void)
1456 8c0fdd85 ths
{
1457 8c0fdd85 ths
    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1458 8c0fdd85 ths
    if (T0 & (1 << CP0DB_DM))
1459 8c0fdd85 ths
        env->hflags |= MIPS_HFLAG_DM;
1460 8c0fdd85 ths
    else
1461 8c0fdd85 ths
        env->hflags &= ~MIPS_HFLAG_DM;
1462 8c0fdd85 ths
    RETURN();
1463 8c0fdd85 ths
}
1464 8c0fdd85 ths
1465 8c0fdd85 ths
void op_mtc0_depc (void)
1466 8c0fdd85 ths
{
1467 f1b0aa5d ths
    env->CP0_DEPC = T0;
1468 8c0fdd85 ths
    RETURN();
1469 8c0fdd85 ths
}
1470 8c0fdd85 ths
1471 7a387fff ths
void op_mtc0_performance0 (void)
1472 7a387fff ths
{
1473 7a387fff ths
    env->CP0_Performance0 = T0; /* XXX */
1474 7a387fff ths
    RETURN();
1475 7a387fff ths
}
1476 7a387fff ths
1477 8c0fdd85 ths
void op_mtc0_taglo (void)
1478 8c0fdd85 ths
{
1479 9c2149c8 ths
    env->CP0_TagLo = T0 & 0xFFFFFCF6;
1480 8c0fdd85 ths
    RETURN();
1481 8c0fdd85 ths
}
1482 8c0fdd85 ths
1483 7a387fff ths
void op_mtc0_datalo (void)
1484 7a387fff ths
{
1485 7a387fff ths
    env->CP0_DataLo = T0; /* XXX */
1486 7a387fff ths
    RETURN();
1487 7a387fff ths
}
1488 7a387fff ths
1489 7a387fff ths
void op_mtc0_taghi (void)
1490 7a387fff ths
{
1491 7a387fff ths
    env->CP0_TagHi = T0; /* XXX */
1492 7a387fff ths
    RETURN();
1493 7a387fff ths
}
1494 7a387fff ths
1495 7a387fff ths
void op_mtc0_datahi (void)
1496 7a387fff ths
{
1497 7a387fff ths
    env->CP0_DataHi = T0; /* XXX */
1498 7a387fff ths
    RETURN();
1499 7a387fff ths
}
1500 7a387fff ths
1501 8c0fdd85 ths
void op_mtc0_errorepc (void)
1502 8c0fdd85 ths
{
1503 f1b0aa5d ths
    env->CP0_ErrorEPC = T0;
1504 8c0fdd85 ths
    RETURN();
1505 8c0fdd85 ths
}
1506 8c0fdd85 ths
1507 8c0fdd85 ths
void op_mtc0_desave (void)
1508 8c0fdd85 ths
{
1509 8c0fdd85 ths
    env->CP0_DESAVE = T0;
1510 6af0bf9c bellard
    RETURN();
1511 6af0bf9c bellard
}
1512 6af0bf9c bellard
1513 534ce69f ths
#ifdef TARGET_MIPS64
1514 f1b0aa5d ths
void op_mtc0_xcontext (void)
1515 f1b0aa5d ths
{
1516 f1b0aa5d ths
    env->CP0_XContext = (env->CP0_XContext & 0x1ffffffffULL) | (T0 & ~0x1ffffffffULL);
1517 f1b0aa5d ths
    RETURN();
1518 f1b0aa5d ths
}
1519 f1b0aa5d ths
1520 9c2149c8 ths
void op_dmfc0_entrylo0 (void)
1521 9c2149c8 ths
{
1522 9c2149c8 ths
    T0 = env->CP0_EntryLo0;
1523 9c2149c8 ths
    RETURN();
1524 9c2149c8 ths
}
1525 9c2149c8 ths
1526 9c2149c8 ths
void op_dmfc0_entrylo1 (void)
1527 9c2149c8 ths
{
1528 9c2149c8 ths
    T0 = env->CP0_EntryLo1;
1529 9c2149c8 ths
    RETURN();
1530 9c2149c8 ths
}
1531 9c2149c8 ths
1532 9c2149c8 ths
void op_dmfc0_context (void)
1533 9c2149c8 ths
{
1534 9c2149c8 ths
    T0 = env->CP0_Context;
1535 9c2149c8 ths
    RETURN();
1536 9c2149c8 ths
}
1537 9c2149c8 ths
1538 9c2149c8 ths
void op_dmfc0_badvaddr (void)
1539 9c2149c8 ths
{
1540 9c2149c8 ths
    T0 = env->CP0_BadVAddr;
1541 9c2149c8 ths
    RETURN();
1542 9c2149c8 ths
}
1543 9c2149c8 ths
1544 9c2149c8 ths
void op_dmfc0_entryhi (void)
1545 9c2149c8 ths
{
1546 9c2149c8 ths
    T0 = env->CP0_EntryHi;
1547 9c2149c8 ths
    RETURN();
1548 9c2149c8 ths
}
1549 9c2149c8 ths
1550 9c2149c8 ths
void op_dmfc0_epc (void)
1551 9c2149c8 ths
{
1552 9c2149c8 ths
    T0 = env->CP0_EPC;
1553 9c2149c8 ths
    RETURN();
1554 9c2149c8 ths
}
1555 9c2149c8 ths
1556 9c2149c8 ths
void op_dmfc0_lladdr (void)
1557 9c2149c8 ths
{
1558 9c2149c8 ths
    T0 = env->CP0_LLAddr >> 4;
1559 9c2149c8 ths
    RETURN();
1560 9c2149c8 ths
}
1561 9c2149c8 ths
1562 fd88b6ab ths
void op_dmfc0_watchlo (void)
1563 9c2149c8 ths
{
1564 fd88b6ab ths
    T0 = env->CP0_WatchLo[PARAM1];
1565 9c2149c8 ths
    RETURN();
1566 9c2149c8 ths
}
1567 9c2149c8 ths
1568 9c2149c8 ths
void op_dmfc0_xcontext (void)
1569 9c2149c8 ths
{
1570 9c2149c8 ths
    T0 = env->CP0_XContext;
1571 9c2149c8 ths
    RETURN();
1572 9c2149c8 ths
}
1573 9c2149c8 ths
1574 9c2149c8 ths
void op_dmfc0_depc (void)
1575 9c2149c8 ths
{
1576 9c2149c8 ths
    T0 = env->CP0_DEPC;
1577 9c2149c8 ths
    RETURN();
1578 9c2149c8 ths
}
1579 9c2149c8 ths
1580 9c2149c8 ths
void op_dmfc0_errorepc (void)
1581 9c2149c8 ths
{
1582 9c2149c8 ths
    T0 = env->CP0_ErrorEPC;
1583 9c2149c8 ths
    RETURN();
1584 9c2149c8 ths
}
1585 534ce69f ths
#endif /* TARGET_MIPS64 */
1586 9c2149c8 ths
1587 5a5012ec ths
/* CP1 functions */
1588 6ea83fed bellard
#if 0
1589 6ea83fed bellard
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1590 6ea83fed bellard
#else
1591 6ea83fed bellard
# define DEBUG_FPU_STATE() do { } while(0)
1592 6ea83fed bellard
#endif
1593 6ea83fed bellard
1594 24c7b0e3 ths
void op_cp0_enabled(void)
1595 24c7b0e3 ths
{
1596 24c7b0e3 ths
    if (!(env->CP0_Status & (1 << CP0St_CU0)) &&
1597 24c7b0e3 ths
        (env->hflags & MIPS_HFLAG_UM)) {
1598 1579a72e ths
        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 0);
1599 24c7b0e3 ths
    }
1600 24c7b0e3 ths
    RETURN();
1601 24c7b0e3 ths
}
1602 24c7b0e3 ths
1603 6ea83fed bellard
void op_cp1_enabled(void)
1604 6ea83fed bellard
{
1605 6ea83fed bellard
    if (!(env->CP0_Status & (1 << CP0St_CU1))) {
1606 1579a72e ths
        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
1607 6ea83fed bellard
    }
1608 6ea83fed bellard
    RETURN();
1609 6ea83fed bellard
}
1610 6ea83fed bellard
1611 57fa1fb3 ths
void op_cp1_64bitmode(void)
1612 57fa1fb3 ths
{
1613 57fa1fb3 ths
    if (!(env->CP0_Status & (1 << CP0St_FR))) {
1614 57fa1fb3 ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
1615 57fa1fb3 ths
    }
1616 57fa1fb3 ths
    RETURN();
1617 57fa1fb3 ths
}
1618 57fa1fb3 ths
1619 fd4a04eb ths
/*
1620 fd4a04eb ths
 * Verify if floating point register is valid; an operation is not defined
1621 fd4a04eb ths
 * if bit 0 of any register specification is set and the FR bit in the
1622 fd4a04eb ths
 * Status register equals zero, since the register numbers specify an
1623 fd4a04eb ths
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1624 fd4a04eb ths
 * in the Status register equals one, both even and odd register numbers
1625 fd4a04eb ths
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1626 fd4a04eb ths
 *
1627 fd4a04eb ths
 * Multiple 64 bit wide registers can be checked by calling
1628 fd4a04eb ths
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1629 fd4a04eb ths
 */
1630 fd4a04eb ths
void op_cp1_registers(void)
1631 5a5012ec ths
{
1632 fd4a04eb ths
    if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) {
1633 fd4a04eb ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
1634 fd4a04eb ths
    }
1635 fd4a04eb ths
    RETURN();
1636 5a5012ec ths
}
1637 5a5012ec ths
1638 5a5012ec ths
void op_cfc1 (void)
1639 5a5012ec ths
{
1640 5a5012ec ths
    switch (T1) {
1641 5a5012ec ths
    case 0:
1642 5a5012ec ths
        T0 = (int32_t)env->fcr0;
1643 5a5012ec ths
        break;
1644 5a5012ec ths
    case 25:
1645 5a5012ec ths
        T0 = ((env->fcr31 >> 24) & 0xfe) | ((env->fcr31 >> 23) & 0x1);
1646 5a5012ec ths
        break;
1647 5a5012ec ths
    case 26:
1648 5a5012ec ths
        T0 = env->fcr31 & 0x0003f07c;
1649 5a5012ec ths
        break;
1650 5a5012ec ths
    case 28:
1651 5a5012ec ths
        T0 = (env->fcr31 & 0x00000f83) | ((env->fcr31 >> 22) & 0x4);
1652 5a5012ec ths
        break;
1653 5a5012ec ths
    default:
1654 5a5012ec ths
        T0 = (int32_t)env->fcr31;
1655 5a5012ec ths
        break;
1656 5a5012ec ths
    }
1657 5a5012ec ths
    DEBUG_FPU_STATE();
1658 5a5012ec ths
    RETURN();
1659 5a5012ec ths
}
1660 5a5012ec ths
1661 5a5012ec ths
void op_ctc1 (void)
1662 5a5012ec ths
{
1663 fd4a04eb ths
    CALL_FROM_TB0(do_ctc1);
1664 6ea83fed bellard
    DEBUG_FPU_STATE();
1665 6ea83fed bellard
    RETURN();
1666 6ea83fed bellard
}
1667 6ea83fed bellard
1668 6ea83fed bellard
void op_mfc1 (void)
1669 6ea83fed bellard
{
1670 6ea83fed bellard
    T0 = WT0;
1671 6ea83fed bellard
    DEBUG_FPU_STATE();
1672 6ea83fed bellard
    RETURN();
1673 6ea83fed bellard
}
1674 6ea83fed bellard
1675 6ea83fed bellard
void op_mtc1 (void)
1676 6ea83fed bellard
{
1677 6ea83fed bellard
    WT0 = T0;
1678 6ea83fed bellard
    DEBUG_FPU_STATE();
1679 6ea83fed bellard
    RETURN();
1680 6ea83fed bellard
}
1681 6ea83fed bellard
1682 5a5012ec ths
void op_dmfc1 (void)
1683 5a5012ec ths
{
1684 5a5012ec ths
    T0 = DT0;
1685 5a5012ec ths
    DEBUG_FPU_STATE();
1686 5a5012ec ths
    RETURN();
1687 5a5012ec ths
}
1688 5a5012ec ths
1689 5a5012ec ths
void op_dmtc1 (void)
1690 5a5012ec ths
{
1691 5a5012ec ths
    DT0 = T0;
1692 5a5012ec ths
    DEBUG_FPU_STATE();
1693 5a5012ec ths
    RETURN();
1694 5a5012ec ths
}
1695 5a5012ec ths
1696 5a5012ec ths
void op_mfhc1 (void)
1697 5a5012ec ths
{
1698 5a5012ec ths
    T0 = WTH0;
1699 5a5012ec ths
    DEBUG_FPU_STATE();
1700 5a5012ec ths
    RETURN();
1701 5a5012ec ths
}
1702 5a5012ec ths
1703 5a5012ec ths
void op_mthc1 (void)
1704 5a5012ec ths
{
1705 5a5012ec ths
    WTH0 = T0;
1706 5a5012ec ths
    DEBUG_FPU_STATE();
1707 5a5012ec ths
    RETURN();
1708 5a5012ec ths
}
1709 5a5012ec ths
1710 6ea83fed bellard
/* Float support.
1711 6ea83fed bellard
   Single precition routines have a "s" suffix, double precision a
1712 5a5012ec ths
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1713 5a5012ec ths
   paired single lowwer "pl", paired single upper "pu".  */
1714 6ea83fed bellard
1715 6ea83fed bellard
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1716 6ea83fed bellard
1717 dd016883 bellard
FLOAT_OP(cvtd, s)
1718 dd016883 bellard
{
1719 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtd_s);
1720 dd016883 bellard
    DEBUG_FPU_STATE();
1721 dd016883 bellard
    RETURN();
1722 dd016883 bellard
}
1723 6ea83fed bellard
FLOAT_OP(cvtd, w)
1724 6ea83fed bellard
{
1725 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtd_w);
1726 5a5012ec ths
    DEBUG_FPU_STATE();
1727 5a5012ec ths
    RETURN();
1728 5a5012ec ths
}
1729 5a5012ec ths
FLOAT_OP(cvtd, l)
1730 5a5012ec ths
{
1731 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtd_l);
1732 5a5012ec ths
    DEBUG_FPU_STATE();
1733 5a5012ec ths
    RETURN();
1734 5a5012ec ths
}
1735 5a5012ec ths
FLOAT_OP(cvtl, d)
1736 5a5012ec ths
{
1737 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtl_d);
1738 5a5012ec ths
    DEBUG_FPU_STATE();
1739 5a5012ec ths
    RETURN();
1740 5a5012ec ths
}
1741 5a5012ec ths
FLOAT_OP(cvtl, s)
1742 5a5012ec ths
{
1743 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtl_s);
1744 5a5012ec ths
    DEBUG_FPU_STATE();
1745 5a5012ec ths
    RETURN();
1746 5a5012ec ths
}
1747 5a5012ec ths
FLOAT_OP(cvtps, s)
1748 5a5012ec ths
{
1749 5a5012ec ths
    WT2 = WT0;
1750 5a5012ec ths
    WTH2 = WT1;
1751 5a5012ec ths
    DEBUG_FPU_STATE();
1752 5a5012ec ths
    RETURN();
1753 5a5012ec ths
}
1754 5a5012ec ths
FLOAT_OP(cvtps, pw)
1755 5a5012ec ths
{
1756 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtps_pw);
1757 5a5012ec ths
    DEBUG_FPU_STATE();
1758 5a5012ec ths
    RETURN();
1759 5a5012ec ths
}
1760 5a5012ec ths
FLOAT_OP(cvtpw, ps)
1761 5a5012ec ths
{
1762 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtpw_ps);
1763 6ea83fed bellard
    DEBUG_FPU_STATE();
1764 6ea83fed bellard
    RETURN();
1765 6ea83fed bellard
}
1766 dd016883 bellard
FLOAT_OP(cvts, d)
1767 dd016883 bellard
{
1768 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_d);
1769 dd016883 bellard
    DEBUG_FPU_STATE();
1770 dd016883 bellard
    RETURN();
1771 dd016883 bellard
}
1772 6ea83fed bellard
FLOAT_OP(cvts, w)
1773 6ea83fed bellard
{
1774 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_w);
1775 5a5012ec ths
    DEBUG_FPU_STATE();
1776 5a5012ec ths
    RETURN();
1777 5a5012ec ths
}
1778 5a5012ec ths
FLOAT_OP(cvts, l)
1779 5a5012ec ths
{
1780 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_l);
1781 5a5012ec ths
    DEBUG_FPU_STATE();
1782 5a5012ec ths
    RETURN();
1783 5a5012ec ths
}
1784 5a5012ec ths
FLOAT_OP(cvts, pl)
1785 5a5012ec ths
{
1786 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_pl);
1787 5a5012ec ths
    DEBUG_FPU_STATE();
1788 5a5012ec ths
    RETURN();
1789 5a5012ec ths
}
1790 5a5012ec ths
FLOAT_OP(cvts, pu)
1791 5a5012ec ths
{
1792 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_pu);
1793 6ea83fed bellard
    DEBUG_FPU_STATE();
1794 6ea83fed bellard
    RETURN();
1795 6ea83fed bellard
}
1796 6ea83fed bellard
FLOAT_OP(cvtw, s)
1797 6ea83fed bellard
{
1798 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtw_s);
1799 6ea83fed bellard
    DEBUG_FPU_STATE();
1800 6ea83fed bellard
    RETURN();
1801 6ea83fed bellard
}
1802 6ea83fed bellard
FLOAT_OP(cvtw, d)
1803 6ea83fed bellard
{
1804 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtw_d);
1805 5a5012ec ths
    DEBUG_FPU_STATE();
1806 5a5012ec ths
    RETURN();
1807 5a5012ec ths
}
1808 5a5012ec ths
1809 5a5012ec ths
FLOAT_OP(pll, ps)
1810 5a5012ec ths
{
1811 5a5012ec ths
    DT2 = ((uint64_t)WT0 << 32) | WT1;
1812 5a5012ec ths
    DEBUG_FPU_STATE();
1813 5a5012ec ths
    RETURN();
1814 5a5012ec ths
}
1815 5a5012ec ths
FLOAT_OP(plu, ps)
1816 5a5012ec ths
{
1817 5a5012ec ths
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
1818 5a5012ec ths
    DEBUG_FPU_STATE();
1819 5a5012ec ths
    RETURN();
1820 5a5012ec ths
}
1821 5a5012ec ths
FLOAT_OP(pul, ps)
1822 5a5012ec ths
{
1823 5a5012ec ths
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
1824 5a5012ec ths
    DEBUG_FPU_STATE();
1825 5a5012ec ths
    RETURN();
1826 5a5012ec ths
}
1827 5a5012ec ths
FLOAT_OP(puu, ps)
1828 5a5012ec ths
{
1829 5a5012ec ths
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1830 6ea83fed bellard
    DEBUG_FPU_STATE();
1831 6ea83fed bellard
    RETURN();
1832 6ea83fed bellard
}
1833 6ea83fed bellard
1834 fd4a04eb ths
#define FLOAT_ROUNDOP(op, ttype, stype)                    \
1835 fd4a04eb ths
FLOAT_OP(op ## ttype, stype)                               \
1836 fd4a04eb ths
{                                                          \
1837 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
1838 fd4a04eb ths
    DEBUG_FPU_STATE();                                     \
1839 fd4a04eb ths
    RETURN();                                              \
1840 6ea83fed bellard
}
1841 6ea83fed bellard
1842 fd4a04eb ths
FLOAT_ROUNDOP(round, l, d)
1843 fd4a04eb ths
FLOAT_ROUNDOP(round, l, s)
1844 fd4a04eb ths
FLOAT_ROUNDOP(round, w, d)
1845 fd4a04eb ths
FLOAT_ROUNDOP(round, w, s)
1846 6ea83fed bellard
1847 fd4a04eb ths
FLOAT_ROUNDOP(trunc, l, d)
1848 fd4a04eb ths
FLOAT_ROUNDOP(trunc, l, s)
1849 fd4a04eb ths
FLOAT_ROUNDOP(trunc, w, d)
1850 fd4a04eb ths
FLOAT_ROUNDOP(trunc, w, s)
1851 6ea83fed bellard
1852 fd4a04eb ths
FLOAT_ROUNDOP(ceil, l, d)
1853 fd4a04eb ths
FLOAT_ROUNDOP(ceil, l, s)
1854 fd4a04eb ths
FLOAT_ROUNDOP(ceil, w, d)
1855 fd4a04eb ths
FLOAT_ROUNDOP(ceil, w, s)
1856 fd4a04eb ths
1857 fd4a04eb ths
FLOAT_ROUNDOP(floor, l, d)
1858 fd4a04eb ths
FLOAT_ROUNDOP(floor, l, s)
1859 fd4a04eb ths
FLOAT_ROUNDOP(floor, w, d)
1860 fd4a04eb ths
FLOAT_ROUNDOP(floor, w, s)
1861 fd4a04eb ths
#undef FLOAR_ROUNDOP
1862 6ea83fed bellard
1863 5a5012ec ths
FLOAT_OP(movf, d)
1864 5a5012ec ths
{
1865 5a5012ec ths
    if (!(env->fcr31 & PARAM1))
1866 5a5012ec ths
        DT2 = DT0;
1867 5a5012ec ths
    DEBUG_FPU_STATE();
1868 5a5012ec ths
    RETURN();
1869 5a5012ec ths
}
1870 5a5012ec ths
FLOAT_OP(movf, s)
1871 5a5012ec ths
{
1872 5a5012ec ths
    if (!(env->fcr31 & PARAM1))
1873 5a5012ec ths
        WT2 = WT0;
1874 5a5012ec ths
    DEBUG_FPU_STATE();
1875 5a5012ec ths
    RETURN();
1876 5a5012ec ths
}
1877 5a5012ec ths
FLOAT_OP(movf, ps)
1878 5a5012ec ths
{
1879 5a5012ec ths
    if (!(env->fcr31 & PARAM1)) {
1880 5a5012ec ths
        WT2 = WT0;
1881 5a5012ec ths
        WTH2 = WTH0;
1882 5a5012ec ths
    }
1883 5a5012ec ths
    DEBUG_FPU_STATE();
1884 5a5012ec ths
    RETURN();
1885 5a5012ec ths
}
1886 5a5012ec ths
FLOAT_OP(movt, d)
1887 5a5012ec ths
{
1888 5a5012ec ths
    if (env->fcr31 & PARAM1)
1889 5a5012ec ths
        DT2 = DT0;
1890 5a5012ec ths
    DEBUG_FPU_STATE();
1891 5a5012ec ths
    RETURN();
1892 5a5012ec ths
}
1893 5a5012ec ths
FLOAT_OP(movt, s)
1894 5a5012ec ths
{
1895 5a5012ec ths
    if (env->fcr31 & PARAM1)
1896 5a5012ec ths
        WT2 = WT0;
1897 5a5012ec ths
    DEBUG_FPU_STATE();
1898 5a5012ec ths
    RETURN();
1899 5a5012ec ths
}
1900 5a5012ec ths
FLOAT_OP(movt, ps)
1901 5a5012ec ths
{
1902 5a5012ec ths
    if (env->fcr31 & PARAM1) {
1903 5a5012ec ths
        WT2 = WT0;
1904 5a5012ec ths
        WTH2 = WTH0;
1905 5a5012ec ths
    }
1906 5a5012ec ths
    DEBUG_FPU_STATE();
1907 5a5012ec ths
    RETURN();
1908 5a5012ec ths
}
1909 5a5012ec ths
FLOAT_OP(movz, d)
1910 5a5012ec ths
{
1911 5a5012ec ths
    if (!T0)
1912 5a5012ec ths
        DT2 = DT0;
1913 5a5012ec ths
    DEBUG_FPU_STATE();
1914 5a5012ec ths
    RETURN();
1915 5a5012ec ths
}
1916 5a5012ec ths
FLOAT_OP(movz, s)
1917 5a5012ec ths
{
1918 5a5012ec ths
    if (!T0)
1919 5a5012ec ths
        WT2 = WT0;
1920 5a5012ec ths
    DEBUG_FPU_STATE();
1921 5a5012ec ths
    RETURN();
1922 5a5012ec ths
}
1923 5a5012ec ths
FLOAT_OP(movz, ps)
1924 5a5012ec ths
{
1925 5a5012ec ths
    if (!T0) {
1926 5a5012ec ths
        WT2 = WT0;
1927 5a5012ec ths
        WTH2 = WTH0;
1928 5a5012ec ths
    }
1929 5a5012ec ths
    DEBUG_FPU_STATE();
1930 5a5012ec ths
    RETURN();
1931 5a5012ec ths
}
1932 5a5012ec ths
FLOAT_OP(movn, d)
1933 5a5012ec ths
{
1934 5a5012ec ths
    if (T0)
1935 5a5012ec ths
        DT2 = DT0;
1936 5a5012ec ths
    DEBUG_FPU_STATE();
1937 5a5012ec ths
    RETURN();
1938 5a5012ec ths
}
1939 5a5012ec ths
FLOAT_OP(movn, s)
1940 5a5012ec ths
{
1941 5a5012ec ths
    if (T0)
1942 5a5012ec ths
        WT2 = WT0;
1943 5a5012ec ths
    DEBUG_FPU_STATE();
1944 5a5012ec ths
    RETURN();
1945 5a5012ec ths
}
1946 5a5012ec ths
FLOAT_OP(movn, ps)
1947 5a5012ec ths
{
1948 5a5012ec ths
    if (T0) {
1949 5a5012ec ths
        WT2 = WT0;
1950 5a5012ec ths
        WTH2 = WTH0;
1951 5a5012ec ths
    }
1952 5a5012ec ths
    DEBUG_FPU_STATE();
1953 5a5012ec ths
    RETURN();
1954 5a5012ec ths
}
1955 5a5012ec ths
1956 57fa1fb3 ths
/* operations calling helpers, for s, d and ps */
1957 57fa1fb3 ths
#define FLOAT_HOP(name) \
1958 6ea83fed bellard
FLOAT_OP(name, d)         \
1959 6ea83fed bellard
{                         \
1960 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
1961 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1962 fbcc6828 ths
    RETURN();             \
1963 6ea83fed bellard
}                         \
1964 6ea83fed bellard
FLOAT_OP(name, s)         \
1965 6ea83fed bellard
{                         \
1966 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
1967 5a5012ec ths
    DEBUG_FPU_STATE();    \
1968 fbcc6828 ths
    RETURN();             \
1969 5a5012ec ths
}                         \
1970 5a5012ec ths
FLOAT_OP(name, ps)        \
1971 5a5012ec ths
{                         \
1972 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
1973 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1974 fbcc6828 ths
    RETURN();             \
1975 6ea83fed bellard
}
1976 57fa1fb3 ths
FLOAT_HOP(add)
1977 57fa1fb3 ths
FLOAT_HOP(sub)
1978 57fa1fb3 ths
FLOAT_HOP(mul)
1979 57fa1fb3 ths
FLOAT_HOP(div)
1980 57fa1fb3 ths
FLOAT_HOP(recip2)
1981 57fa1fb3 ths
FLOAT_HOP(rsqrt2)
1982 57fa1fb3 ths
FLOAT_HOP(rsqrt1)
1983 57fa1fb3 ths
FLOAT_HOP(recip1)
1984 57fa1fb3 ths
#undef FLOAT_HOP
1985 57fa1fb3 ths
1986 57fa1fb3 ths
/* operations calling helpers, for s and d */
1987 57fa1fb3 ths
#define FLOAT_HOP(name)   \
1988 57fa1fb3 ths
FLOAT_OP(name, d)         \
1989 57fa1fb3 ths
{                         \
1990 57fa1fb3 ths
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
1991 57fa1fb3 ths
    DEBUG_FPU_STATE();    \
1992 57fa1fb3 ths
    RETURN();             \
1993 57fa1fb3 ths
}                         \
1994 57fa1fb3 ths
FLOAT_OP(name, s)         \
1995 57fa1fb3 ths
{                         \
1996 57fa1fb3 ths
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
1997 57fa1fb3 ths
    DEBUG_FPU_STATE();    \
1998 57fa1fb3 ths
    RETURN();             \
1999 57fa1fb3 ths
}
2000 57fa1fb3 ths
FLOAT_HOP(rsqrt)
2001 57fa1fb3 ths
FLOAT_HOP(recip)
2002 57fa1fb3 ths
#undef FLOAT_HOP
2003 6ea83fed bellard
2004 57fa1fb3 ths
/* operations calling helpers, for ps */
2005 57fa1fb3 ths
#define FLOAT_HOP(name)   \
2006 57fa1fb3 ths
FLOAT_OP(name, ps)        \
2007 57fa1fb3 ths
{                         \
2008 57fa1fb3 ths
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
2009 57fa1fb3 ths
    DEBUG_FPU_STATE();    \
2010 57fa1fb3 ths
    RETURN();             \
2011 fbcc6828 ths
}
2012 57fa1fb3 ths
FLOAT_HOP(addr)
2013 57fa1fb3 ths
FLOAT_HOP(mulr)
2014 57fa1fb3 ths
#undef FLOAT_HOP
2015 fbcc6828 ths
2016 5a5012ec ths
/* ternary operations */
2017 5a5012ec ths
#define FLOAT_TERNOP(name1, name2) \
2018 5a5012ec ths
FLOAT_OP(name1 ## name2, d)        \
2019 5a5012ec ths
{                                  \
2020 5a5012ec ths
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status);    \
2021 5a5012ec ths
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status);    \
2022 5a5012ec ths
    DEBUG_FPU_STATE();             \
2023 fbcc6828 ths
    RETURN();                      \
2024 5a5012ec ths
}                                  \
2025 5a5012ec ths
FLOAT_OP(name1 ## name2, s)        \
2026 5a5012ec ths
{                                  \
2027 5a5012ec ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
2028 5a5012ec ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
2029 5a5012ec ths
    DEBUG_FPU_STATE();             \
2030 fbcc6828 ths
    RETURN();                      \
2031 5a5012ec ths
}                                  \
2032 5a5012ec ths
FLOAT_OP(name1 ## name2, ps)       \
2033 5a5012ec ths
{                                  \
2034 5a5012ec ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
2035 5a5012ec ths
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
2036 5a5012ec ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
2037 5a5012ec ths
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
2038 5a5012ec ths
    DEBUG_FPU_STATE();             \
2039 fbcc6828 ths
    RETURN();                      \
2040 5a5012ec ths
}
2041 5a5012ec ths
FLOAT_TERNOP(mul, add)
2042 5a5012ec ths
FLOAT_TERNOP(mul, sub)
2043 5a5012ec ths
#undef FLOAT_TERNOP
2044 5a5012ec ths
2045 fbcc6828 ths
/* negated ternary operations */
2046 fbcc6828 ths
#define FLOAT_NTERNOP(name1, name2) \
2047 fbcc6828 ths
FLOAT_OP(n ## name1 ## name2, d)    \
2048 fbcc6828 ths
{                                   \
2049 fbcc6828 ths
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status);    \
2050 fbcc6828 ths
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status);    \
2051 fbcc6828 ths
    FDT2 ^= 1ULL << 63;             \
2052 fbcc6828 ths
    DEBUG_FPU_STATE();              \
2053 fbcc6828 ths
    RETURN();                       \
2054 fbcc6828 ths
}                                   \
2055 fbcc6828 ths
FLOAT_OP(n ## name1 ## name2, s)    \
2056 fbcc6828 ths
{                                   \
2057 fbcc6828 ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
2058 fbcc6828 ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
2059 fbcc6828 ths
    FST2 ^= 1 << 31;                \
2060 fbcc6828 ths
    DEBUG_FPU_STATE();              \
2061 fbcc6828 ths
    RETURN();                       \
2062 fbcc6828 ths
}                                   \
2063 fbcc6828 ths
FLOAT_OP(n ## name1 ## name2, ps)   \
2064 fbcc6828 ths
{                                   \
2065 fbcc6828 ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status);    \
2066 fbcc6828 ths
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
2067 fbcc6828 ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status);    \
2068 fbcc6828 ths
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
2069 fbcc6828 ths
    FST2 ^= 1 << 31;                \
2070 fbcc6828 ths
    FSTH2 ^= 1 << 31;               \
2071 fbcc6828 ths
    DEBUG_FPU_STATE();              \
2072 fbcc6828 ths
    RETURN();                       \
2073 fbcc6828 ths
}
2074 fbcc6828 ths
FLOAT_NTERNOP(mul, add)
2075 fbcc6828 ths
FLOAT_NTERNOP(mul, sub)
2076 fbcc6828 ths
#undef FLOAT_NTERNOP
2077 fbcc6828 ths
2078 6ea83fed bellard
/* unary operations, modifying fp status  */
2079 6ea83fed bellard
#define FLOAT_UNOP(name)  \
2080 6ea83fed bellard
FLOAT_OP(name, d)         \
2081 6ea83fed bellard
{                         \
2082 6ea83fed bellard
    FDT2 = float64_ ## name(FDT0, &env->fp_status);   \
2083 6ea83fed bellard
    DEBUG_FPU_STATE();    \
2084 fbcc6828 ths
    RETURN();                      \
2085 6ea83fed bellard
}                         \
2086 6ea83fed bellard
FLOAT_OP(name, s)         \
2087 6ea83fed bellard
{                         \
2088 6ea83fed bellard
    FST2 = float32_ ## name(FST0, &env->fp_status);   \
2089 6ea83fed bellard
    DEBUG_FPU_STATE();    \
2090 57fa1fb3 ths
    RETURN();             \
2091 6ea83fed bellard
}
2092 6ea83fed bellard
FLOAT_UNOP(sqrt)
2093 6ea83fed bellard
#undef FLOAT_UNOP
2094 6ea83fed bellard
2095 6ea83fed bellard
/* unary operations, not modifying fp status  */
2096 6ea83fed bellard
#define FLOAT_UNOP(name)  \
2097 6ea83fed bellard
FLOAT_OP(name, d)         \
2098 6ea83fed bellard
{                         \
2099 6ea83fed bellard
    FDT2 = float64_ ## name(FDT0);   \
2100 6ea83fed bellard
    DEBUG_FPU_STATE();    \
2101 fbcc6828 ths
    RETURN();             \
2102 6ea83fed bellard
}                         \
2103 6ea83fed bellard
FLOAT_OP(name, s)         \
2104 6ea83fed bellard
{                         \
2105 6ea83fed bellard
    FST2 = float32_ ## name(FST0);   \
2106 6ea83fed bellard
    DEBUG_FPU_STATE();    \
2107 fbcc6828 ths
    RETURN();             \
2108 5a5012ec ths
}                         \
2109 5a5012ec ths
FLOAT_OP(name, ps)        \
2110 5a5012ec ths
{                         \
2111 5a5012ec ths
    FST2 = float32_ ## name(FST0);   \
2112 5a5012ec ths
    FSTH2 = float32_ ## name(FSTH0); \
2113 5a5012ec ths
    DEBUG_FPU_STATE();    \
2114 fbcc6828 ths
    RETURN();             \
2115 6ea83fed bellard
}
2116 6ea83fed bellard
FLOAT_UNOP(abs)
2117 6ea83fed bellard
FLOAT_UNOP(chs)
2118 6ea83fed bellard
#undef FLOAT_UNOP
2119 6ea83fed bellard
2120 6ea83fed bellard
FLOAT_OP(mov, d)
2121 6ea83fed bellard
{
2122 6ea83fed bellard
    FDT2 = FDT0;
2123 6ea83fed bellard
    DEBUG_FPU_STATE();
2124 6ea83fed bellard
    RETURN();
2125 6ea83fed bellard
}
2126 6ea83fed bellard
FLOAT_OP(mov, s)
2127 6ea83fed bellard
{
2128 6ea83fed bellard
    FST2 = FST0;
2129 6ea83fed bellard
    DEBUG_FPU_STATE();
2130 6ea83fed bellard
    RETURN();
2131 6ea83fed bellard
}
2132 5a5012ec ths
FLOAT_OP(mov, ps)
2133 5a5012ec ths
{
2134 5a5012ec ths
    FST2 = FST0;
2135 5a5012ec ths
    FSTH2 = FSTH0;
2136 5a5012ec ths
    DEBUG_FPU_STATE();
2137 5a5012ec ths
    RETURN();
2138 5a5012ec ths
}
2139 5a5012ec ths
FLOAT_OP(alnv, ps)
2140 5a5012ec ths
{
2141 5a5012ec ths
    switch (T0 & 0x7) {
2142 5a5012ec ths
    case 0:
2143 5a5012ec ths
        FST2 = FST0;
2144 5a5012ec ths
        FSTH2 = FSTH0;
2145 5a5012ec ths
        break;
2146 5a5012ec ths
    case 4:
2147 5a5012ec ths
#ifdef TARGET_WORDS_BIGENDIAN
2148 5a5012ec ths
        FSTH2 = FST0;
2149 5a5012ec ths
        FST2 = FSTH1;
2150 5a5012ec ths
#else
2151 5a5012ec ths
        FSTH2 = FST1;
2152 5a5012ec ths
        FST2 = FSTH0;
2153 5a5012ec ths
#endif
2154 5a5012ec ths
        break;
2155 5a5012ec ths
    default: /* unpredictable */
2156 5a5012ec ths
        break;
2157 5a5012ec ths
    }
2158 5a5012ec ths
    DEBUG_FPU_STATE();
2159 5a5012ec ths
    RETURN();
2160 5a5012ec ths
}
2161 6ea83fed bellard
2162 6ea83fed bellard
#ifdef CONFIG_SOFTFLOAT
2163 6ea83fed bellard
#define clear_invalid() do {                                \
2164 6ea83fed bellard
    int flags = get_float_exception_flags(&env->fp_status); \
2165 6ea83fed bellard
    flags &= ~float_flag_invalid;                           \
2166 6ea83fed bellard
    set_float_exception_flags(flags, &env->fp_status);      \
2167 6ea83fed bellard
} while(0)
2168 6ea83fed bellard
#else
2169 6ea83fed bellard
#define clear_invalid() do { } while(0)
2170 6ea83fed bellard
#endif
2171 6ea83fed bellard
2172 6ea83fed bellard
extern void dump_fpu_s(CPUState *env);
2173 6ea83fed bellard
2174 fd4a04eb ths
#define CMP_OP(fmt, op)                                \
2175 fd4a04eb ths
void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
2176 fd4a04eb ths
{                                                      \
2177 fd4a04eb ths
    CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2178 fd4a04eb ths
    DEBUG_FPU_STATE();                                 \
2179 fd4a04eb ths
    RETURN();                                          \
2180 fd4a04eb ths
}                                                      \
2181 fd4a04eb ths
void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
2182 fd4a04eb ths
{                                                      \
2183 fd4a04eb ths
    CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2184 fd4a04eb ths
    DEBUG_FPU_STATE();                                 \
2185 fd4a04eb ths
    RETURN();                                          \
2186 fd4a04eb ths
}
2187 fd4a04eb ths
#define CMP_OPS(op)   \
2188 fd4a04eb ths
CMP_OP(d, op)         \
2189 fd4a04eb ths
CMP_OP(s, op)         \
2190 fd4a04eb ths
CMP_OP(ps, op)
2191 fd4a04eb ths
2192 fd4a04eb ths
CMP_OPS(f)
2193 fd4a04eb ths
CMP_OPS(un)
2194 fd4a04eb ths
CMP_OPS(eq)
2195 fd4a04eb ths
CMP_OPS(ueq)
2196 fd4a04eb ths
CMP_OPS(olt)
2197 fd4a04eb ths
CMP_OPS(ult)
2198 fd4a04eb ths
CMP_OPS(ole)
2199 fd4a04eb ths
CMP_OPS(ule)
2200 fd4a04eb ths
CMP_OPS(sf)
2201 fd4a04eb ths
CMP_OPS(ngle)
2202 fd4a04eb ths
CMP_OPS(seq)
2203 fd4a04eb ths
CMP_OPS(ngl)
2204 fd4a04eb ths
CMP_OPS(lt)
2205 fd4a04eb ths
CMP_OPS(nge)
2206 fd4a04eb ths
CMP_OPS(le)
2207 fd4a04eb ths
CMP_OPS(ngt)
2208 fd4a04eb ths
#undef CMP_OPS
2209 fd4a04eb ths
#undef CMP_OP
2210 6ea83fed bellard
2211 6ea83fed bellard
void op_bc1f (void)
2212 6ea83fed bellard
{
2213 fd4a04eb ths
    T0 = !!(~GET_FP_COND(env) & (0x1 << PARAM1));
2214 5a5012ec ths
    DEBUG_FPU_STATE();
2215 5a5012ec ths
    RETURN();
2216 5a5012ec ths
}
2217 fd4a04eb ths
void op_bc1any2f (void)
2218 5a5012ec ths
{
2219 fd4a04eb ths
    T0 = !!(~GET_FP_COND(env) & (0x3 << PARAM1));
2220 5a5012ec ths
    DEBUG_FPU_STATE();
2221 5a5012ec ths
    RETURN();
2222 5a5012ec ths
}
2223 fd4a04eb ths
void op_bc1any4f (void)
2224 5a5012ec ths
{
2225 fd4a04eb ths
    T0 = !!(~GET_FP_COND(env) & (0xf << PARAM1));
2226 6ea83fed bellard
    DEBUG_FPU_STATE();
2227 6ea83fed bellard
    RETURN();
2228 6ea83fed bellard
}
2229 6ea83fed bellard
2230 6ea83fed bellard
void op_bc1t (void)
2231 6ea83fed bellard
{
2232 fd4a04eb ths
    T0 = !!(GET_FP_COND(env) & (0x1 << PARAM1));
2233 5a5012ec ths
    DEBUG_FPU_STATE();
2234 5a5012ec ths
    RETURN();
2235 5a5012ec ths
}
2236 fd4a04eb ths
void op_bc1any2t (void)
2237 5a5012ec ths
{
2238 fd4a04eb ths
    T0 = !!(GET_FP_COND(env) & (0x3 << PARAM1));
2239 5a5012ec ths
    DEBUG_FPU_STATE();
2240 5a5012ec ths
    RETURN();
2241 5a5012ec ths
}
2242 fd4a04eb ths
void op_bc1any4t (void)
2243 5a5012ec ths
{
2244 fd4a04eb ths
    T0 = !!(GET_FP_COND(env) & (0xf << PARAM1));
2245 6ea83fed bellard
    DEBUG_FPU_STATE();
2246 6ea83fed bellard
    RETURN();
2247 6ea83fed bellard
}
2248 6ea83fed bellard
2249 6af0bf9c bellard
void op_tlbwi (void)
2250 6af0bf9c bellard
{
2251 29929e34 ths
    CALL_FROM_TB0(env->do_tlbwi);
2252 6af0bf9c bellard
    RETURN();
2253 6af0bf9c bellard
}
2254 6af0bf9c bellard
2255 6af0bf9c bellard
void op_tlbwr (void)
2256 6af0bf9c bellard
{
2257 29929e34 ths
    CALL_FROM_TB0(env->do_tlbwr);
2258 6af0bf9c bellard
    RETURN();
2259 6af0bf9c bellard
}
2260 6af0bf9c bellard
2261 6af0bf9c bellard
void op_tlbp (void)
2262 6af0bf9c bellard
{
2263 29929e34 ths
    CALL_FROM_TB0(env->do_tlbp);
2264 6af0bf9c bellard
    RETURN();
2265 6af0bf9c bellard
}
2266 6af0bf9c bellard
2267 6af0bf9c bellard
void op_tlbr (void)
2268 6af0bf9c bellard
{
2269 29929e34 ths
    CALL_FROM_TB0(env->do_tlbr);
2270 6af0bf9c bellard
    RETURN();
2271 6af0bf9c bellard
}
2272 6af0bf9c bellard
2273 6af0bf9c bellard
/* Specials */
2274 6f5b89a0 ths
#if defined (CONFIG_USER_ONLY)
2275 6f5b89a0 ths
void op_tls_value (void)
2276 6f5b89a0 ths
{
2277 5a5012ec ths
    T0 = env->tls_value;
2278 6f5b89a0 ths
}
2279 6f5b89a0 ths
#endif
2280 6f5b89a0 ths
2281 6af0bf9c bellard
void op_pmon (void)
2282 6af0bf9c bellard
{
2283 6af0bf9c bellard
    CALL_FROM_TB1(do_pmon, PARAM1);
2284 7a387fff ths
    RETURN();
2285 7a387fff ths
}
2286 7a387fff ths
2287 7a387fff ths
void op_di (void)
2288 7a387fff ths
{
2289 7a387fff ths
    T0 = env->CP0_Status;
2290 4de9b249 ths
    env->CP0_Status = T0 & ~(1 << CP0St_IE);
2291 4de9b249 ths
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2292 7a387fff ths
    RETURN();
2293 7a387fff ths
}
2294 7a387fff ths
2295 7a387fff ths
void op_ei (void)
2296 7a387fff ths
{
2297 7a387fff ths
    T0 = env->CP0_Status;
2298 4de9b249 ths
    env->CP0_Status = T0 | (1 << CP0St_IE);
2299 4de9b249 ths
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2300 7a387fff ths
    RETURN();
2301 6af0bf9c bellard
}
2302 6af0bf9c bellard
2303 6af0bf9c bellard
void op_trap (void)
2304 6af0bf9c bellard
{
2305 6af0bf9c bellard
    if (T0) {
2306 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2307 6af0bf9c bellard
    }
2308 6af0bf9c bellard
    RETURN();
2309 6af0bf9c bellard
}
2310 6af0bf9c bellard
2311 4ad40f36 bellard
void op_debug (void)
2312 4ad40f36 bellard
{
2313 7a387fff ths
    CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2314 7a387fff ths
    RETURN();
2315 4ad40f36 bellard
}
2316 4ad40f36 bellard
2317 6af0bf9c bellard
void op_set_lladdr (void)
2318 6af0bf9c bellard
{
2319 6af0bf9c bellard
    env->CP0_LLAddr = T2;
2320 7a387fff ths
    RETURN();
2321 6af0bf9c bellard
}
2322 6af0bf9c bellard
2323 f41c52f1 ths
void debug_pre_eret (void);
2324 f41c52f1 ths
void debug_post_eret (void);
2325 6af0bf9c bellard
void op_eret (void)
2326 6af0bf9c bellard
{
2327 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2328 f41c52f1 ths
        CALL_FROM_TB0(debug_pre_eret);
2329 24c7b0e3 ths
    if (env->CP0_Status & (1 << CP0St_ERL)) {
2330 6af0bf9c bellard
        env->PC = env->CP0_ErrorEPC;
2331 24c7b0e3 ths
        env->CP0_Status &= ~(1 << CP0St_ERL);
2332 51e11d9e bellard
    } else {
2333 6af0bf9c bellard
        env->PC = env->CP0_EPC;
2334 24c7b0e3 ths
        env->CP0_Status &= ~(1 << CP0St_EXL);
2335 51e11d9e bellard
    }
2336 24c7b0e3 ths
    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
2337 24c7b0e3 ths
        !(env->CP0_Status & (1 << CP0St_ERL)) &&
2338 24c7b0e3 ths
        !(env->hflags & MIPS_HFLAG_DM) &&
2339 24c7b0e3 ths
        (env->CP0_Status & (1 << CP0St_UM)))
2340 24c7b0e3 ths
        env->hflags |= MIPS_HFLAG_UM;
2341 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2342 f41c52f1 ths
        CALL_FROM_TB0(debug_post_eret);
2343 6af0bf9c bellard
    env->CP0_LLAddr = 1;
2344 7a387fff ths
    RETURN();
2345 6af0bf9c bellard
}
2346 6af0bf9c bellard
2347 6af0bf9c bellard
void op_deret (void)
2348 6af0bf9c bellard
{
2349 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2350 f41c52f1 ths
        CALL_FROM_TB0(debug_pre_eret);
2351 6af0bf9c bellard
    env->PC = env->CP0_DEPC;
2352 24c7b0e3 ths
    env->hflags |= MIPS_HFLAG_DM;
2353 24c7b0e3 ths
    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
2354 24c7b0e3 ths
        !(env->CP0_Status & (1 << CP0St_ERL)) &&
2355 24c7b0e3 ths
        !(env->hflags & MIPS_HFLAG_DM) &&
2356 24c7b0e3 ths
        (env->CP0_Status & (1 << CP0St_UM)))
2357 24c7b0e3 ths
        env->hflags |= MIPS_HFLAG_UM;
2358 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2359 f41c52f1 ths
        CALL_FROM_TB0(debug_post_eret);
2360 24c7b0e3 ths
    env->CP0_LLAddr = 1;
2361 7a387fff ths
    RETURN();
2362 7a387fff ths
}
2363 7a387fff ths
2364 7a387fff ths
void op_rdhwr_cpunum(void)
2365 7a387fff ths
{
2366 1579a72e ths
    if (!(env->hflags & MIPS_HFLAG_UM) ||
2367 97428a4d ths
        (env->CP0_HWREna & (1 << 0)) ||
2368 1579a72e ths
        (env->CP0_Status & (1 << CP0St_CU0)))
2369 1579a72e ths
        T0 = env->CP0_EBase & 0x3ff;
2370 7a387fff ths
    else
2371 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2372 7a387fff ths
    RETURN();
2373 7a387fff ths
}
2374 7a387fff ths
2375 7a387fff ths
void op_rdhwr_synci_step(void)
2376 7a387fff ths
{
2377 1579a72e ths
    if (!(env->hflags & MIPS_HFLAG_UM) ||
2378 97428a4d ths
        (env->CP0_HWREna & (1 << 1)) ||
2379 1579a72e ths
        (env->CP0_Status & (1 << CP0St_CU0)))
2380 1579a72e ths
        T0 = env->SYNCI_Step;
2381 7a387fff ths
    else
2382 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2383 7a387fff ths
    RETURN();
2384 7a387fff ths
}
2385 7a387fff ths
2386 7a387fff ths
void op_rdhwr_cc(void)
2387 7a387fff ths
{
2388 1579a72e ths
    if (!(env->hflags & MIPS_HFLAG_UM) ||
2389 97428a4d ths
        (env->CP0_HWREna & (1 << 2)) ||
2390 1579a72e ths
        (env->CP0_Status & (1 << CP0St_CU0)))
2391 1579a72e ths
        T0 = env->CP0_Count;
2392 7a387fff ths
    else
2393 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2394 7a387fff ths
    RETURN();
2395 7a387fff ths
}
2396 7a387fff ths
2397 7a387fff ths
void op_rdhwr_ccres(void)
2398 7a387fff ths
{
2399 1579a72e ths
    if (!(env->hflags & MIPS_HFLAG_UM) ||
2400 97428a4d ths
        (env->CP0_HWREna & (1 << 3)) ||
2401 1579a72e ths
        (env->CP0_Status & (1 << CP0St_CU0)))
2402 1579a72e ths
        T0 = env->CCRes;
2403 7a387fff ths
    else
2404 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2405 1579a72e ths
    RETURN();
2406 1579a72e ths
}
2407 1579a72e ths
2408 6af0bf9c bellard
void op_save_state (void)
2409 6af0bf9c bellard
{
2410 6af0bf9c bellard
    env->hflags = PARAM1;
2411 6af0bf9c bellard
    RETURN();
2412 6af0bf9c bellard
}
2413 6af0bf9c bellard
2414 6af0bf9c bellard
void op_save_pc (void)
2415 6af0bf9c bellard
{
2416 6af0bf9c bellard
    env->PC = PARAM1;
2417 6af0bf9c bellard
    RETURN();
2418 6af0bf9c bellard
}
2419 6af0bf9c bellard
2420 9b9e4393 ths
#ifdef TARGET_MIPS64
2421 9b9e4393 ths
void op_save_pc64 (void)
2422 9b9e4393 ths
{
2423 9b9e4393 ths
    env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
2424 9b9e4393 ths
    RETURN();
2425 9b9e4393 ths
}
2426 9b9e4393 ths
#endif
2427 9b9e4393 ths
2428 16c00cb2 ths
void op_interrupt_restart (void)
2429 16c00cb2 ths
{
2430 16c00cb2 ths
    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
2431 16c00cb2 ths
        !(env->CP0_Status & (1 << CP0St_ERL)) &&
2432 16c00cb2 ths
        !(env->hflags & MIPS_HFLAG_DM) &&
2433 16c00cb2 ths
        (env->CP0_Status & (1 << CP0St_IE)) &&
2434 16c00cb2 ths
        (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
2435 16c00cb2 ths
        env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
2436 16c00cb2 ths
        CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
2437 16c00cb2 ths
    }
2438 16c00cb2 ths
    RETURN();
2439 16c00cb2 ths
}
2440 16c00cb2 ths
2441 6af0bf9c bellard
void op_raise_exception (void)
2442 6af0bf9c bellard
{
2443 6af0bf9c bellard
    CALL_FROM_TB1(do_raise_exception, PARAM1);
2444 6af0bf9c bellard
    RETURN();
2445 6af0bf9c bellard
}
2446 6af0bf9c bellard
2447 6af0bf9c bellard
void op_raise_exception_err (void)
2448 6af0bf9c bellard
{
2449 6af0bf9c bellard
    CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
2450 6af0bf9c bellard
    RETURN();
2451 6af0bf9c bellard
}
2452 6af0bf9c bellard
2453 6af0bf9c bellard
void op_exit_tb (void)
2454 6af0bf9c bellard
{
2455 6af0bf9c bellard
    EXIT_TB();
2456 7a387fff ths
    RETURN();
2457 6af0bf9c bellard
}
2458 6af0bf9c bellard
2459 4ad40f36 bellard
void op_wait (void)
2460 4ad40f36 bellard
{
2461 4ad40f36 bellard
    env->halted = 1;
2462 4ad40f36 bellard
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2463 7a387fff ths
    RETURN();
2464 7a387fff ths
}
2465 7a387fff ths
2466 7a387fff ths
/* Bitfield operations. */
2467 7a387fff ths
void op_ext(void)
2468 7a387fff ths
{
2469 7a387fff ths
    unsigned int pos = PARAM1;
2470 7a387fff ths
    unsigned int size = PARAM2;
2471 7a387fff ths
2472 f757d6ff ths
    T0 = ((uint32_t)T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0);
2473 7a387fff ths
    RETURN();
2474 7a387fff ths
}
2475 7a387fff ths
2476 7a387fff ths
void op_ins(void)
2477 7a387fff ths
{
2478 7a387fff ths
    unsigned int pos = PARAM1;
2479 7a387fff ths
    unsigned int size = PARAM2;
2480 f757d6ff ths
    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2481 7a387fff ths
2482 171b31e7 ths
    T0 = (T0 & ~mask) | (((uint32_t)T1 << pos) & mask);
2483 7a387fff ths
    RETURN();
2484 7a387fff ths
}
2485 7a387fff ths
2486 7a387fff ths
void op_wsbh(void)
2487 7a387fff ths
{
2488 7a387fff ths
    T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF);
2489 7a387fff ths
    RETURN();
2490 7a387fff ths
}
2491 7a387fff ths
2492 60aa19ab ths
#ifdef TARGET_MIPS64
2493 c570fd16 ths
void op_dext(void)
2494 c570fd16 ths
{
2495 c570fd16 ths
    unsigned int pos = PARAM1;
2496 c570fd16 ths
    unsigned int size = PARAM2;
2497 c570fd16 ths
2498 f757d6ff ths
    T0 = (T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0);
2499 c570fd16 ths
    RETURN();
2500 c570fd16 ths
}
2501 c570fd16 ths
2502 c570fd16 ths
void op_dins(void)
2503 c570fd16 ths
{
2504 c570fd16 ths
    unsigned int pos = PARAM1;
2505 c570fd16 ths
    unsigned int size = PARAM2;
2506 f757d6ff ths
    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2507 c570fd16 ths
2508 171b31e7 ths
    T0 = (T0 & ~mask) | ((T1 << pos) & mask);
2509 c570fd16 ths
    RETURN();
2510 c570fd16 ths
}
2511 c570fd16 ths
2512 7a387fff ths
void op_dsbh(void)
2513 7a387fff ths
{
2514 7a387fff ths
    T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2515 7a387fff ths
    RETURN();
2516 7a387fff ths
}
2517 7a387fff ths
2518 7a387fff ths
void op_dshd(void)
2519 7a387fff ths
{
2520 7a387fff ths
    T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2521 7a387fff ths
    RETURN();
2522 7a387fff ths
}
2523 c570fd16 ths
#endif
2524 7a387fff ths
2525 7a387fff ths
void op_seb(void)
2526 7a387fff ths
{
2527 7a387fff ths
    T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
2528 7a387fff ths
    RETURN();
2529 7a387fff ths
}
2530 7a387fff ths
2531 7a387fff ths
void op_seh(void)
2532 7a387fff ths
{
2533 7a387fff ths
    T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
2534 7a387fff ths
    RETURN();
2535 4ad40f36 bellard
}