Statistics
| Branch: | Revision:

root / target-mips / op.c @ e6bb7d7e

History | View | Annotate | Download (45.1 kB)

1 6af0bf9c bellard
/*
2 6af0bf9c bellard
 *  MIPS emulation micro-operations for qemu.
3 5fafdf24 ths
 *
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 05f778c8 ths
#include "host-utils.h"
26 6af0bf9c bellard
27 1b351e52 bellard
#ifndef CALL_FROM_TB0
28 5a5012ec ths
#define CALL_FROM_TB0(func) func()
29 1b351e52 bellard
#endif
30 1b351e52 bellard
#ifndef CALL_FROM_TB1
31 5a5012ec ths
#define CALL_FROM_TB1(func, arg0) func(arg0)
32 1b351e52 bellard
#endif
33 1b351e52 bellard
#ifndef CALL_FROM_TB1_CONST16
34 5a5012ec ths
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
35 1b351e52 bellard
#endif
36 1b351e52 bellard
#ifndef CALL_FROM_TB2
37 5a5012ec ths
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
38 1b351e52 bellard
#endif
39 1b351e52 bellard
#ifndef CALL_FROM_TB2_CONST16
40 1b351e52 bellard
#define CALL_FROM_TB2_CONST16(func, arg0, arg1)     \
41 5a5012ec ths
        CALL_FROM_TB2(func, arg0, arg1)
42 1b351e52 bellard
#endif
43 1b351e52 bellard
#ifndef CALL_FROM_TB3
44 5a5012ec ths
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
45 1b351e52 bellard
#endif
46 1b351e52 bellard
#ifndef CALL_FROM_TB4
47 1b351e52 bellard
#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
48 5a5012ec ths
        func(arg0, arg1, arg2, arg3)
49 1b351e52 bellard
#endif
50 1b351e52 bellard
51 5a5012ec ths
#define FREG 0
52 6ea83fed bellard
#include "fop_template.c"
53 5a5012ec ths
#undef FREG
54 5a5012ec ths
#define FREG 1
55 6ea83fed bellard
#include "fop_template.c"
56 5a5012ec ths
#undef FREG
57 5a5012ec ths
#define FREG 2
58 6ea83fed bellard
#include "fop_template.c"
59 5a5012ec ths
#undef FREG
60 5a5012ec ths
#define FREG 3
61 6ea83fed bellard
#include "fop_template.c"
62 5a5012ec ths
#undef FREG
63 5a5012ec ths
#define FREG 4
64 6ea83fed bellard
#include "fop_template.c"
65 5a5012ec ths
#undef FREG
66 5a5012ec ths
#define FREG 5
67 6ea83fed bellard
#include "fop_template.c"
68 5a5012ec ths
#undef FREG
69 5a5012ec ths
#define FREG 6
70 6ea83fed bellard
#include "fop_template.c"
71 5a5012ec ths
#undef FREG
72 5a5012ec ths
#define FREG 7
73 6ea83fed bellard
#include "fop_template.c"
74 5a5012ec ths
#undef FREG
75 5a5012ec ths
#define FREG 8
76 6ea83fed bellard
#include "fop_template.c"
77 5a5012ec ths
#undef FREG
78 5a5012ec ths
#define FREG 9
79 6ea83fed bellard
#include "fop_template.c"
80 5a5012ec ths
#undef FREG
81 5a5012ec ths
#define FREG 10
82 6ea83fed bellard
#include "fop_template.c"
83 5a5012ec ths
#undef FREG
84 5a5012ec ths
#define FREG 11
85 6ea83fed bellard
#include "fop_template.c"
86 5a5012ec ths
#undef FREG
87 5a5012ec ths
#define FREG 12
88 6ea83fed bellard
#include "fop_template.c"
89 5a5012ec ths
#undef FREG
90 5a5012ec ths
#define FREG 13
91 6ea83fed bellard
#include "fop_template.c"
92 5a5012ec ths
#undef FREG
93 5a5012ec ths
#define FREG 14
94 6ea83fed bellard
#include "fop_template.c"
95 5a5012ec ths
#undef FREG
96 5a5012ec ths
#define FREG 15
97 6ea83fed bellard
#include "fop_template.c"
98 5a5012ec ths
#undef FREG
99 5a5012ec ths
#define FREG 16
100 6ea83fed bellard
#include "fop_template.c"
101 5a5012ec ths
#undef FREG
102 5a5012ec ths
#define FREG 17
103 6ea83fed bellard
#include "fop_template.c"
104 5a5012ec ths
#undef FREG
105 5a5012ec ths
#define FREG 18
106 6ea83fed bellard
#include "fop_template.c"
107 5a5012ec ths
#undef FREG
108 5a5012ec ths
#define FREG 19
109 6ea83fed bellard
#include "fop_template.c"
110 5a5012ec ths
#undef FREG
111 5a5012ec ths
#define FREG 20
112 6ea83fed bellard
#include "fop_template.c"
113 5a5012ec ths
#undef FREG
114 5a5012ec ths
#define FREG 21
115 6ea83fed bellard
#include "fop_template.c"
116 5a5012ec ths
#undef FREG
117 5a5012ec ths
#define FREG 22
118 6ea83fed bellard
#include "fop_template.c"
119 5a5012ec ths
#undef FREG
120 5a5012ec ths
#define FREG 23
121 6ea83fed bellard
#include "fop_template.c"
122 5a5012ec ths
#undef FREG
123 5a5012ec ths
#define FREG 24
124 6ea83fed bellard
#include "fop_template.c"
125 5a5012ec ths
#undef FREG
126 5a5012ec ths
#define FREG 25
127 6ea83fed bellard
#include "fop_template.c"
128 5a5012ec ths
#undef FREG
129 5a5012ec ths
#define FREG 26
130 6ea83fed bellard
#include "fop_template.c"
131 5a5012ec ths
#undef FREG
132 5a5012ec ths
#define FREG 27
133 6ea83fed bellard
#include "fop_template.c"
134 5a5012ec ths
#undef FREG
135 5a5012ec ths
#define FREG 28
136 6ea83fed bellard
#include "fop_template.c"
137 5a5012ec ths
#undef FREG
138 5a5012ec ths
#define FREG 29
139 6ea83fed bellard
#include "fop_template.c"
140 5a5012ec ths
#undef FREG
141 5a5012ec ths
#define FREG 30
142 6ea83fed bellard
#include "fop_template.c"
143 5a5012ec ths
#undef FREG
144 5a5012ec ths
#define FREG 31
145 6ea83fed bellard
#include "fop_template.c"
146 5a5012ec ths
#undef FREG
147 6ea83fed bellard
148 6af0bf9c bellard
/* Load and store */
149 6af0bf9c bellard
#define MEMSUFFIX _raw
150 6af0bf9c bellard
#include "op_mem.c"
151 6af0bf9c bellard
#undef MEMSUFFIX
152 6af0bf9c bellard
#if !defined(CONFIG_USER_ONLY)
153 6af0bf9c bellard
#define MEMSUFFIX _user
154 6af0bf9c bellard
#include "op_mem.c"
155 6af0bf9c bellard
#undef MEMSUFFIX
156 6af0bf9c bellard
157 623a930e ths
#define MEMSUFFIX _super
158 623a930e ths
#include "op_mem.c"
159 623a930e ths
#undef MEMSUFFIX
160 623a930e ths
161 6af0bf9c bellard
#define MEMSUFFIX _kernel
162 6af0bf9c bellard
#include "op_mem.c"
163 6af0bf9c bellard
#undef MEMSUFFIX
164 6af0bf9c bellard
#endif
165 6af0bf9c bellard
166 c570fd16 ths
/* 64 bits arithmetic */
167 c570fd16 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
168 6af0bf9c bellard
void op_mult (void)
169 6af0bf9c bellard
{
170 6af0bf9c bellard
    CALL_FROM_TB0(do_mult);
171 8f6f6026 ths
    FORCE_RET();
172 6af0bf9c bellard
}
173 6af0bf9c bellard
174 6af0bf9c bellard
void op_multu (void)
175 6af0bf9c bellard
{
176 6af0bf9c bellard
    CALL_FROM_TB0(do_multu);
177 8f6f6026 ths
    FORCE_RET();
178 6af0bf9c bellard
}
179 6af0bf9c bellard
180 6af0bf9c bellard
void op_madd (void)
181 6af0bf9c bellard
{
182 6af0bf9c bellard
    CALL_FROM_TB0(do_madd);
183 8f6f6026 ths
    FORCE_RET();
184 6af0bf9c bellard
}
185 6af0bf9c bellard
186 6af0bf9c bellard
void op_maddu (void)
187 6af0bf9c bellard
{
188 6af0bf9c bellard
    CALL_FROM_TB0(do_maddu);
189 8f6f6026 ths
    FORCE_RET();
190 6af0bf9c bellard
}
191 6af0bf9c bellard
192 6af0bf9c bellard
void op_msub (void)
193 6af0bf9c bellard
{
194 6af0bf9c bellard
    CALL_FROM_TB0(do_msub);
195 8f6f6026 ths
    FORCE_RET();
196 6af0bf9c bellard
}
197 6af0bf9c bellard
198 6af0bf9c bellard
void op_msubu (void)
199 6af0bf9c bellard
{
200 6af0bf9c bellard
    CALL_FROM_TB0(do_msubu);
201 8f6f6026 ths
    FORCE_RET();
202 6af0bf9c bellard
}
203 c570fd16 ths
204 e9c71dd1 ths
/* Multiplication variants of the vr54xx. */
205 e9c71dd1 ths
void op_muls (void)
206 e9c71dd1 ths
{
207 e9c71dd1 ths
    CALL_FROM_TB0(do_muls);
208 e9c71dd1 ths
    FORCE_RET();
209 e9c71dd1 ths
}
210 e9c71dd1 ths
211 e9c71dd1 ths
void op_mulsu (void)
212 e9c71dd1 ths
{
213 e9c71dd1 ths
    CALL_FROM_TB0(do_mulsu);
214 e9c71dd1 ths
    FORCE_RET();
215 e9c71dd1 ths
}
216 e9c71dd1 ths
217 e9c71dd1 ths
void op_macc (void)
218 e9c71dd1 ths
{
219 e9c71dd1 ths
    CALL_FROM_TB0(do_macc);
220 e9c71dd1 ths
    FORCE_RET();
221 e9c71dd1 ths
}
222 e9c71dd1 ths
223 e9c71dd1 ths
void op_macchi (void)
224 e9c71dd1 ths
{
225 e9c71dd1 ths
    CALL_FROM_TB0(do_macchi);
226 e9c71dd1 ths
    FORCE_RET();
227 e9c71dd1 ths
}
228 e9c71dd1 ths
229 e9c71dd1 ths
void op_maccu (void)
230 e9c71dd1 ths
{
231 e9c71dd1 ths
    CALL_FROM_TB0(do_maccu);
232 e9c71dd1 ths
    FORCE_RET();
233 e9c71dd1 ths
}
234 e9c71dd1 ths
void op_macchiu (void)
235 e9c71dd1 ths
{
236 e9c71dd1 ths
    CALL_FROM_TB0(do_macchiu);
237 e9c71dd1 ths
    FORCE_RET();
238 e9c71dd1 ths
}
239 e9c71dd1 ths
240 e9c71dd1 ths
void op_msac (void)
241 e9c71dd1 ths
{
242 e9c71dd1 ths
    CALL_FROM_TB0(do_msac);
243 e9c71dd1 ths
    FORCE_RET();
244 e9c71dd1 ths
}
245 e9c71dd1 ths
246 e9c71dd1 ths
void op_msachi (void)
247 e9c71dd1 ths
{
248 e9c71dd1 ths
    CALL_FROM_TB0(do_msachi);
249 e9c71dd1 ths
    FORCE_RET();
250 e9c71dd1 ths
}
251 e9c71dd1 ths
252 e9c71dd1 ths
void op_msacu (void)
253 e9c71dd1 ths
{
254 e9c71dd1 ths
    CALL_FROM_TB0(do_msacu);
255 e9c71dd1 ths
    FORCE_RET();
256 e9c71dd1 ths
}
257 e9c71dd1 ths
258 e9c71dd1 ths
void op_msachiu (void)
259 e9c71dd1 ths
{
260 e9c71dd1 ths
    CALL_FROM_TB0(do_msachiu);
261 e9c71dd1 ths
    FORCE_RET();
262 e9c71dd1 ths
}
263 e9c71dd1 ths
264 e9c71dd1 ths
void op_mulhi (void)
265 e9c71dd1 ths
{
266 e9c71dd1 ths
    CALL_FROM_TB0(do_mulhi);
267 e9c71dd1 ths
    FORCE_RET();
268 e9c71dd1 ths
}
269 e9c71dd1 ths
270 e9c71dd1 ths
void op_mulhiu (void)
271 e9c71dd1 ths
{
272 e9c71dd1 ths
    CALL_FROM_TB0(do_mulhiu);
273 e9c71dd1 ths
    FORCE_RET();
274 e9c71dd1 ths
}
275 e9c71dd1 ths
276 e9c71dd1 ths
void op_mulshi (void)
277 e9c71dd1 ths
{
278 e9c71dd1 ths
    CALL_FROM_TB0(do_mulshi);
279 e9c71dd1 ths
    FORCE_RET();
280 e9c71dd1 ths
}
281 e9c71dd1 ths
282 e9c71dd1 ths
void op_mulshiu (void)
283 e9c71dd1 ths
{
284 e9c71dd1 ths
    CALL_FROM_TB0(do_mulshiu);
285 e9c71dd1 ths
    FORCE_RET();
286 e9c71dd1 ths
}
287 e9c71dd1 ths
288 c570fd16 ths
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
289 c570fd16 ths
290 aa343735 ths
static always_inline uint64_t get_HILO (void)
291 c570fd16 ths
{
292 d0dc7dc3 ths
    return ((uint64_t)env->HI[env->current_tc][0] << 32) |
293 d0dc7dc3 ths
            ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
294 c570fd16 ths
}
295 c570fd16 ths
296 aa343735 ths
static always_inline void set_HILO (uint64_t HILO)
297 c570fd16 ths
{
298 d0dc7dc3 ths
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
299 d0dc7dc3 ths
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
300 c570fd16 ths
}
301 c570fd16 ths
302 e9c71dd1 ths
static always_inline void set_HIT0_LO (uint64_t HILO)
303 e9c71dd1 ths
{
304 d0dc7dc3 ths
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
305 d0dc7dc3 ths
    T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
306 e9c71dd1 ths
}
307 e9c71dd1 ths
308 e9c71dd1 ths
static always_inline void set_HI_LOT0 (uint64_t HILO)
309 e9c71dd1 ths
{
310 d0dc7dc3 ths
    T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
311 d0dc7dc3 ths
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
312 e9c71dd1 ths
}
313 e9c71dd1 ths
314 c570fd16 ths
void op_mult (void)
315 c570fd16 ths
{
316 c570fd16 ths
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
317 8f6f6026 ths
    FORCE_RET();
318 c570fd16 ths
}
319 c570fd16 ths
320 c570fd16 ths
void op_multu (void)
321 c570fd16 ths
{
322 c570fd16 ths
    set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
323 8f6f6026 ths
    FORCE_RET();
324 c570fd16 ths
}
325 c570fd16 ths
326 c570fd16 ths
void op_madd (void)
327 c570fd16 ths
{
328 c570fd16 ths
    int64_t tmp;
329 c570fd16 ths
330 c570fd16 ths
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
331 c570fd16 ths
    set_HILO((int64_t)get_HILO() + tmp);
332 8f6f6026 ths
    FORCE_RET();
333 c570fd16 ths
}
334 c570fd16 ths
335 c570fd16 ths
void op_maddu (void)
336 c570fd16 ths
{
337 c570fd16 ths
    uint64_t tmp;
338 c570fd16 ths
339 c570fd16 ths
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
340 c570fd16 ths
    set_HILO(get_HILO() + tmp);
341 8f6f6026 ths
    FORCE_RET();
342 c570fd16 ths
}
343 c570fd16 ths
344 c570fd16 ths
void op_msub (void)
345 c570fd16 ths
{
346 c570fd16 ths
    int64_t tmp;
347 c570fd16 ths
348 c570fd16 ths
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
349 c570fd16 ths
    set_HILO((int64_t)get_HILO() - tmp);
350 8f6f6026 ths
    FORCE_RET();
351 c570fd16 ths
}
352 c570fd16 ths
353 c570fd16 ths
void op_msubu (void)
354 c570fd16 ths
{
355 c570fd16 ths
    uint64_t tmp;
356 c570fd16 ths
357 c570fd16 ths
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
358 c570fd16 ths
    set_HILO(get_HILO() - tmp);
359 8f6f6026 ths
    FORCE_RET();
360 c570fd16 ths
}
361 e9c71dd1 ths
362 e9c71dd1 ths
/* Multiplication variants of the vr54xx. */
363 e9c71dd1 ths
void op_muls (void)
364 e9c71dd1 ths
{
365 e9c71dd1 ths
    set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
366 e9c71dd1 ths
    FORCE_RET();
367 e9c71dd1 ths
}
368 e9c71dd1 ths
369 e9c71dd1 ths
void op_mulsu (void)
370 e9c71dd1 ths
{
371 e9c71dd1 ths
    set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
372 e9c71dd1 ths
    FORCE_RET();
373 e9c71dd1 ths
}
374 e9c71dd1 ths
375 e9c71dd1 ths
void op_macc (void)
376 e9c71dd1 ths
{
377 e9c71dd1 ths
    set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
378 e9c71dd1 ths
    FORCE_RET();
379 e9c71dd1 ths
}
380 e9c71dd1 ths
381 e9c71dd1 ths
void op_macchi (void)
382 e9c71dd1 ths
{
383 e9c71dd1 ths
    set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
384 e9c71dd1 ths
    FORCE_RET();
385 e9c71dd1 ths
}
386 e9c71dd1 ths
387 e9c71dd1 ths
void op_maccu (void)
388 e9c71dd1 ths
{
389 e9c71dd1 ths
    set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
390 e9c71dd1 ths
    FORCE_RET();
391 e9c71dd1 ths
}
392 e9c71dd1 ths
393 e9c71dd1 ths
void op_macchiu (void)
394 e9c71dd1 ths
{
395 e9c71dd1 ths
    set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
396 e9c71dd1 ths
    FORCE_RET();
397 e9c71dd1 ths
}
398 e9c71dd1 ths
399 e9c71dd1 ths
void op_msac (void)
400 e9c71dd1 ths
{
401 e9c71dd1 ths
    set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
402 e9c71dd1 ths
    FORCE_RET();
403 e9c71dd1 ths
}
404 e9c71dd1 ths
405 e9c71dd1 ths
void op_msachi (void)
406 e9c71dd1 ths
{
407 e9c71dd1 ths
    set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
408 e9c71dd1 ths
    FORCE_RET();
409 e9c71dd1 ths
}
410 e9c71dd1 ths
411 e9c71dd1 ths
void op_msacu (void)
412 e9c71dd1 ths
{
413 e9c71dd1 ths
    set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
414 e9c71dd1 ths
    FORCE_RET();
415 e9c71dd1 ths
}
416 e9c71dd1 ths
417 e9c71dd1 ths
void op_msachiu (void)
418 e9c71dd1 ths
{
419 e9c71dd1 ths
    set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
420 e9c71dd1 ths
    FORCE_RET();
421 e9c71dd1 ths
}
422 e9c71dd1 ths
423 e9c71dd1 ths
void op_mulhi (void)
424 e9c71dd1 ths
{
425 e9c71dd1 ths
    set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
426 e9c71dd1 ths
    FORCE_RET();
427 e9c71dd1 ths
}
428 e9c71dd1 ths
429 e9c71dd1 ths
void op_mulhiu (void)
430 e9c71dd1 ths
{
431 e9c71dd1 ths
    set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
432 e9c71dd1 ths
    FORCE_RET();
433 e9c71dd1 ths
}
434 e9c71dd1 ths
435 e9c71dd1 ths
void op_mulshi (void)
436 e9c71dd1 ths
{
437 e9c71dd1 ths
    set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
438 e9c71dd1 ths
    FORCE_RET();
439 e9c71dd1 ths
}
440 e9c71dd1 ths
441 e9c71dd1 ths
void op_mulshiu (void)
442 e9c71dd1 ths
{
443 e9c71dd1 ths
    set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
444 e9c71dd1 ths
    FORCE_RET();
445 e9c71dd1 ths
}
446 e9c71dd1 ths
447 c570fd16 ths
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
448 c570fd16 ths
449 d26bc211 ths
#if defined(TARGET_MIPS64)
450 c570fd16 ths
void op_dmult (void)
451 c570fd16 ths
{
452 d0dc7dc3 ths
    CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
453 8f6f6026 ths
    FORCE_RET();
454 c570fd16 ths
}
455 c570fd16 ths
456 c570fd16 ths
void op_dmultu (void)
457 c570fd16 ths
{
458 d0dc7dc3 ths
    CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
459 8f6f6026 ths
    FORCE_RET();
460 c570fd16 ths
}
461 6af0bf9c bellard
#endif
462 6af0bf9c bellard
463 6af0bf9c bellard
/* CP0 functions */
464 ead9360e ths
void op_mfc0_mvpcontrol (void)
465 ead9360e ths
{
466 ead9360e ths
    T0 = env->mvp->CP0_MVPControl;
467 8f6f6026 ths
    FORCE_RET();
468 ead9360e ths
}
469 ead9360e ths
470 ead9360e ths
void op_mfc0_mvpconf0 (void)
471 ead9360e ths
{
472 ead9360e ths
    T0 = env->mvp->CP0_MVPConf0;
473 8f6f6026 ths
    FORCE_RET();
474 ead9360e ths
}
475 ead9360e ths
476 ead9360e ths
void op_mfc0_mvpconf1 (void)
477 ead9360e ths
{
478 ead9360e ths
    T0 = env->mvp->CP0_MVPConf1;
479 8f6f6026 ths
    FORCE_RET();
480 ead9360e ths
}
481 ead9360e ths
482 873eb012 ths
void op_mfc0_random (void)
483 873eb012 ths
{
484 873eb012 ths
    CALL_FROM_TB0(do_mfc0_random);
485 8f6f6026 ths
    FORCE_RET();
486 873eb012 ths
}
487 873eb012 ths
488 ead9360e ths
void op_mfc0_tcstatus (void)
489 ead9360e ths
{
490 ead9360e ths
    T0 = env->CP0_TCStatus[env->current_tc];
491 8f6f6026 ths
    FORCE_RET();
492 ead9360e ths
}
493 ead9360e ths
494 ead9360e ths
void op_mftc0_tcstatus(void)
495 ead9360e ths
{
496 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
497 ead9360e ths
498 ead9360e ths
    T0 = env->CP0_TCStatus[other_tc];
499 8f6f6026 ths
    FORCE_RET();
500 ead9360e ths
}
501 ead9360e ths
502 ead9360e ths
void op_mfc0_tcbind (void)
503 ead9360e ths
{
504 ead9360e ths
    T0 = env->CP0_TCBind[env->current_tc];
505 8f6f6026 ths
    FORCE_RET();
506 ead9360e ths
}
507 ead9360e ths
508 ead9360e ths
void op_mftc0_tcbind(void)
509 ead9360e ths
{
510 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
511 ead9360e ths
512 ead9360e ths
    T0 = env->CP0_TCBind[other_tc];
513 8f6f6026 ths
    FORCE_RET();
514 ead9360e ths
}
515 ead9360e ths
516 ead9360e ths
void op_mfc0_tcrestart (void)
517 ead9360e ths
{
518 ead9360e ths
    T0 = env->PC[env->current_tc];
519 8f6f6026 ths
    FORCE_RET();
520 ead9360e ths
}
521 ead9360e ths
522 ead9360e ths
void op_mftc0_tcrestart(void)
523 ead9360e ths
{
524 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
525 ead9360e ths
526 ead9360e ths
    T0 = env->PC[other_tc];
527 8f6f6026 ths
    FORCE_RET();
528 ead9360e ths
}
529 ead9360e ths
530 ead9360e ths
void op_mfc0_tchalt (void)
531 ead9360e ths
{
532 ead9360e ths
    T0 = env->CP0_TCHalt[env->current_tc];
533 8f6f6026 ths
    FORCE_RET();
534 ead9360e ths
}
535 ead9360e ths
536 ead9360e ths
void op_mftc0_tchalt(void)
537 ead9360e ths
{
538 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
539 ead9360e ths
540 ead9360e ths
    T0 = env->CP0_TCHalt[other_tc];
541 8f6f6026 ths
    FORCE_RET();
542 ead9360e ths
}
543 ead9360e ths
544 ead9360e ths
void op_mfc0_tccontext (void)
545 ead9360e ths
{
546 ead9360e ths
    T0 = env->CP0_TCContext[env->current_tc];
547 8f6f6026 ths
    FORCE_RET();
548 ead9360e ths
}
549 ead9360e ths
550 ead9360e ths
void op_mftc0_tccontext(void)
551 ead9360e ths
{
552 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
553 ead9360e ths
554 ead9360e ths
    T0 = env->CP0_TCContext[other_tc];
555 8f6f6026 ths
    FORCE_RET();
556 ead9360e ths
}
557 ead9360e ths
558 ead9360e ths
void op_mfc0_tcschedule (void)
559 ead9360e ths
{
560 ead9360e ths
    T0 = env->CP0_TCSchedule[env->current_tc];
561 8f6f6026 ths
    FORCE_RET();
562 ead9360e ths
}
563 ead9360e ths
564 ead9360e ths
void op_mftc0_tcschedule(void)
565 ead9360e ths
{
566 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
567 ead9360e ths
568 ead9360e ths
    T0 = env->CP0_TCSchedule[other_tc];
569 8f6f6026 ths
    FORCE_RET();
570 ead9360e ths
}
571 ead9360e ths
572 ead9360e ths
void op_mfc0_tcschefback (void)
573 ead9360e ths
{
574 ead9360e ths
    T0 = env->CP0_TCScheFBack[env->current_tc];
575 8f6f6026 ths
    FORCE_RET();
576 ead9360e ths
}
577 ead9360e ths
578 ead9360e ths
void op_mftc0_tcschefback(void)
579 ead9360e ths
{
580 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
581 ead9360e ths
582 ead9360e ths
    T0 = env->CP0_TCScheFBack[other_tc];
583 8f6f6026 ths
    FORCE_RET();
584 ead9360e ths
}
585 ead9360e ths
586 873eb012 ths
void op_mfc0_count (void)
587 873eb012 ths
{
588 873eb012 ths
    CALL_FROM_TB0(do_mfc0_count);
589 8f6f6026 ths
    FORCE_RET();
590 873eb012 ths
}
591 873eb012 ths
592 ead9360e ths
void op_mftc0_entryhi(void)
593 ead9360e ths
{
594 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
595 ead9360e ths
596 ead9360e ths
    T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
597 8f6f6026 ths
    FORCE_RET();
598 ead9360e ths
}
599 ead9360e ths
600 ead9360e ths
void op_mftc0_status(void)
601 ead9360e ths
{
602 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
603 ead9360e ths
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
604 ead9360e ths
605 ead9360e ths
    T0 = env->CP0_Status & ~0xf1000018;
606 ead9360e ths
    T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
607 ead9360e ths
    T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
608 623a930e ths
    T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
609 8f6f6026 ths
    FORCE_RET();
610 ead9360e ths
}
611 ead9360e ths
612 873eb012 ths
void op_mfc0_lladdr (void)
613 873eb012 ths
{
614 9c2149c8 ths
    T0 = (int32_t)env->CP0_LLAddr >> 4;
615 8f6f6026 ths
    FORCE_RET();
616 873eb012 ths
}
617 873eb012 ths
618 fd88b6ab ths
void op_mfc0_watchlo (void)
619 873eb012 ths
{
620 fd88b6ab ths
    T0 = (int32_t)env->CP0_WatchLo[PARAM1];
621 8f6f6026 ths
    FORCE_RET();
622 873eb012 ths
}
623 873eb012 ths
624 fd88b6ab ths
void op_mfc0_watchhi (void)
625 873eb012 ths
{
626 fd88b6ab ths
    T0 = env->CP0_WatchHi[PARAM1];
627 8f6f6026 ths
    FORCE_RET();
628 873eb012 ths
}
629 873eb012 ths
630 873eb012 ths
void op_mfc0_debug (void)
631 873eb012 ths
{
632 9c2149c8 ths
    T0 = env->CP0_Debug;
633 873eb012 ths
    if (env->hflags & MIPS_HFLAG_DM)
634 873eb012 ths
        T0 |= 1 << CP0DB_DM;
635 8f6f6026 ths
    FORCE_RET();
636 873eb012 ths
}
637 873eb012 ths
638 ead9360e ths
void op_mftc0_debug(void)
639 ead9360e ths
{
640 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
641 ead9360e ths
642 ead9360e ths
    /* XXX: Might be wrong, check with EJTAG spec. */
643 ead9360e ths
    T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
644 ead9360e ths
         (env->CP0_Debug_tcstatus[other_tc] &
645 ead9360e ths
          ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
646 8f6f6026 ths
    FORCE_RET();
647 ead9360e ths
}
648 ead9360e ths
649 8c0fdd85 ths
void op_mtc0_index (void)
650 6af0bf9c bellard
{
651 60445285 ths
    int num = 1;
652 60445285 ths
    unsigned int tmp = env->tlb->nb_tlb;
653 60445285 ths
654 60445285 ths
    do {
655 60445285 ths
        tmp >>= 1;
656 60445285 ths
        num <<= 1;
657 60445285 ths
    } while (tmp);
658 60445285 ths
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
659 8f6f6026 ths
    FORCE_RET();
660 ead9360e ths
}
661 ead9360e ths
662 ead9360e ths
void op_mtc0_mvpcontrol (void)
663 ead9360e ths
{
664 ead9360e ths
    uint32_t mask = 0;
665 ead9360e ths
    uint32_t newval;
666 ead9360e ths
667 ead9360e ths
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
668 ead9360e ths
        mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
669 ead9360e ths
                (1 << CP0MVPCo_EVP);
670 ead9360e ths
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
671 ead9360e ths
        mask |= (1 << CP0MVPCo_STLB);
672 ead9360e ths
    newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
673 ead9360e ths
674 ead9360e ths
    // TODO: Enable/disable shared TLB, enable/disable VPEs.
675 ead9360e ths
676 ead9360e ths
    env->mvp->CP0_MVPControl = newval;
677 8f6f6026 ths
    FORCE_RET();
678 ead9360e ths
}
679 ead9360e ths
680 ead9360e ths
void op_mtc0_vpecontrol (void)
681 ead9360e ths
{
682 ead9360e ths
    uint32_t mask;
683 ead9360e ths
    uint32_t newval;
684 ead9360e ths
685 ead9360e ths
    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
686 ead9360e ths
           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
687 ead9360e ths
    newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
688 ead9360e ths
689 ead9360e ths
    /* Yield scheduler intercept not implemented. */
690 ead9360e ths
    /* Gating storage scheduler intercept not implemented. */
691 ead9360e ths
692 ead9360e ths
    // TODO: Enable/disable TCs.
693 ead9360e ths
694 ead9360e ths
    env->CP0_VPEControl = newval;
695 8f6f6026 ths
    FORCE_RET();
696 ead9360e ths
}
697 ead9360e ths
698 ead9360e ths
void op_mtc0_vpeconf0 (void)
699 ead9360e ths
{
700 ead9360e ths
    uint32_t mask = 0;
701 ead9360e ths
    uint32_t newval;
702 ead9360e ths
703 ead9360e ths
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
704 ead9360e ths
        if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
705 ead9360e ths
            mask |= (0xff << CP0VPEC0_XTC);
706 ead9360e ths
        mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
707 ead9360e ths
    }
708 ead9360e ths
    newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
709 ead9360e ths
710 ead9360e ths
    // TODO: TC exclusive handling due to ERL/EXL.
711 ead9360e ths
712 ead9360e ths
    env->CP0_VPEConf0 = newval;
713 8f6f6026 ths
    FORCE_RET();
714 ead9360e ths
}
715 ead9360e ths
716 ead9360e ths
void op_mtc0_vpeconf1 (void)
717 ead9360e ths
{
718 ead9360e ths
    uint32_t mask = 0;
719 ead9360e ths
    uint32_t newval;
720 ead9360e ths
721 ead9360e ths
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
722 ead9360e ths
        mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
723 ead9360e ths
                (0xff << CP0VPEC1_NCP1);
724 ead9360e ths
    newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
725 ead9360e ths
726 ead9360e ths
    /* UDI not implemented. */
727 ead9360e ths
    /* CP2 not implemented. */
728 ead9360e ths
729 ead9360e ths
    // TODO: Handle FPU (CP1) binding.
730 ead9360e ths
731 ead9360e ths
    env->CP0_VPEConf1 = newval;
732 8f6f6026 ths
    FORCE_RET();
733 ead9360e ths
}
734 ead9360e ths
735 ead9360e ths
void op_mtc0_yqmask (void)
736 ead9360e ths
{
737 ead9360e ths
    /* Yield qualifier inputs not implemented. */
738 ead9360e ths
    env->CP0_YQMask = 0x00000000;
739 8f6f6026 ths
    FORCE_RET();
740 ead9360e ths
}
741 ead9360e ths
742 ead9360e ths
void op_mtc0_vpeschedule (void)
743 ead9360e ths
{
744 ead9360e ths
    env->CP0_VPESchedule = T0;
745 8f6f6026 ths
    FORCE_RET();
746 ead9360e ths
}
747 ead9360e ths
748 ead9360e ths
void op_mtc0_vpeschefback (void)
749 ead9360e ths
{
750 ead9360e ths
    env->CP0_VPEScheFBack = T0;
751 8f6f6026 ths
    FORCE_RET();
752 ead9360e ths
}
753 ead9360e ths
754 ead9360e ths
void op_mtc0_vpeopt (void)
755 ead9360e ths
{
756 ead9360e ths
    env->CP0_VPEOpt = T0 & 0x0000ffff;
757 8f6f6026 ths
    FORCE_RET();
758 8c0fdd85 ths
}
759 8c0fdd85 ths
760 8c0fdd85 ths
void op_mtc0_entrylo0 (void)
761 8c0fdd85 ths
{
762 6d35524c ths
    /* Large physaddr (PABITS) not implemented */
763 7a387fff ths
    /* 1k pages not implemented */
764 f1b0aa5d ths
    env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
765 8f6f6026 ths
    FORCE_RET();
766 8c0fdd85 ths
}
767 8c0fdd85 ths
768 ead9360e ths
void op_mtc0_tcstatus (void)
769 ead9360e ths
{
770 ead9360e ths
    uint32_t mask = env->CP0_TCStatus_rw_bitmask;
771 ead9360e ths
    uint32_t newval;
772 ead9360e ths
773 ead9360e ths
    newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
774 ead9360e ths
775 ead9360e ths
    // TODO: Sync with CP0_Status.
776 ead9360e ths
777 ead9360e ths
    env->CP0_TCStatus[env->current_tc] = newval;
778 8f6f6026 ths
    FORCE_RET();
779 ead9360e ths
}
780 ead9360e ths
781 ead9360e ths
void op_mttc0_tcstatus (void)
782 ead9360e ths
{
783 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
784 ead9360e ths
785 ead9360e ths
    // TODO: Sync with CP0_Status.
786 ead9360e ths
787 ead9360e ths
    env->CP0_TCStatus[other_tc] = T0;
788 8f6f6026 ths
    FORCE_RET();
789 ead9360e ths
}
790 ead9360e ths
791 ead9360e ths
void op_mtc0_tcbind (void)
792 ead9360e ths
{
793 ead9360e ths
    uint32_t mask = (1 << CP0TCBd_TBE);
794 ead9360e ths
    uint32_t newval;
795 ead9360e ths
796 ead9360e ths
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
797 ead9360e ths
        mask |= (1 << CP0TCBd_CurVPE);
798 ead9360e ths
    newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
799 ead9360e ths
    env->CP0_TCBind[env->current_tc] = newval;
800 8f6f6026 ths
    FORCE_RET();
801 ead9360e ths
}
802 ead9360e ths
803 ead9360e ths
void op_mttc0_tcbind (void)
804 ead9360e ths
{
805 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
806 ead9360e ths
    uint32_t mask = (1 << CP0TCBd_TBE);
807 ead9360e ths
    uint32_t newval;
808 ead9360e ths
809 ead9360e ths
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
810 ead9360e ths
        mask |= (1 << CP0TCBd_CurVPE);
811 ead9360e ths
    newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
812 ead9360e ths
    env->CP0_TCBind[other_tc] = newval;
813 8f6f6026 ths
    FORCE_RET();
814 ead9360e ths
}
815 ead9360e ths
816 ead9360e ths
void op_mtc0_tcrestart (void)
817 ead9360e ths
{
818 ead9360e ths
    env->PC[env->current_tc] = T0;
819 ead9360e ths
    env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
820 ead9360e ths
    env->CP0_LLAddr = 0ULL;
821 ead9360e ths
    /* MIPS16 not implemented. */
822 8f6f6026 ths
    FORCE_RET();
823 ead9360e ths
}
824 ead9360e ths
825 ead9360e ths
void op_mttc0_tcrestart (void)
826 ead9360e ths
{
827 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
828 ead9360e ths
829 ead9360e ths
    env->PC[other_tc] = T0;
830 ead9360e ths
    env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
831 ead9360e ths
    env->CP0_LLAddr = 0ULL;
832 ead9360e ths
    /* MIPS16 not implemented. */
833 8f6f6026 ths
    FORCE_RET();
834 ead9360e ths
}
835 ead9360e ths
836 ead9360e ths
void op_mtc0_tchalt (void)
837 ead9360e ths
{
838 ead9360e ths
    env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
839 ead9360e ths
840 ead9360e ths
    // TODO: Halt TC / Restart (if allocated+active) TC.
841 ead9360e ths
842 8f6f6026 ths
    FORCE_RET();
843 ead9360e ths
}
844 ead9360e ths
845 ead9360e ths
void op_mttc0_tchalt (void)
846 ead9360e ths
{
847 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
848 ead9360e ths
849 ead9360e ths
    // TODO: Halt TC / Restart (if allocated+active) TC.
850 ead9360e ths
851 ead9360e ths
    env->CP0_TCHalt[other_tc] = T0;
852 8f6f6026 ths
    FORCE_RET();
853 ead9360e ths
}
854 ead9360e ths
855 ead9360e ths
void op_mtc0_tccontext (void)
856 ead9360e ths
{
857 ead9360e ths
    env->CP0_TCContext[env->current_tc] = T0;
858 8f6f6026 ths
    FORCE_RET();
859 ead9360e ths
}
860 ead9360e ths
861 ead9360e ths
void op_mttc0_tccontext (void)
862 ead9360e ths
{
863 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
864 ead9360e ths
865 ead9360e ths
    env->CP0_TCContext[other_tc] = T0;
866 8f6f6026 ths
    FORCE_RET();
867 ead9360e ths
}
868 ead9360e ths
869 ead9360e ths
void op_mtc0_tcschedule (void)
870 ead9360e ths
{
871 ead9360e ths
    env->CP0_TCSchedule[env->current_tc] = T0;
872 8f6f6026 ths
    FORCE_RET();
873 ead9360e ths
}
874 ead9360e ths
875 ead9360e ths
void op_mttc0_tcschedule (void)
876 ead9360e ths
{
877 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
878 ead9360e ths
879 ead9360e ths
    env->CP0_TCSchedule[other_tc] = T0;
880 8f6f6026 ths
    FORCE_RET();
881 ead9360e ths
}
882 ead9360e ths
883 ead9360e ths
void op_mtc0_tcschefback (void)
884 ead9360e ths
{
885 ead9360e ths
    env->CP0_TCScheFBack[env->current_tc] = T0;
886 8f6f6026 ths
    FORCE_RET();
887 ead9360e ths
}
888 ead9360e ths
889 ead9360e ths
void op_mttc0_tcschefback (void)
890 ead9360e ths
{
891 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
892 ead9360e ths
893 ead9360e ths
    env->CP0_TCScheFBack[other_tc] = T0;
894 8f6f6026 ths
    FORCE_RET();
895 ead9360e ths
}
896 ead9360e ths
897 8c0fdd85 ths
void op_mtc0_entrylo1 (void)
898 8c0fdd85 ths
{
899 6d35524c ths
    /* Large physaddr (PABITS) not implemented */
900 7a387fff ths
    /* 1k pages not implemented */
901 f1b0aa5d ths
    env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
902 8f6f6026 ths
    FORCE_RET();
903 8c0fdd85 ths
}
904 8c0fdd85 ths
905 8c0fdd85 ths
void op_mtc0_context (void)
906 8c0fdd85 ths
{
907 534ce69f ths
    env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
908 8f6f6026 ths
    FORCE_RET();
909 8c0fdd85 ths
}
910 8c0fdd85 ths
911 8c0fdd85 ths
void op_mtc0_pagemask (void)
912 8c0fdd85 ths
{
913 7a387fff ths
    /* 1k pages not implemented */
914 f2e9ebef ths
    env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
915 8f6f6026 ths
    FORCE_RET();
916 7a387fff ths
}
917 7a387fff ths
918 7a387fff ths
void op_mtc0_pagegrain (void)
919 7a387fff ths
{
920 7a387fff ths
    /* SmartMIPS not implemented */
921 6d35524c ths
    /* Large physaddr (PABITS) not implemented */
922 7a387fff ths
    /* 1k pages not implemented */
923 7a387fff ths
    env->CP0_PageGrain = 0;
924 8f6f6026 ths
    FORCE_RET();
925 8c0fdd85 ths
}
926 8c0fdd85 ths
927 8c0fdd85 ths
void op_mtc0_wired (void)
928 8c0fdd85 ths
{
929 ead9360e ths
    env->CP0_Wired = T0 % env->tlb->nb_tlb;
930 8f6f6026 ths
    FORCE_RET();
931 ead9360e ths
}
932 ead9360e ths
933 ead9360e ths
void op_mtc0_srsconf0 (void)
934 ead9360e ths
{
935 ead9360e ths
    env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
936 8f6f6026 ths
    FORCE_RET();
937 ead9360e ths
}
938 ead9360e ths
939 ead9360e ths
void op_mtc0_srsconf1 (void)
940 ead9360e ths
{
941 ead9360e ths
    env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
942 8f6f6026 ths
    FORCE_RET();
943 ead9360e ths
}
944 ead9360e ths
945 ead9360e ths
void op_mtc0_srsconf2 (void)
946 ead9360e ths
{
947 ead9360e ths
    env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
948 8f6f6026 ths
    FORCE_RET();
949 ead9360e ths
}
950 ead9360e ths
951 ead9360e ths
void op_mtc0_srsconf3 (void)
952 ead9360e ths
{
953 ead9360e ths
    env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
954 8f6f6026 ths
    FORCE_RET();
955 ead9360e ths
}
956 ead9360e ths
957 ead9360e ths
void op_mtc0_srsconf4 (void)
958 ead9360e ths
{
959 ead9360e ths
    env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
960 8f6f6026 ths
    FORCE_RET();
961 7a387fff ths
}
962 7a387fff ths
963 7a387fff ths
void op_mtc0_hwrena (void)
964 7a387fff ths
{
965 7a387fff ths
    env->CP0_HWREna = T0 & 0x0000000F;
966 8f6f6026 ths
    FORCE_RET();
967 8c0fdd85 ths
}
968 8c0fdd85 ths
969 8c0fdd85 ths
void op_mtc0_count (void)
970 8c0fdd85 ths
{
971 8c0fdd85 ths
    CALL_FROM_TB2(cpu_mips_store_count, env, T0);
972 8f6f6026 ths
    FORCE_RET();
973 8c0fdd85 ths
}
974 8c0fdd85 ths
975 8c0fdd85 ths
void op_mtc0_entryhi (void)
976 8c0fdd85 ths
{
977 0feef828 ths
    target_ulong old, val;
978 8c0fdd85 ths
979 7a387fff ths
    /* 1k pages not implemented */
980 100ce988 ths
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
981 d26bc211 ths
#if defined(TARGET_MIPS64)
982 e034e2c3 ths
    val &= env->SEGMask;
983 100ce988 ths
#endif
984 8c0fdd85 ths
    old = env->CP0_EntryHi;
985 8c0fdd85 ths
    env->CP0_EntryHi = val;
986 ead9360e ths
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
987 ead9360e ths
        uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
988 ead9360e ths
        env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
989 ead9360e ths
    }
990 8c0fdd85 ths
    /* If the ASID changes, flush qemu's TLB.  */
991 8c0fdd85 ths
    if ((old & 0xFF) != (val & 0xFF))
992 8c0fdd85 ths
        CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
993 8f6f6026 ths
    FORCE_RET();
994 8c0fdd85 ths
}
995 8c0fdd85 ths
996 ead9360e ths
void op_mttc0_entryhi(void)
997 ead9360e ths
{
998 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
999 ead9360e ths
1000 ead9360e ths
    env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1001 ead9360e ths
    env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1002 8f6f6026 ths
    FORCE_RET();
1003 ead9360e ths
}
1004 ead9360e ths
1005 8c0fdd85 ths
void op_mtc0_compare (void)
1006 8c0fdd85 ths
{
1007 8c0fdd85 ths
    CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1008 8f6f6026 ths
    FORCE_RET();
1009 8c0fdd85 ths
}
1010 8c0fdd85 ths
1011 8c0fdd85 ths
void op_mtc0_status (void)
1012 8c0fdd85 ths
{
1013 4de9b249 ths
    uint32_t val, old;
1014 ead9360e ths
    uint32_t mask = env->CP0_Status_rw_bitmask;
1015 8c0fdd85 ths
1016 f1b0aa5d ths
    val = T0 & mask;
1017 8c0fdd85 ths
    old = env->CP0_Status;
1018 5a5012ec ths
    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1019 08fa4bab ths
    CALL_FROM_TB1(compute_hflags, env);
1020 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
1021 f41c52f1 ths
        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1022 4de9b249 ths
    CALL_FROM_TB1(cpu_mips_update_irq, env);
1023 8f6f6026 ths
    FORCE_RET();
1024 8c0fdd85 ths
}
1025 8c0fdd85 ths
1026 ead9360e ths
void op_mttc0_status(void)
1027 ead9360e ths
{
1028 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1029 ead9360e ths
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1030 ead9360e ths
1031 ead9360e ths
    env->CP0_Status = T0 & ~0xf1000018;
1032 ead9360e ths
    tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1033 ead9360e ths
    tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1034 623a930e ths
    tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1035 ead9360e ths
    env->CP0_TCStatus[other_tc] = tcstatus;
1036 8f6f6026 ths
    FORCE_RET();
1037 ead9360e ths
}
1038 ead9360e ths
1039 7a387fff ths
void op_mtc0_intctl (void)
1040 7a387fff ths
{
1041 42532189 ths
    /* vectored interrupts not implemented, no performance counters. */
1042 42532189 ths
    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1043 8f6f6026 ths
    FORCE_RET();
1044 7a387fff ths
}
1045 7a387fff ths
1046 7a387fff ths
void op_mtc0_srsctl (void)
1047 7a387fff ths
{
1048 ead9360e ths
    uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1049 ead9360e ths
    env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1050 8f6f6026 ths
    FORCE_RET();
1051 7a387fff ths
}
1052 7a387fff ths
1053 9c2149c8 ths
void op_mtc0_srsmap (void)
1054 9c2149c8 ths
{
1055 ead9360e ths
    env->CP0_SRSMap = T0;
1056 8f6f6026 ths
    FORCE_RET();
1057 9c2149c8 ths
}
1058 9c2149c8 ths
1059 8c0fdd85 ths
void op_mtc0_cause (void)
1060 8c0fdd85 ths
{
1061 39d51eb8 ths
    uint32_t mask = 0x00C00300;
1062 42532189 ths
    uint32_t old = env->CP0_Cause;
1063 39d51eb8 ths
1064 e189e748 ths
    if (env->insn_flags & ISA_MIPS32R2)
1065 39d51eb8 ths
        mask |= 1 << CP0Ca_DC;
1066 39d51eb8 ths
1067 e58c8ba5 ths
    env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1068 8c0fdd85 ths
1069 42532189 ths
    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1070 42532189 ths
        if (env->CP0_Cause & (1 << CP0Ca_DC))
1071 42532189 ths
            CALL_FROM_TB1(cpu_mips_stop_count, env);
1072 42532189 ths
        else
1073 42532189 ths
            CALL_FROM_TB1(cpu_mips_start_count, env);
1074 42532189 ths
    }
1075 42532189 ths
1076 4de9b249 ths
    /* Handle the software interrupt as an hardware one, as they
1077 4de9b249 ths
       are very similar */
1078 4de9b249 ths
    if (T0 & CP0Ca_IP_mask) {
1079 4de9b249 ths
        CALL_FROM_TB1(cpu_mips_update_irq, env);
1080 8c0fdd85 ths
    }
1081 8f6f6026 ths
    FORCE_RET();
1082 8c0fdd85 ths
}
1083 8c0fdd85 ths
1084 8c0fdd85 ths
void op_mtc0_epc (void)
1085 8c0fdd85 ths
{
1086 f1b0aa5d ths
    env->CP0_EPC = T0;
1087 8f6f6026 ths
    FORCE_RET();
1088 8c0fdd85 ths
}
1089 8c0fdd85 ths
1090 7a387fff ths
void op_mtc0_ebase (void)
1091 7a387fff ths
{
1092 7a387fff ths
    /* vectored interrupts not implemented */
1093 7a387fff ths
    /* Multi-CPU not implemented */
1094 b29a0341 ths
    env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1095 8f6f6026 ths
    FORCE_RET();
1096 7a387fff ths
}
1097 7a387fff ths
1098 8c0fdd85 ths
void op_mtc0_config0 (void)
1099 8c0fdd85 ths
{
1100 7bfd934a ths
    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
1101 8f6f6026 ths
    FORCE_RET();
1102 8c0fdd85 ths
}
1103 8c0fdd85 ths
1104 7a387fff ths
void op_mtc0_config2 (void)
1105 7a387fff ths
{
1106 7a387fff ths
    /* tertiary/secondary caches not implemented */
1107 7a387fff ths
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1108 8f6f6026 ths
    FORCE_RET();
1109 7a387fff ths
}
1110 7a387fff ths
1111 fd88b6ab ths
void op_mtc0_watchlo (void)
1112 8c0fdd85 ths
{
1113 4e7a4a4e ths
    /* Watch exceptions for instructions, data loads, data stores
1114 4e7a4a4e ths
       not implemented. */
1115 fd88b6ab ths
    env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1116 8f6f6026 ths
    FORCE_RET();
1117 8c0fdd85 ths
}
1118 8c0fdd85 ths
1119 fd88b6ab ths
void op_mtc0_watchhi (void)
1120 8c0fdd85 ths
{
1121 fd88b6ab ths
    env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1122 fd88b6ab ths
    env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1123 8f6f6026 ths
    FORCE_RET();
1124 8c0fdd85 ths
}
1125 8c0fdd85 ths
1126 ead9360e ths
void op_mtc0_xcontext (void)
1127 ead9360e ths
{
1128 ead9360e ths
    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1129 ead9360e ths
    env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1130 8f6f6026 ths
    FORCE_RET();
1131 ead9360e ths
}
1132 ead9360e ths
1133 7a387fff ths
void op_mtc0_framemask (void)
1134 7a387fff ths
{
1135 7a387fff ths
    env->CP0_Framemask = T0; /* XXX */
1136 8f6f6026 ths
    FORCE_RET();
1137 7a387fff ths
}
1138 7a387fff ths
1139 8c0fdd85 ths
void op_mtc0_debug (void)
1140 8c0fdd85 ths
{
1141 8c0fdd85 ths
    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1142 8c0fdd85 ths
    if (T0 & (1 << CP0DB_DM))
1143 8c0fdd85 ths
        env->hflags |= MIPS_HFLAG_DM;
1144 8c0fdd85 ths
    else
1145 8c0fdd85 ths
        env->hflags &= ~MIPS_HFLAG_DM;
1146 8f6f6026 ths
    FORCE_RET();
1147 8c0fdd85 ths
}
1148 8c0fdd85 ths
1149 ead9360e ths
void op_mttc0_debug(void)
1150 ead9360e ths
{
1151 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1152 ead9360e ths
1153 ead9360e ths
    /* XXX: Might be wrong, check with EJTAG spec. */
1154 ead9360e ths
    env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
1155 ead9360e ths
    env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1156 ead9360e ths
                     (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1157 8f6f6026 ths
    FORCE_RET();
1158 ead9360e ths
}
1159 ead9360e ths
1160 8c0fdd85 ths
void op_mtc0_depc (void)
1161 8c0fdd85 ths
{
1162 f1b0aa5d ths
    env->CP0_DEPC = T0;
1163 8f6f6026 ths
    FORCE_RET();
1164 8c0fdd85 ths
}
1165 8c0fdd85 ths
1166 7a387fff ths
void op_mtc0_performance0 (void)
1167 7a387fff ths
{
1168 1b6fd0bc ths
    env->CP0_Performance0 = T0 & 0x000007ff;
1169 8f6f6026 ths
    FORCE_RET();
1170 7a387fff ths
}
1171 7a387fff ths
1172 8c0fdd85 ths
void op_mtc0_taglo (void)
1173 8c0fdd85 ths
{
1174 9c2149c8 ths
    env->CP0_TagLo = T0 & 0xFFFFFCF6;
1175 8f6f6026 ths
    FORCE_RET();
1176 8c0fdd85 ths
}
1177 8c0fdd85 ths
1178 7a387fff ths
void op_mtc0_datalo (void)
1179 7a387fff ths
{
1180 7a387fff ths
    env->CP0_DataLo = T0; /* XXX */
1181 8f6f6026 ths
    FORCE_RET();
1182 7a387fff ths
}
1183 7a387fff ths
1184 7a387fff ths
void op_mtc0_taghi (void)
1185 7a387fff ths
{
1186 7a387fff ths
    env->CP0_TagHi = T0; /* XXX */
1187 8f6f6026 ths
    FORCE_RET();
1188 7a387fff ths
}
1189 7a387fff ths
1190 7a387fff ths
void op_mtc0_datahi (void)
1191 7a387fff ths
{
1192 7a387fff ths
    env->CP0_DataHi = T0; /* XXX */
1193 8f6f6026 ths
    FORCE_RET();
1194 7a387fff ths
}
1195 7a387fff ths
1196 8c0fdd85 ths
void op_mtc0_errorepc (void)
1197 8c0fdd85 ths
{
1198 f1b0aa5d ths
    env->CP0_ErrorEPC = T0;
1199 8f6f6026 ths
    FORCE_RET();
1200 8c0fdd85 ths
}
1201 8c0fdd85 ths
1202 8c0fdd85 ths
void op_mtc0_desave (void)
1203 8c0fdd85 ths
{
1204 8c0fdd85 ths
    env->CP0_DESAVE = T0;
1205 8f6f6026 ths
    FORCE_RET();
1206 6af0bf9c bellard
}
1207 6af0bf9c bellard
1208 d26bc211 ths
#if defined(TARGET_MIPS64)
1209 ead9360e ths
void op_dmfc0_tcrestart (void)
1210 ead9360e ths
{
1211 ead9360e ths
    T0 = env->PC[env->current_tc];
1212 8f6f6026 ths
    FORCE_RET();
1213 ead9360e ths
}
1214 ead9360e ths
1215 ead9360e ths
void op_dmfc0_tchalt (void)
1216 ead9360e ths
{
1217 ead9360e ths
    T0 = env->CP0_TCHalt[env->current_tc];
1218 8f6f6026 ths
    FORCE_RET();
1219 ead9360e ths
}
1220 ead9360e ths
1221 ead9360e ths
void op_dmfc0_tccontext (void)
1222 ead9360e ths
{
1223 ead9360e ths
    T0 = env->CP0_TCContext[env->current_tc];
1224 8f6f6026 ths
    FORCE_RET();
1225 ead9360e ths
}
1226 ead9360e ths
1227 ead9360e ths
void op_dmfc0_tcschedule (void)
1228 ead9360e ths
{
1229 ead9360e ths
    T0 = env->CP0_TCSchedule[env->current_tc];
1230 8f6f6026 ths
    FORCE_RET();
1231 ead9360e ths
}
1232 ead9360e ths
1233 ead9360e ths
void op_dmfc0_tcschefback (void)
1234 ead9360e ths
{
1235 ead9360e ths
    T0 = env->CP0_TCScheFBack[env->current_tc];
1236 8f6f6026 ths
    FORCE_RET();
1237 ead9360e ths
}
1238 ead9360e ths
1239 9c2149c8 ths
void op_dmfc0_lladdr (void)
1240 9c2149c8 ths
{
1241 9c2149c8 ths
    T0 = env->CP0_LLAddr >> 4;
1242 8f6f6026 ths
    FORCE_RET();
1243 9c2149c8 ths
}
1244 9c2149c8 ths
1245 fd88b6ab ths
void op_dmfc0_watchlo (void)
1246 9c2149c8 ths
{
1247 fd88b6ab ths
    T0 = env->CP0_WatchLo[PARAM1];
1248 8f6f6026 ths
    FORCE_RET();
1249 9c2149c8 ths
}
1250 d26bc211 ths
#endif /* TARGET_MIPS64 */
1251 9c2149c8 ths
1252 ead9360e ths
/* MIPS MT functions */
1253 ead9360e ths
void op_mftgpr(void)
1254 ead9360e ths
{
1255 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1256 ead9360e ths
1257 5b2808bf ths
    T0 = env->gpr[other_tc][PARAM1];
1258 8f6f6026 ths
    FORCE_RET();
1259 ead9360e ths
}
1260 ead9360e ths
1261 ead9360e ths
void op_mftlo(void)
1262 ead9360e ths
{
1263 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1264 ead9360e ths
1265 5b2808bf ths
    T0 = env->LO[other_tc][PARAM1];
1266 8f6f6026 ths
    FORCE_RET();
1267 ead9360e ths
}
1268 ead9360e ths
1269 ead9360e ths
void op_mfthi(void)
1270 ead9360e ths
{
1271 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1272 ead9360e ths
1273 5b2808bf ths
    T0 = env->HI[other_tc][PARAM1];
1274 8f6f6026 ths
    FORCE_RET();
1275 ead9360e ths
}
1276 ead9360e ths
1277 ead9360e ths
void op_mftacx(void)
1278 ead9360e ths
{
1279 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1280 ead9360e ths
1281 5b2808bf ths
    T0 = env->ACX[other_tc][PARAM1];
1282 8f6f6026 ths
    FORCE_RET();
1283 ead9360e ths
}
1284 ead9360e ths
1285 ead9360e ths
void op_mftdsp(void)
1286 ead9360e ths
{
1287 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1288 ead9360e ths
1289 ead9360e ths
    T0 = env->DSPControl[other_tc];
1290 8f6f6026 ths
    FORCE_RET();
1291 ead9360e ths
}
1292 ead9360e ths
1293 ead9360e ths
void op_mttgpr(void)
1294 ead9360e ths
{
1295 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1296 ead9360e ths
1297 5b2808bf ths
    T0 = env->gpr[other_tc][PARAM1];
1298 8f6f6026 ths
    FORCE_RET();
1299 ead9360e ths
}
1300 ead9360e ths
1301 ead9360e ths
void op_mttlo(void)
1302 ead9360e ths
{
1303 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1304 ead9360e ths
1305 5b2808bf ths
    T0 = env->LO[other_tc][PARAM1];
1306 8f6f6026 ths
    FORCE_RET();
1307 ead9360e ths
}
1308 ead9360e ths
1309 ead9360e ths
void op_mtthi(void)
1310 ead9360e ths
{
1311 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1312 ead9360e ths
1313 5b2808bf ths
    T0 = env->HI[other_tc][PARAM1];
1314 8f6f6026 ths
    FORCE_RET();
1315 ead9360e ths
}
1316 ead9360e ths
1317 ead9360e ths
void op_mttacx(void)
1318 ead9360e ths
{
1319 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1320 ead9360e ths
1321 5b2808bf ths
    T0 = env->ACX[other_tc][PARAM1];
1322 8f6f6026 ths
    FORCE_RET();
1323 ead9360e ths
}
1324 ead9360e ths
1325 ead9360e ths
void op_mttdsp(void)
1326 ead9360e ths
{
1327 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1328 ead9360e ths
1329 ead9360e ths
    T0 = env->DSPControl[other_tc];
1330 8f6f6026 ths
    FORCE_RET();
1331 ead9360e ths
}
1332 ead9360e ths
1333 ead9360e ths
1334 ead9360e ths
void op_dmt(void)
1335 ead9360e ths
{
1336 ead9360e ths
    // TODO
1337 ead9360e ths
    T0 = 0;
1338 ead9360e ths
    // rt = T0
1339 8f6f6026 ths
    FORCE_RET();
1340 ead9360e ths
}
1341 ead9360e ths
1342 ead9360e ths
void op_emt(void)
1343 ead9360e ths
{
1344 ead9360e ths
    // TODO
1345 ead9360e ths
    T0 = 0;
1346 ead9360e ths
    // rt = T0
1347 8f6f6026 ths
    FORCE_RET();
1348 ead9360e ths
}
1349 ead9360e ths
1350 ead9360e ths
void op_dvpe(void)
1351 ead9360e ths
{
1352 ead9360e ths
    // TODO
1353 ead9360e ths
    T0 = 0;
1354 ead9360e ths
    // rt = T0
1355 8f6f6026 ths
    FORCE_RET();
1356 ead9360e ths
}
1357 ead9360e ths
1358 ead9360e ths
void op_evpe(void)
1359 ead9360e ths
{
1360 ead9360e ths
    // TODO
1361 ead9360e ths
    T0 = 0;
1362 ead9360e ths
    // rt = T0
1363 8f6f6026 ths
    FORCE_RET();
1364 ead9360e ths
}
1365 ead9360e ths
1366 ead9360e ths
void op_fork(void)
1367 ead9360e ths
{
1368 ead9360e ths
    // T0 = rt, T1 = rs
1369 ead9360e ths
    T0 = 0;
1370 ead9360e ths
    // TODO: store to TC register
1371 8f6f6026 ths
    FORCE_RET();
1372 ead9360e ths
}
1373 ead9360e ths
1374 ead9360e ths
void op_yield(void)
1375 ead9360e ths
{
1376 ead9360e ths
    if (T0 < 0) {
1377 ead9360e ths
        /* No scheduling policy implemented. */
1378 ead9360e ths
        if (T0 != -2) {
1379 ead9360e ths
            if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
1380 ead9360e ths
                env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
1381 ead9360e ths
                env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1382 ead9360e ths
                env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
1383 ead9360e ths
                CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1384 ead9360e ths
            }
1385 ead9360e ths
        }
1386 ead9360e ths
    } else if (T0 == 0) {
1387 ead9360e ths
        if (0 /* TODO: TC underflow */) {
1388 ead9360e ths
            env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1389 ead9360e ths
            CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1390 ead9360e ths
        } else {
1391 ead9360e ths
            // TODO: Deallocate TC
1392 ead9360e ths
        }
1393 ead9360e ths
    } else if (T0 > 0) {
1394 ead9360e ths
        /* Yield qualifier inputs not implemented. */
1395 ead9360e ths
        env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1396 ead9360e ths
        env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
1397 ead9360e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1398 ead9360e ths
    }
1399 ead9360e ths
    T0 = env->CP0_YQMask;
1400 8f6f6026 ths
    FORCE_RET();
1401 ead9360e ths
}
1402 ead9360e ths
1403 5a5012ec ths
/* CP1 functions */
1404 6ea83fed bellard
#if 0
1405 6ea83fed bellard
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1406 6ea83fed bellard
#else
1407 6ea83fed bellard
# define DEBUG_FPU_STATE() do { } while(0)
1408 6ea83fed bellard
#endif
1409 6ea83fed bellard
1410 5a5012ec ths
void op_cfc1 (void)
1411 5a5012ec ths
{
1412 ead9360e ths
    CALL_FROM_TB1(do_cfc1, PARAM1);
1413 5a5012ec ths
    DEBUG_FPU_STATE();
1414 8f6f6026 ths
    FORCE_RET();
1415 5a5012ec ths
}
1416 5a5012ec ths
1417 5a5012ec ths
void op_ctc1 (void)
1418 5a5012ec ths
{
1419 ead9360e ths
    CALL_FROM_TB1(do_ctc1, PARAM1);
1420 6ea83fed bellard
    DEBUG_FPU_STATE();
1421 8f6f6026 ths
    FORCE_RET();
1422 6ea83fed bellard
}
1423 6ea83fed bellard
1424 6ea83fed bellard
void op_mfc1 (void)
1425 6ea83fed bellard
{
1426 6ad38722 ths
    T0 = (int32_t)WT0;
1427 6ea83fed bellard
    DEBUG_FPU_STATE();
1428 8f6f6026 ths
    FORCE_RET();
1429 6ea83fed bellard
}
1430 6ea83fed bellard
1431 6ea83fed bellard
void op_mtc1 (void)
1432 6ea83fed bellard
{
1433 6ea83fed bellard
    WT0 = T0;
1434 6ea83fed bellard
    DEBUG_FPU_STATE();
1435 8f6f6026 ths
    FORCE_RET();
1436 6ea83fed bellard
}
1437 6ea83fed bellard
1438 5a5012ec ths
void op_dmfc1 (void)
1439 5a5012ec ths
{
1440 5a5012ec ths
    T0 = DT0;
1441 5a5012ec ths
    DEBUG_FPU_STATE();
1442 8f6f6026 ths
    FORCE_RET();
1443 5a5012ec ths
}
1444 5a5012ec ths
1445 5a5012ec ths
void op_dmtc1 (void)
1446 5a5012ec ths
{
1447 5a5012ec ths
    DT0 = T0;
1448 5a5012ec ths
    DEBUG_FPU_STATE();
1449 8f6f6026 ths
    FORCE_RET();
1450 5a5012ec ths
}
1451 5a5012ec ths
1452 5a5012ec ths
void op_mfhc1 (void)
1453 5a5012ec ths
{
1454 6ad38722 ths
    T0 = (int32_t)WTH0;
1455 5a5012ec ths
    DEBUG_FPU_STATE();
1456 8f6f6026 ths
    FORCE_RET();
1457 5a5012ec ths
}
1458 5a5012ec ths
1459 5a5012ec ths
void op_mthc1 (void)
1460 5a5012ec ths
{
1461 5a5012ec ths
    WTH0 = T0;
1462 5a5012ec ths
    DEBUG_FPU_STATE();
1463 8f6f6026 ths
    FORCE_RET();
1464 5a5012ec ths
}
1465 5a5012ec ths
1466 6ea83fed bellard
/* Float support.
1467 6ea83fed bellard
   Single precition routines have a "s" suffix, double precision a
1468 5a5012ec ths
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1469 5a5012ec ths
   paired single lowwer "pl", paired single upper "pu".  */
1470 6ea83fed bellard
1471 6ea83fed bellard
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1472 6ea83fed bellard
1473 dd016883 bellard
FLOAT_OP(cvtd, s)
1474 dd016883 bellard
{
1475 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtd_s);
1476 dd016883 bellard
    DEBUG_FPU_STATE();
1477 8f6f6026 ths
    FORCE_RET();
1478 dd016883 bellard
}
1479 6ea83fed bellard
FLOAT_OP(cvtd, w)
1480 6ea83fed bellard
{
1481 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtd_w);
1482 5a5012ec ths
    DEBUG_FPU_STATE();
1483 8f6f6026 ths
    FORCE_RET();
1484 5a5012ec ths
}
1485 5a5012ec ths
FLOAT_OP(cvtd, l)
1486 5a5012ec ths
{
1487 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtd_l);
1488 5a5012ec ths
    DEBUG_FPU_STATE();
1489 8f6f6026 ths
    FORCE_RET();
1490 5a5012ec ths
}
1491 5a5012ec ths
FLOAT_OP(cvtl, d)
1492 5a5012ec ths
{
1493 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtl_d);
1494 5a5012ec ths
    DEBUG_FPU_STATE();
1495 8f6f6026 ths
    FORCE_RET();
1496 5a5012ec ths
}
1497 5a5012ec ths
FLOAT_OP(cvtl, s)
1498 5a5012ec ths
{
1499 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtl_s);
1500 5a5012ec ths
    DEBUG_FPU_STATE();
1501 8f6f6026 ths
    FORCE_RET();
1502 5a5012ec ths
}
1503 5a5012ec ths
FLOAT_OP(cvtps, s)
1504 5a5012ec ths
{
1505 5a5012ec ths
    WT2 = WT0;
1506 5a5012ec ths
    WTH2 = WT1;
1507 5a5012ec ths
    DEBUG_FPU_STATE();
1508 8f6f6026 ths
    FORCE_RET();
1509 5a5012ec ths
}
1510 5a5012ec ths
FLOAT_OP(cvtps, pw)
1511 5a5012ec ths
{
1512 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtps_pw);
1513 5a5012ec ths
    DEBUG_FPU_STATE();
1514 8f6f6026 ths
    FORCE_RET();
1515 5a5012ec ths
}
1516 5a5012ec ths
FLOAT_OP(cvtpw, ps)
1517 5a5012ec ths
{
1518 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtpw_ps);
1519 6ea83fed bellard
    DEBUG_FPU_STATE();
1520 8f6f6026 ths
    FORCE_RET();
1521 6ea83fed bellard
}
1522 dd016883 bellard
FLOAT_OP(cvts, d)
1523 dd016883 bellard
{
1524 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_d);
1525 dd016883 bellard
    DEBUG_FPU_STATE();
1526 8f6f6026 ths
    FORCE_RET();
1527 dd016883 bellard
}
1528 6ea83fed bellard
FLOAT_OP(cvts, w)
1529 6ea83fed bellard
{
1530 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_w);
1531 5a5012ec ths
    DEBUG_FPU_STATE();
1532 8f6f6026 ths
    FORCE_RET();
1533 5a5012ec ths
}
1534 5a5012ec ths
FLOAT_OP(cvts, l)
1535 5a5012ec ths
{
1536 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_l);
1537 5a5012ec ths
    DEBUG_FPU_STATE();
1538 8f6f6026 ths
    FORCE_RET();
1539 5a5012ec ths
}
1540 5a5012ec ths
FLOAT_OP(cvts, pl)
1541 5a5012ec ths
{
1542 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_pl);
1543 5a5012ec ths
    DEBUG_FPU_STATE();
1544 8f6f6026 ths
    FORCE_RET();
1545 5a5012ec ths
}
1546 5a5012ec ths
FLOAT_OP(cvts, pu)
1547 5a5012ec ths
{
1548 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvts_pu);
1549 6ea83fed bellard
    DEBUG_FPU_STATE();
1550 8f6f6026 ths
    FORCE_RET();
1551 6ea83fed bellard
}
1552 6ea83fed bellard
FLOAT_OP(cvtw, s)
1553 6ea83fed bellard
{
1554 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtw_s);
1555 6ea83fed bellard
    DEBUG_FPU_STATE();
1556 8f6f6026 ths
    FORCE_RET();
1557 6ea83fed bellard
}
1558 6ea83fed bellard
FLOAT_OP(cvtw, d)
1559 6ea83fed bellard
{
1560 fd4a04eb ths
    CALL_FROM_TB0(do_float_cvtw_d);
1561 5a5012ec ths
    DEBUG_FPU_STATE();
1562 8f6f6026 ths
    FORCE_RET();
1563 5a5012ec ths
}
1564 5a5012ec ths
1565 5a5012ec ths
FLOAT_OP(pll, ps)
1566 5a5012ec ths
{
1567 5a5012ec ths
    DT2 = ((uint64_t)WT0 << 32) | WT1;
1568 5a5012ec ths
    DEBUG_FPU_STATE();
1569 8f6f6026 ths
    FORCE_RET();
1570 5a5012ec ths
}
1571 5a5012ec ths
FLOAT_OP(plu, ps)
1572 5a5012ec ths
{
1573 5a5012ec ths
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
1574 5a5012ec ths
    DEBUG_FPU_STATE();
1575 8f6f6026 ths
    FORCE_RET();
1576 5a5012ec ths
}
1577 5a5012ec ths
FLOAT_OP(pul, ps)
1578 5a5012ec ths
{
1579 5a5012ec ths
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
1580 5a5012ec ths
    DEBUG_FPU_STATE();
1581 8f6f6026 ths
    FORCE_RET();
1582 5a5012ec ths
}
1583 5a5012ec ths
FLOAT_OP(puu, ps)
1584 5a5012ec ths
{
1585 5a5012ec ths
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1586 6ea83fed bellard
    DEBUG_FPU_STATE();
1587 8f6f6026 ths
    FORCE_RET();
1588 6ea83fed bellard
}
1589 6ea83fed bellard
1590 fd4a04eb ths
#define FLOAT_ROUNDOP(op, ttype, stype)                    \
1591 fd4a04eb ths
FLOAT_OP(op ## ttype, stype)                               \
1592 fd4a04eb ths
{                                                          \
1593 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
1594 fd4a04eb ths
    DEBUG_FPU_STATE();                                     \
1595 8f6f6026 ths
    FORCE_RET();                                           \
1596 6ea83fed bellard
}
1597 6ea83fed bellard
1598 fd4a04eb ths
FLOAT_ROUNDOP(round, l, d)
1599 fd4a04eb ths
FLOAT_ROUNDOP(round, l, s)
1600 fd4a04eb ths
FLOAT_ROUNDOP(round, w, d)
1601 fd4a04eb ths
FLOAT_ROUNDOP(round, w, s)
1602 6ea83fed bellard
1603 fd4a04eb ths
FLOAT_ROUNDOP(trunc, l, d)
1604 fd4a04eb ths
FLOAT_ROUNDOP(trunc, l, s)
1605 fd4a04eb ths
FLOAT_ROUNDOP(trunc, w, d)
1606 fd4a04eb ths
FLOAT_ROUNDOP(trunc, w, s)
1607 6ea83fed bellard
1608 fd4a04eb ths
FLOAT_ROUNDOP(ceil, l, d)
1609 fd4a04eb ths
FLOAT_ROUNDOP(ceil, l, s)
1610 fd4a04eb ths
FLOAT_ROUNDOP(ceil, w, d)
1611 fd4a04eb ths
FLOAT_ROUNDOP(ceil, w, s)
1612 fd4a04eb ths
1613 fd4a04eb ths
FLOAT_ROUNDOP(floor, l, d)
1614 fd4a04eb ths
FLOAT_ROUNDOP(floor, l, s)
1615 fd4a04eb ths
FLOAT_ROUNDOP(floor, w, d)
1616 fd4a04eb ths
FLOAT_ROUNDOP(floor, w, s)
1617 fd4a04eb ths
#undef FLOAR_ROUNDOP
1618 6ea83fed bellard
1619 5a5012ec ths
FLOAT_OP(movf, d)
1620 5a5012ec ths
{
1621 ead9360e ths
    if (!(env->fpu->fcr31 & PARAM1))
1622 5a5012ec ths
        DT2 = DT0;
1623 5a5012ec ths
    DEBUG_FPU_STATE();
1624 8f6f6026 ths
    FORCE_RET();
1625 5a5012ec ths
}
1626 5a5012ec ths
FLOAT_OP(movf, s)
1627 5a5012ec ths
{
1628 ead9360e ths
    if (!(env->fpu->fcr31 & PARAM1))
1629 5a5012ec ths
        WT2 = WT0;
1630 5a5012ec ths
    DEBUG_FPU_STATE();
1631 8f6f6026 ths
    FORCE_RET();
1632 5a5012ec ths
}
1633 5a5012ec ths
FLOAT_OP(movf, ps)
1634 5a5012ec ths
{
1635 e6bb7d7e ths
    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
1636 e6bb7d7e ths
    if (!(mask & 1))
1637 5a5012ec ths
        WT2 = WT0;
1638 e6bb7d7e ths
    if (!(mask & 2))
1639 5a5012ec ths
        WTH2 = WTH0;
1640 5a5012ec ths
    DEBUG_FPU_STATE();
1641 8f6f6026 ths
    FORCE_RET();
1642 5a5012ec ths
}
1643 5a5012ec ths
FLOAT_OP(movt, d)
1644 5a5012ec ths
{
1645 ead9360e ths
    if (env->fpu->fcr31 & PARAM1)
1646 5a5012ec ths
        DT2 = DT0;
1647 5a5012ec ths
    DEBUG_FPU_STATE();
1648 8f6f6026 ths
    FORCE_RET();
1649 5a5012ec ths
}
1650 5a5012ec ths
FLOAT_OP(movt, s)
1651 5a5012ec ths
{
1652 ead9360e ths
    if (env->fpu->fcr31 & PARAM1)
1653 5a5012ec ths
        WT2 = WT0;
1654 5a5012ec ths
    DEBUG_FPU_STATE();
1655 8f6f6026 ths
    FORCE_RET();
1656 5a5012ec ths
}
1657 5a5012ec ths
FLOAT_OP(movt, ps)
1658 5a5012ec ths
{
1659 e6bb7d7e ths
    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
1660 e6bb7d7e ths
    if (mask & 1)
1661 5a5012ec ths
        WT2 = WT0;
1662 e6bb7d7e ths
    if (mask & 2)
1663 5a5012ec ths
        WTH2 = WTH0;
1664 5a5012ec ths
    DEBUG_FPU_STATE();
1665 8f6f6026 ths
    FORCE_RET();
1666 5a5012ec ths
}
1667 5a5012ec ths
FLOAT_OP(movz, d)
1668 5a5012ec ths
{
1669 5a5012ec ths
    if (!T0)
1670 5a5012ec ths
        DT2 = DT0;
1671 5a5012ec ths
    DEBUG_FPU_STATE();
1672 8f6f6026 ths
    FORCE_RET();
1673 5a5012ec ths
}
1674 5a5012ec ths
FLOAT_OP(movz, s)
1675 5a5012ec ths
{
1676 5a5012ec ths
    if (!T0)
1677 5a5012ec ths
        WT2 = WT0;
1678 5a5012ec ths
    DEBUG_FPU_STATE();
1679 8f6f6026 ths
    FORCE_RET();
1680 5a5012ec ths
}
1681 5a5012ec ths
FLOAT_OP(movz, ps)
1682 5a5012ec ths
{
1683 5a5012ec ths
    if (!T0) {
1684 5a5012ec ths
        WT2 = WT0;
1685 5a5012ec ths
        WTH2 = WTH0;
1686 5a5012ec ths
    }
1687 5a5012ec ths
    DEBUG_FPU_STATE();
1688 8f6f6026 ths
    FORCE_RET();
1689 5a5012ec ths
}
1690 5a5012ec ths
FLOAT_OP(movn, d)
1691 5a5012ec ths
{
1692 5a5012ec ths
    if (T0)
1693 5a5012ec ths
        DT2 = DT0;
1694 5a5012ec ths
    DEBUG_FPU_STATE();
1695 8f6f6026 ths
    FORCE_RET();
1696 5a5012ec ths
}
1697 5a5012ec ths
FLOAT_OP(movn, s)
1698 5a5012ec ths
{
1699 5a5012ec ths
    if (T0)
1700 5a5012ec ths
        WT2 = WT0;
1701 5a5012ec ths
    DEBUG_FPU_STATE();
1702 8f6f6026 ths
    FORCE_RET();
1703 5a5012ec ths
}
1704 5a5012ec ths
FLOAT_OP(movn, ps)
1705 5a5012ec ths
{
1706 5a5012ec ths
    if (T0) {
1707 5a5012ec ths
        WT2 = WT0;
1708 5a5012ec ths
        WTH2 = WTH0;
1709 5a5012ec ths
    }
1710 5a5012ec ths
    DEBUG_FPU_STATE();
1711 8f6f6026 ths
    FORCE_RET();
1712 5a5012ec ths
}
1713 5a5012ec ths
1714 57fa1fb3 ths
/* operations calling helpers, for s, d and ps */
1715 8f6f6026 ths
#define FLOAT_HOP(name)   \
1716 6ea83fed bellard
FLOAT_OP(name, d)         \
1717 6ea83fed bellard
{                         \
1718 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
1719 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1720 8f6f6026 ths
    FORCE_RET();          \
1721 6ea83fed bellard
}                         \
1722 6ea83fed bellard
FLOAT_OP(name, s)         \
1723 6ea83fed bellard
{                         \
1724 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
1725 5a5012ec ths
    DEBUG_FPU_STATE();    \
1726 8f6f6026 ths
    FORCE_RET();          \
1727 5a5012ec ths
}                         \
1728 5a5012ec ths
FLOAT_OP(name, ps)        \
1729 5a5012ec ths
{                         \
1730 fd4a04eb ths
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
1731 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1732 8f6f6026 ths
    FORCE_RET();          \
1733 6ea83fed bellard
}
1734 57fa1fb3 ths
FLOAT_HOP(add)
1735 57fa1fb3 ths
FLOAT_HOP(sub)
1736 57fa1fb3 ths
FLOAT_HOP(mul)
1737 57fa1fb3 ths
FLOAT_HOP(div)
1738 57fa1fb3 ths
FLOAT_HOP(recip2)
1739 57fa1fb3 ths
FLOAT_HOP(rsqrt2)
1740 57fa1fb3 ths
FLOAT_HOP(rsqrt1)
1741 57fa1fb3 ths
FLOAT_HOP(recip1)
1742 57fa1fb3 ths
#undef FLOAT_HOP
1743 57fa1fb3 ths
1744 57fa1fb3 ths
/* operations calling helpers, for s and d */
1745 57fa1fb3 ths
#define FLOAT_HOP(name)   \
1746 57fa1fb3 ths
FLOAT_OP(name, d)         \
1747 57fa1fb3 ths
{                         \
1748 57fa1fb3 ths
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
1749 57fa1fb3 ths
    DEBUG_FPU_STATE();    \
1750 8f6f6026 ths
    FORCE_RET();          \
1751 57fa1fb3 ths
}                         \
1752 57fa1fb3 ths
FLOAT_OP(name, s)         \
1753 57fa1fb3 ths
{                         \
1754 57fa1fb3 ths
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
1755 57fa1fb3 ths
    DEBUG_FPU_STATE();    \
1756 8f6f6026 ths
    FORCE_RET();          \
1757 57fa1fb3 ths
}
1758 57fa1fb3 ths
FLOAT_HOP(rsqrt)
1759 57fa1fb3 ths
FLOAT_HOP(recip)
1760 57fa1fb3 ths
#undef FLOAT_HOP
1761 6ea83fed bellard
1762 57fa1fb3 ths
/* operations calling helpers, for ps */
1763 57fa1fb3 ths
#define FLOAT_HOP(name)   \
1764 57fa1fb3 ths
FLOAT_OP(name, ps)        \
1765 57fa1fb3 ths
{                         \
1766 57fa1fb3 ths
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
1767 57fa1fb3 ths
    DEBUG_FPU_STATE();    \
1768 8f6f6026 ths
    FORCE_RET();          \
1769 fbcc6828 ths
}
1770 57fa1fb3 ths
FLOAT_HOP(addr)
1771 57fa1fb3 ths
FLOAT_HOP(mulr)
1772 57fa1fb3 ths
#undef FLOAT_HOP
1773 fbcc6828 ths
1774 5a5012ec ths
/* ternary operations */
1775 5a5012ec ths
#define FLOAT_TERNOP(name1, name2) \
1776 5a5012ec ths
FLOAT_OP(name1 ## name2, d)        \
1777 5a5012ec ths
{                                  \
1778 ead9360e ths
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
1779 ead9360e ths
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
1780 5a5012ec ths
    DEBUG_FPU_STATE();             \
1781 8f6f6026 ths
    FORCE_RET();                   \
1782 5a5012ec ths
}                                  \
1783 5a5012ec ths
FLOAT_OP(name1 ## name2, s)        \
1784 5a5012ec ths
{                                  \
1785 ead9360e ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1786 ead9360e ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1787 5a5012ec ths
    DEBUG_FPU_STATE();             \
1788 8f6f6026 ths
    FORCE_RET();                   \
1789 5a5012ec ths
}                                  \
1790 5a5012ec ths
FLOAT_OP(name1 ## name2, ps)       \
1791 5a5012ec ths
{                                  \
1792 ead9360e ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1793 ead9360e ths
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
1794 ead9360e ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1795 ead9360e ths
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
1796 5a5012ec ths
    DEBUG_FPU_STATE();             \
1797 8f6f6026 ths
    FORCE_RET();                   \
1798 5a5012ec ths
}
1799 5a5012ec ths
FLOAT_TERNOP(mul, add)
1800 5a5012ec ths
FLOAT_TERNOP(mul, sub)
1801 5a5012ec ths
#undef FLOAT_TERNOP
1802 5a5012ec ths
1803 fbcc6828 ths
/* negated ternary operations */
1804 fbcc6828 ths
#define FLOAT_NTERNOP(name1, name2) \
1805 fbcc6828 ths
FLOAT_OP(n ## name1 ## name2, d)    \
1806 fbcc6828 ths
{                                   \
1807 ead9360e ths
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
1808 ead9360e ths
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
1809 5747c073 pbrook
    FDT2 = float64_chs(FDT2);       \
1810 fbcc6828 ths
    DEBUG_FPU_STATE();              \
1811 8f6f6026 ths
    FORCE_RET();                    \
1812 fbcc6828 ths
}                                   \
1813 fbcc6828 ths
FLOAT_OP(n ## name1 ## name2, s)    \
1814 fbcc6828 ths
{                                   \
1815 ead9360e ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1816 ead9360e ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1817 5747c073 pbrook
    FST2 = float32_chs(FST2);       \
1818 fbcc6828 ths
    DEBUG_FPU_STATE();              \
1819 8f6f6026 ths
    FORCE_RET();                    \
1820 fbcc6828 ths
}                                   \
1821 fbcc6828 ths
FLOAT_OP(n ## name1 ## name2, ps)   \
1822 fbcc6828 ths
{                                   \
1823 ead9360e ths
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1824 ead9360e ths
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
1825 ead9360e ths
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1826 ead9360e ths
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
1827 5747c073 pbrook
    FST2 = float32_chs(FST2);       \
1828 5747c073 pbrook
    FSTH2 = float32_chs(FSTH2);     \
1829 fbcc6828 ths
    DEBUG_FPU_STATE();              \
1830 8f6f6026 ths
    FORCE_RET();                    \
1831 fbcc6828 ths
}
1832 fbcc6828 ths
FLOAT_NTERNOP(mul, add)
1833 fbcc6828 ths
FLOAT_NTERNOP(mul, sub)
1834 fbcc6828 ths
#undef FLOAT_NTERNOP
1835 fbcc6828 ths
1836 6ea83fed bellard
/* unary operations, modifying fp status  */
1837 6ea83fed bellard
#define FLOAT_UNOP(name)  \
1838 6ea83fed bellard
FLOAT_OP(name, d)         \
1839 6ea83fed bellard
{                         \
1840 8f6f6026 ths
    FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
1841 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1842 8f6f6026 ths
    FORCE_RET();          \
1843 6ea83fed bellard
}                         \
1844 6ea83fed bellard
FLOAT_OP(name, s)         \
1845 6ea83fed bellard
{                         \
1846 8f6f6026 ths
    FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
1847 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1848 8f6f6026 ths
    FORCE_RET();          \
1849 6ea83fed bellard
}
1850 6ea83fed bellard
FLOAT_UNOP(sqrt)
1851 6ea83fed bellard
#undef FLOAT_UNOP
1852 6ea83fed bellard
1853 6ea83fed bellard
/* unary operations, not modifying fp status  */
1854 6ea83fed bellard
#define FLOAT_UNOP(name)  \
1855 6ea83fed bellard
FLOAT_OP(name, d)         \
1856 6ea83fed bellard
{                         \
1857 6ea83fed bellard
    FDT2 = float64_ ## name(FDT0);   \
1858 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1859 8f6f6026 ths
    FORCE_RET();          \
1860 6ea83fed bellard
}                         \
1861 6ea83fed bellard
FLOAT_OP(name, s)         \
1862 6ea83fed bellard
{                         \
1863 6ea83fed bellard
    FST2 = float32_ ## name(FST0);   \
1864 6ea83fed bellard
    DEBUG_FPU_STATE();    \
1865 8f6f6026 ths
    FORCE_RET();          \
1866 5a5012ec ths
}                         \
1867 5a5012ec ths
FLOAT_OP(name, ps)        \
1868 5a5012ec ths
{                         \
1869 5a5012ec ths
    FST2 = float32_ ## name(FST0);   \
1870 5a5012ec ths
    FSTH2 = float32_ ## name(FSTH0); \
1871 5a5012ec ths
    DEBUG_FPU_STATE();    \
1872 8f6f6026 ths
    FORCE_RET();          \
1873 6ea83fed bellard
}
1874 6ea83fed bellard
FLOAT_UNOP(abs)
1875 6ea83fed bellard
FLOAT_UNOP(chs)
1876 6ea83fed bellard
#undef FLOAT_UNOP
1877 6ea83fed bellard
1878 6ea83fed bellard
FLOAT_OP(mov, d)
1879 6ea83fed bellard
{
1880 6ea83fed bellard
    FDT2 = FDT0;
1881 6ea83fed bellard
    DEBUG_FPU_STATE();
1882 8f6f6026 ths
    FORCE_RET();
1883 6ea83fed bellard
}
1884 6ea83fed bellard
FLOAT_OP(mov, s)
1885 6ea83fed bellard
{
1886 6ea83fed bellard
    FST2 = FST0;
1887 6ea83fed bellard
    DEBUG_FPU_STATE();
1888 8f6f6026 ths
    FORCE_RET();
1889 6ea83fed bellard
}
1890 5a5012ec ths
FLOAT_OP(mov, ps)
1891 5a5012ec ths
{
1892 5a5012ec ths
    FST2 = FST0;
1893 5a5012ec ths
    FSTH2 = FSTH0;
1894 5a5012ec ths
    DEBUG_FPU_STATE();
1895 8f6f6026 ths
    FORCE_RET();
1896 5a5012ec ths
}
1897 5a5012ec ths
FLOAT_OP(alnv, ps)
1898 5a5012ec ths
{
1899 5a5012ec ths
    switch (T0 & 0x7) {
1900 5a5012ec ths
    case 0:
1901 5a5012ec ths
        FST2 = FST0;
1902 5a5012ec ths
        FSTH2 = FSTH0;
1903 5a5012ec ths
        break;
1904 5a5012ec ths
    case 4:
1905 5a5012ec ths
#ifdef TARGET_WORDS_BIGENDIAN
1906 5a5012ec ths
        FSTH2 = FST0;
1907 5a5012ec ths
        FST2 = FSTH1;
1908 5a5012ec ths
#else
1909 5a5012ec ths
        FSTH2 = FST1;
1910 5a5012ec ths
        FST2 = FSTH0;
1911 5a5012ec ths
#endif
1912 5a5012ec ths
        break;
1913 5a5012ec ths
    default: /* unpredictable */
1914 5a5012ec ths
        break;
1915 5a5012ec ths
    }
1916 5a5012ec ths
    DEBUG_FPU_STATE();
1917 8f6f6026 ths
    FORCE_RET();
1918 5a5012ec ths
}
1919 6ea83fed bellard
1920 6ea83fed bellard
#ifdef CONFIG_SOFTFLOAT
1921 6ea83fed bellard
#define clear_invalid() do {                                \
1922 ead9360e ths
    int flags = get_float_exception_flags(&env->fpu->fp_status); \
1923 6ea83fed bellard
    flags &= ~float_flag_invalid;                           \
1924 8f6f6026 ths
    set_float_exception_flags(flags, &env->fpu->fp_status); \
1925 6ea83fed bellard
} while(0)
1926 6ea83fed bellard
#else
1927 6ea83fed bellard
#define clear_invalid() do { } while(0)
1928 6ea83fed bellard
#endif
1929 6ea83fed bellard
1930 6ea83fed bellard
extern void dump_fpu_s(CPUState *env);
1931 6ea83fed bellard
1932 fd4a04eb ths
#define CMP_OP(fmt, op)                                \
1933 fd4a04eb ths
void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
1934 fd4a04eb ths
{                                                      \
1935 fd4a04eb ths
    CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
1936 fd4a04eb ths
    DEBUG_FPU_STATE();                                 \
1937 8f6f6026 ths
    FORCE_RET();                                       \
1938 fd4a04eb ths
}                                                      \
1939 fd4a04eb ths
void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
1940 fd4a04eb ths
{                                                      \
1941 fd4a04eb ths
    CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
1942 fd4a04eb ths
    DEBUG_FPU_STATE();                                 \
1943 8f6f6026 ths
    FORCE_RET();                                       \
1944 fd4a04eb ths
}
1945 fd4a04eb ths
#define CMP_OPS(op)   \
1946 fd4a04eb ths
CMP_OP(d, op)         \
1947 fd4a04eb ths
CMP_OP(s, op)         \
1948 fd4a04eb ths
CMP_OP(ps, op)
1949 fd4a04eb ths
1950 fd4a04eb ths
CMP_OPS(f)
1951 fd4a04eb ths
CMP_OPS(un)
1952 fd4a04eb ths
CMP_OPS(eq)
1953 fd4a04eb ths
CMP_OPS(ueq)
1954 fd4a04eb ths
CMP_OPS(olt)
1955 fd4a04eb ths
CMP_OPS(ult)
1956 fd4a04eb ths
CMP_OPS(ole)
1957 fd4a04eb ths
CMP_OPS(ule)
1958 fd4a04eb ths
CMP_OPS(sf)
1959 fd4a04eb ths
CMP_OPS(ngle)
1960 fd4a04eb ths
CMP_OPS(seq)
1961 fd4a04eb ths
CMP_OPS(ngl)
1962 fd4a04eb ths
CMP_OPS(lt)
1963 fd4a04eb ths
CMP_OPS(nge)
1964 fd4a04eb ths
CMP_OPS(le)
1965 fd4a04eb ths
CMP_OPS(ngt)
1966 fd4a04eb ths
#undef CMP_OPS
1967 fd4a04eb ths
#undef CMP_OP
1968 6ea83fed bellard
1969 6ea83fed bellard
void op_bc1f (void)
1970 6ea83fed bellard
{
1971 ead9360e ths
    T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
1972 5a5012ec ths
    DEBUG_FPU_STATE();
1973 8f6f6026 ths
    FORCE_RET();
1974 5a5012ec ths
}
1975 fd4a04eb ths
void op_bc1any2f (void)
1976 5a5012ec ths
{
1977 ead9360e ths
    T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
1978 5a5012ec ths
    DEBUG_FPU_STATE();
1979 8f6f6026 ths
    FORCE_RET();
1980 5a5012ec ths
}
1981 fd4a04eb ths
void op_bc1any4f (void)
1982 5a5012ec ths
{
1983 ead9360e ths
    T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
1984 6ea83fed bellard
    DEBUG_FPU_STATE();
1985 8f6f6026 ths
    FORCE_RET();
1986 6ea83fed bellard
}
1987 6ea83fed bellard
1988 6ea83fed bellard
void op_bc1t (void)
1989 6ea83fed bellard
{
1990 ead9360e ths
    T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
1991 5a5012ec ths
    DEBUG_FPU_STATE();
1992 8f6f6026 ths
    FORCE_RET();
1993 5a5012ec ths
}
1994 fd4a04eb ths
void op_bc1any2t (void)
1995 5a5012ec ths
{
1996 ead9360e ths
    T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
1997 5a5012ec ths
    DEBUG_FPU_STATE();
1998 8f6f6026 ths
    FORCE_RET();
1999 5a5012ec ths
}
2000 fd4a04eb ths
void op_bc1any4t (void)
2001 5a5012ec ths
{
2002 ead9360e ths
    T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2003 6ea83fed bellard
    DEBUG_FPU_STATE();
2004 8f6f6026 ths
    FORCE_RET();
2005 6ea83fed bellard
}
2006 6ea83fed bellard
2007 6af0bf9c bellard
void op_tlbwi (void)
2008 6af0bf9c bellard
{
2009 ead9360e ths
    CALL_FROM_TB0(env->tlb->do_tlbwi);
2010 8f6f6026 ths
    FORCE_RET();
2011 6af0bf9c bellard
}
2012 6af0bf9c bellard
2013 6af0bf9c bellard
void op_tlbwr (void)
2014 6af0bf9c bellard
{
2015 ead9360e ths
    CALL_FROM_TB0(env->tlb->do_tlbwr);
2016 8f6f6026 ths
    FORCE_RET();
2017 6af0bf9c bellard
}
2018 6af0bf9c bellard
2019 6af0bf9c bellard
void op_tlbp (void)
2020 6af0bf9c bellard
{
2021 ead9360e ths
    CALL_FROM_TB0(env->tlb->do_tlbp);
2022 8f6f6026 ths
    FORCE_RET();
2023 6af0bf9c bellard
}
2024 6af0bf9c bellard
2025 6af0bf9c bellard
void op_tlbr (void)
2026 6af0bf9c bellard
{
2027 ead9360e ths
    CALL_FROM_TB0(env->tlb->do_tlbr);
2028 8f6f6026 ths
    FORCE_RET();
2029 6af0bf9c bellard
}
2030 6af0bf9c bellard
2031 6af0bf9c bellard
/* Specials */
2032 6f5b89a0 ths
#if defined (CONFIG_USER_ONLY)
2033 6f5b89a0 ths
void op_tls_value (void)
2034 6f5b89a0 ths
{
2035 5a5012ec ths
    T0 = env->tls_value;
2036 6f5b89a0 ths
}
2037 6f5b89a0 ths
#endif
2038 6f5b89a0 ths
2039 6af0bf9c bellard
void op_pmon (void)
2040 6af0bf9c bellard
{
2041 6af0bf9c bellard
    CALL_FROM_TB1(do_pmon, PARAM1);
2042 8f6f6026 ths
    FORCE_RET();
2043 7a387fff ths
}
2044 7a387fff ths
2045 7a387fff ths
void op_di (void)
2046 7a387fff ths
{
2047 7a387fff ths
    T0 = env->CP0_Status;
2048 4de9b249 ths
    env->CP0_Status = T0 & ~(1 << CP0St_IE);
2049 4de9b249 ths
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2050 8f6f6026 ths
    FORCE_RET();
2051 7a387fff ths
}
2052 7a387fff ths
2053 7a387fff ths
void op_ei (void)
2054 7a387fff ths
{
2055 7a387fff ths
    T0 = env->CP0_Status;
2056 4de9b249 ths
    env->CP0_Status = T0 | (1 << CP0St_IE);
2057 4de9b249 ths
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2058 8f6f6026 ths
    FORCE_RET();
2059 6af0bf9c bellard
}
2060 6af0bf9c bellard
2061 6af0bf9c bellard
void op_trap (void)
2062 6af0bf9c bellard
{
2063 6af0bf9c bellard
    if (T0) {
2064 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2065 6af0bf9c bellard
    }
2066 8f6f6026 ths
    FORCE_RET();
2067 6af0bf9c bellard
}
2068 6af0bf9c bellard
2069 4ad40f36 bellard
void op_debug (void)
2070 4ad40f36 bellard
{
2071 7a387fff ths
    CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2072 8f6f6026 ths
    FORCE_RET();
2073 4ad40f36 bellard
}
2074 4ad40f36 bellard
2075 f41c52f1 ths
void debug_pre_eret (void);
2076 f41c52f1 ths
void debug_post_eret (void);
2077 6af0bf9c bellard
void op_eret (void)
2078 6af0bf9c bellard
{
2079 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2080 f41c52f1 ths
        CALL_FROM_TB0(debug_pre_eret);
2081 24c7b0e3 ths
    if (env->CP0_Status & (1 << CP0St_ERL)) {
2082 ead9360e ths
        env->PC[env->current_tc] = env->CP0_ErrorEPC;
2083 24c7b0e3 ths
        env->CP0_Status &= ~(1 << CP0St_ERL);
2084 51e11d9e bellard
    } else {
2085 ead9360e ths
        env->PC[env->current_tc] = env->CP0_EPC;
2086 24c7b0e3 ths
        env->CP0_Status &= ~(1 << CP0St_EXL);
2087 51e11d9e bellard
    }
2088 08fa4bab ths
    CALL_FROM_TB1(compute_hflags, env);
2089 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2090 f41c52f1 ths
        CALL_FROM_TB0(debug_post_eret);
2091 6af0bf9c bellard
    env->CP0_LLAddr = 1;
2092 8f6f6026 ths
    FORCE_RET();
2093 6af0bf9c bellard
}
2094 6af0bf9c bellard
2095 6af0bf9c bellard
void op_deret (void)
2096 6af0bf9c bellard
{
2097 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2098 f41c52f1 ths
        CALL_FROM_TB0(debug_pre_eret);
2099 ead9360e ths
    env->PC[env->current_tc] = env->CP0_DEPC;
2100 08fa4bab ths
    env->hflags &= MIPS_HFLAG_DM;
2101 08fa4bab ths
    CALL_FROM_TB1(compute_hflags, env);
2102 f41c52f1 ths
    if (loglevel & CPU_LOG_EXEC)
2103 f41c52f1 ths
        CALL_FROM_TB0(debug_post_eret);
2104 24c7b0e3 ths
    env->CP0_LLAddr = 1;
2105 8f6f6026 ths
    FORCE_RET();
2106 7a387fff ths
}
2107 7a387fff ths
2108 7a387fff ths
void op_rdhwr_cpunum(void)
2109 7a387fff ths
{
2110 387a8fe5 ths
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2111 387a8fe5 ths
        (env->CP0_HWREna & (1 << 0)))
2112 1579a72e ths
        T0 = env->CP0_EBase & 0x3ff;
2113 7a387fff ths
    else
2114 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2115 8f6f6026 ths
    FORCE_RET();
2116 7a387fff ths
}
2117 7a387fff ths
2118 7a387fff ths
void op_rdhwr_synci_step(void)
2119 7a387fff ths
{
2120 387a8fe5 ths
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2121 387a8fe5 ths
        (env->CP0_HWREna & (1 << 1)))
2122 1579a72e ths
        T0 = env->SYNCI_Step;
2123 7a387fff ths
    else
2124 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2125 8f6f6026 ths
    FORCE_RET();
2126 7a387fff ths
}
2127 7a387fff ths
2128 7a387fff ths
void op_rdhwr_cc(void)
2129 7a387fff ths
{
2130 387a8fe5 ths
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2131 387a8fe5 ths
        (env->CP0_HWREna & (1 << 2)))
2132 1579a72e ths
        T0 = env->CP0_Count;
2133 7a387fff ths
    else
2134 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2135 8f6f6026 ths
    FORCE_RET();
2136 7a387fff ths
}
2137 7a387fff ths
2138 7a387fff ths
void op_rdhwr_ccres(void)
2139 7a387fff ths
{
2140 387a8fe5 ths
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2141 387a8fe5 ths
        (env->CP0_HWREna & (1 << 3)))
2142 1579a72e ths
        T0 = env->CCRes;
2143 7a387fff ths
    else
2144 1579a72e ths
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2145 8f6f6026 ths
    FORCE_RET();
2146 1579a72e ths
}
2147 1579a72e ths
2148 6af0bf9c bellard
void op_save_state (void)
2149 6af0bf9c bellard
{
2150 6af0bf9c bellard
    env->hflags = PARAM1;
2151 8f6f6026 ths
    FORCE_RET();
2152 6af0bf9c bellard
}
2153 6af0bf9c bellard
2154 4ad40f36 bellard
void op_wait (void)
2155 4ad40f36 bellard
{
2156 4ad40f36 bellard
    env->halted = 1;
2157 4ad40f36 bellard
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2158 8f6f6026 ths
    FORCE_RET();
2159 7a387fff ths
}
2160 7a387fff ths
2161 7a387fff ths
/* Bitfield operations. */
2162 7a387fff ths
void op_ext(void)
2163 7a387fff ths
{
2164 7a387fff ths
    unsigned int pos = PARAM1;
2165 7a387fff ths
    unsigned int size = PARAM2;
2166 7a387fff ths
2167 c6d6dd7c ths
    T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
2168 8f6f6026 ths
    FORCE_RET();
2169 7a387fff ths
}
2170 7a387fff ths
2171 7a387fff ths
void op_ins(void)
2172 7a387fff ths
{
2173 7a387fff ths
    unsigned int pos = PARAM1;
2174 7a387fff ths
    unsigned int size = PARAM2;
2175 f757d6ff ths
    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2176 7a387fff ths
2177 c6d6dd7c ths
    T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
2178 8f6f6026 ths
    FORCE_RET();
2179 7a387fff ths
}
2180 7a387fff ths
2181 7a387fff ths
void op_wsbh(void)
2182 7a387fff ths
{
2183 c6d6dd7c ths
    T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
2184 8f6f6026 ths
    FORCE_RET();
2185 7a387fff ths
}
2186 7a387fff ths
2187 d26bc211 ths
#if defined(TARGET_MIPS64)
2188 c570fd16 ths
void op_dext(void)
2189 c570fd16 ths
{
2190 c570fd16 ths
    unsigned int pos = PARAM1;
2191 c570fd16 ths
    unsigned int size = PARAM2;
2192 c570fd16 ths
2193 c6d6dd7c ths
    T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
2194 8f6f6026 ths
    FORCE_RET();
2195 c570fd16 ths
}
2196 c570fd16 ths
2197 c570fd16 ths
void op_dins(void)
2198 c570fd16 ths
{
2199 c570fd16 ths
    unsigned int pos = PARAM1;
2200 c570fd16 ths
    unsigned int size = PARAM2;
2201 c6d6dd7c ths
    target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
2202 c570fd16 ths
2203 171b31e7 ths
    T0 = (T0 & ~mask) | ((T1 << pos) & mask);
2204 8f6f6026 ths
    FORCE_RET();
2205 c570fd16 ths
}
2206 c570fd16 ths
2207 7a387fff ths
void op_dsbh(void)
2208 7a387fff ths
{
2209 7a387fff ths
    T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2210 8f6f6026 ths
    FORCE_RET();
2211 7a387fff ths
}
2212 7a387fff ths
2213 7a387fff ths
void op_dshd(void)
2214 7a387fff ths
{
2215 c6d6dd7c ths
    T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2216 c6d6dd7c ths
    T0 = (T1 << 32) | (T1 >> 32);
2217 8f6f6026 ths
    FORCE_RET();
2218 7a387fff ths
}
2219 c570fd16 ths
#endif