]>
Commit | Line | Data |
---|---|---|
fdf9b3e8 FB |
1 | /* |
2 | * SH4 emulation | |
5fafdf24 | 3 | * |
fdf9b3e8 FB |
4 | * Copyright (c) 2005 Samuel Tardieu |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | */ | |
20 | #include "exec.h" | |
21 | ||
22 | static inline void set_flag(uint32_t flag) | |
23 | { | |
24 | env->flags |= flag; | |
25 | } | |
26 | ||
27 | static inline void clr_flag(uint32_t flag) | |
28 | { | |
29 | env->flags &= ~flag; | |
30 | } | |
31 | ||
32 | static inline void set_t(void) | |
33 | { | |
34 | env->sr |= SR_T; | |
35 | } | |
36 | ||
37 | static inline void clr_t(void) | |
38 | { | |
39 | env->sr &= ~SR_T; | |
40 | } | |
41 | ||
42 | static inline void cond_t(int cond) | |
43 | { | |
44 | if (cond) | |
45 | set_t(); | |
46 | else | |
47 | clr_t(); | |
48 | } | |
49 | ||
50 | void OPPROTO op_movl_imm_T0(void) | |
51 | { | |
52 | T0 = (uint32_t) PARAM1; | |
53 | RETURN(); | |
54 | } | |
55 | ||
56 | void OPPROTO op_movl_imm_T1(void) | |
57 | { | |
58 | T0 = (uint32_t) PARAM1; | |
59 | RETURN(); | |
60 | } | |
61 | ||
62 | void OPPROTO op_movl_imm_T2(void) | |
63 | { | |
64 | T0 = (uint32_t) PARAM1; | |
65 | RETURN(); | |
66 | } | |
67 | ||
68 | void OPPROTO op_cmp_eq_imm_T0(void) | |
69 | { | |
70 | cond_t((int32_t) T0 == (int32_t) PARAM1); | |
71 | RETURN(); | |
72 | } | |
73 | ||
74 | void OPPROTO op_cmd_eq_T0_T1(void) | |
75 | { | |
76 | cond_t(T0 == T1); | |
77 | RETURN(); | |
78 | } | |
79 | ||
80 | void OPPROTO op_cmd_hs_T0_T1(void) | |
81 | { | |
82 | cond_t((uint32_t) T0 <= (uint32_t) T1); | |
83 | RETURN(); | |
84 | } | |
85 | ||
86 | void OPPROTO op_cmd_ge_T0_T1(void) | |
87 | { | |
88 | cond_t((int32_t) T0 <= (int32_t) T1); | |
89 | RETURN(); | |
90 | } | |
91 | ||
92 | void OPPROTO op_cmd_hi_T0_T1(void) | |
93 | { | |
94 | cond_t((uint32_t) T0 < (uint32_t) T1); | |
95 | RETURN(); | |
96 | } | |
97 | ||
98 | void OPPROTO op_cmd_gt_T0_T1(void) | |
99 | { | |
100 | cond_t((int32_t) T0 < (int32_t) T1); | |
101 | RETURN(); | |
102 | } | |
103 | ||
104 | void OPPROTO op_not_T0(void) | |
105 | { | |
106 | T0 = ~T0; | |
107 | RETURN(); | |
108 | } | |
109 | ||
110 | void OPPROTO op_bf_s(void) | |
111 | { | |
fdf9b3e8 | 112 | env->delayed_pc = PARAM1; |
9c2a9ea1 | 113 | set_flag(DELAY_SLOT_CONDITIONAL | ((~env->sr) & SR_T)); |
fdf9b3e8 FB |
114 | RETURN(); |
115 | } | |
116 | ||
117 | void OPPROTO op_bt_s(void) | |
118 | { | |
fdf9b3e8 | 119 | env->delayed_pc = PARAM1; |
9c2a9ea1 | 120 | set_flag(DELAY_SLOT_CONDITIONAL | (env->sr & SR_T)); |
fdf9b3e8 FB |
121 | RETURN(); |
122 | } | |
123 | ||
124 | void OPPROTO op_bra(void) | |
125 | { | |
126 | env->delayed_pc = PARAM1; | |
127 | set_flag(DELAY_SLOT); | |
128 | RETURN(); | |
129 | } | |
130 | ||
131 | void OPPROTO op_braf_T0(void) | |
132 | { | |
133 | env->delayed_pc = PARAM1 + T0; | |
134 | set_flag(DELAY_SLOT); | |
135 | RETURN(); | |
136 | } | |
137 | ||
138 | void OPPROTO op_bsr(void) | |
139 | { | |
140 | env->pr = PARAM1; | |
141 | env->delayed_pc = PARAM2; | |
142 | set_flag(DELAY_SLOT); | |
143 | RETURN(); | |
144 | } | |
145 | ||
146 | void OPPROTO op_bsrf_T0(void) | |
147 | { | |
148 | env->pr = PARAM1; | |
149 | env->delayed_pc = PARAM1 + T0; | |
150 | set_flag(DELAY_SLOT); | |
151 | RETURN(); | |
152 | } | |
153 | ||
154 | void OPPROTO op_jsr_T0(void) | |
155 | { | |
156 | env->pr = PARAM1; | |
157 | env->delayed_pc = T0; | |
158 | set_flag(DELAY_SLOT); | |
159 | RETURN(); | |
160 | } | |
161 | ||
162 | void OPPROTO op_rts(void) | |
163 | { | |
164 | env->delayed_pc = env->pr; | |
165 | set_flag(DELAY_SLOT); | |
166 | RETURN(); | |
167 | } | |
168 | ||
169 | void OPPROTO op_clr_delay_slot(void) | |
170 | { | |
171 | clr_flag(DELAY_SLOT); | |
172 | RETURN(); | |
173 | } | |
174 | ||
175 | void OPPROTO op_clr_delay_slot_conditional(void) | |
176 | { | |
177 | clr_flag(DELAY_SLOT_CONDITIONAL); | |
178 | RETURN(); | |
179 | } | |
180 | ||
181 | void OPPROTO op_exit_tb(void) | |
182 | { | |
183 | EXIT_TB(); | |
184 | RETURN(); | |
185 | } | |
186 | ||
187 | void OPPROTO op_addl_imm_T0(void) | |
188 | { | |
189 | T0 += PARAM1; | |
190 | RETURN(); | |
191 | } | |
192 | ||
193 | void OPPROTO op_addl_imm_T1(void) | |
194 | { | |
195 | T1 += PARAM1; | |
196 | RETURN(); | |
197 | } | |
198 | ||
199 | void OPPROTO op_clrmac(void) | |
200 | { | |
201 | env->mach = env->macl = 0; | |
202 | RETURN(); | |
203 | } | |
204 | ||
205 | void OPPROTO op_clrs(void) | |
206 | { | |
207 | env->sr &= ~SR_S; | |
208 | RETURN(); | |
209 | } | |
210 | ||
211 | void OPPROTO op_clrt(void) | |
212 | { | |
213 | env->sr &= ~SR_T; | |
214 | RETURN(); | |
215 | } | |
216 | ||
217 | void OPPROTO op_sets(void) | |
218 | { | |
219 | env->sr |= SR_S; | |
220 | RETURN(); | |
221 | } | |
222 | ||
223 | void OPPROTO op_sett(void) | |
224 | { | |
225 | env->sr |= SR_T; | |
226 | RETURN(); | |
227 | } | |
228 | ||
eda9b09b FB |
229 | void OPPROTO op_frchg(void) |
230 | { | |
231 | env->fpscr ^= FPSCR_FR; | |
232 | RETURN(); | |
233 | } | |
234 | ||
235 | void OPPROTO op_fschg(void) | |
236 | { | |
237 | env->fpscr ^= FPSCR_SZ; | |
238 | RETURN(); | |
239 | } | |
240 | ||
fdf9b3e8 FB |
241 | void OPPROTO op_rte(void) |
242 | { | |
243 | env->sr = env->ssr; | |
244 | env->delayed_pc = env->spc; | |
245 | set_flag(DELAY_SLOT); | |
246 | RETURN(); | |
247 | } | |
248 | ||
249 | void OPPROTO op_swapb_T0(void) | |
250 | { | |
251 | T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff); | |
252 | RETURN(); | |
253 | } | |
254 | ||
255 | void OPPROTO op_swapw_T0(void) | |
256 | { | |
257 | T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff); | |
258 | RETURN(); | |
259 | } | |
260 | ||
261 | void OPPROTO op_xtrct_T0_T1(void) | |
262 | { | |
263 | T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff); | |
264 | RETURN(); | |
265 | } | |
266 | ||
267 | void OPPROTO op_addc_T0_T1(void) | |
268 | { | |
269 | helper_addc_T0_T1(); | |
270 | RETURN(); | |
271 | } | |
272 | ||
273 | void OPPROTO op_addv_T0_T1(void) | |
274 | { | |
275 | helper_addv_T0_T1(); | |
276 | RETURN(); | |
277 | } | |
278 | ||
279 | void OPPROTO op_cmp_eq_T0_T1(void) | |
280 | { | |
281 | cond_t(T1 == T0); | |
282 | RETURN(); | |
283 | } | |
284 | ||
285 | void OPPROTO op_cmp_ge_T0_T1(void) | |
286 | { | |
287 | cond_t((int32_t) T1 >= (int32_t) T0); | |
288 | RETURN(); | |
289 | } | |
290 | ||
291 | void OPPROTO op_cmp_gt_T0_T1(void) | |
292 | { | |
293 | cond_t((int32_t) T1 > (int32_t) T0); | |
294 | RETURN(); | |
295 | } | |
296 | ||
297 | void OPPROTO op_cmp_hi_T0_T1(void) | |
298 | { | |
299 | cond_t((uint32_t) T1 > (uint32_t) T0); | |
300 | RETURN(); | |
301 | } | |
302 | ||
303 | void OPPROTO op_cmp_hs_T0_T1(void) | |
304 | { | |
305 | cond_t((uint32_t) T1 >= (uint32_t) T0); | |
306 | RETURN(); | |
307 | } | |
308 | ||
309 | void OPPROTO op_cmp_str_T0_T1(void) | |
310 | { | |
311 | cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) || | |
312 | (T0 & 0x0000ff00) == (T1 & 0x0000ff00) || | |
313 | (T0 & 0x00ff0000) == (T1 & 0x00ff0000) || | |
314 | (T0 & 0xff000000) == (T1 & 0xff000000)); | |
315 | RETURN(); | |
316 | } | |
317 | ||
318 | void OPPROTO op_tst_T0_T1(void) | |
319 | { | |
320 | cond_t((T1 & T0) == 0); | |
321 | RETURN(); | |
322 | } | |
323 | ||
324 | void OPPROTO op_div0s_T0_T1(void) | |
325 | { | |
326 | if (T1 & 0x80000000) | |
327 | env->sr |= SR_Q; | |
328 | else | |
329 | env->sr &= ~SR_Q; | |
330 | if (T0 & 0x80000000) | |
331 | env->sr |= SR_M; | |
332 | else | |
333 | env->sr &= ~SR_M; | |
334 | cond_t((T1 ^ T0) & 0x80000000); | |
335 | RETURN(); | |
336 | } | |
337 | ||
338 | void OPPROTO op_div0u(void) | |
339 | { | |
340 | env->sr &= ~(SR_M | SR_Q | SR_T); | |
341 | RETURN(); | |
342 | } | |
343 | ||
344 | void OPPROTO op_div1_T0_T1(void) | |
345 | { | |
346 | helper_div1_T0_T1(); | |
347 | RETURN(); | |
348 | } | |
349 | ||
350 | void OPPROTO op_dmulsl_T0_T1(void) | |
351 | { | |
352 | helper_dmulsl_T0_T1(); | |
353 | RETURN(); | |
354 | } | |
355 | ||
356 | void OPPROTO op_dmulul_T0_T1(void) | |
357 | { | |
358 | helper_dmulul_T0_T1(); | |
359 | RETURN(); | |
360 | } | |
361 | ||
362 | void OPPROTO op_macl_T0_T1(void) | |
363 | { | |
364 | helper_macl_T0_T1(); | |
365 | RETURN(); | |
366 | } | |
367 | ||
368 | void OPPROTO op_macw_T0_T1(void) | |
369 | { | |
370 | helper_macw_T0_T1(); | |
371 | RETURN(); | |
372 | } | |
373 | ||
374 | void OPPROTO op_mull_T0_T1(void) | |
375 | { | |
376 | env->macl = (T0 * T1) & 0xffffffff; | |
377 | RETURN(); | |
378 | } | |
379 | ||
380 | void OPPROTO op_mulsw_T0_T1(void) | |
381 | { | |
382 | env->macl = (int32_t) T0 *(int32_t) T1; | |
383 | RETURN(); | |
384 | } | |
385 | ||
386 | void OPPROTO op_muluw_T0_T1(void) | |
387 | { | |
388 | env->macl = (uint32_t) T0 *(uint32_t) T1; | |
389 | RETURN(); | |
390 | } | |
391 | ||
392 | void OPPROTO op_neg_T0(void) | |
393 | { | |
394 | T0 = -T0; | |
395 | RETURN(); | |
396 | } | |
397 | ||
398 | void OPPROTO op_negc_T0(void) | |
399 | { | |
400 | helper_negc_T0(); | |
401 | RETURN(); | |
402 | } | |
403 | ||
404 | void OPPROTO op_shad_T0_T1(void) | |
405 | { | |
406 | if ((T0 & 0x80000000) == 0) | |
407 | T1 <<= (T0 & 0x1f); | |
408 | else if ((T0 & 0x1f) == 0) | |
409 | T1 = 0; | |
410 | else | |
411 | T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1); | |
412 | RETURN(); | |
413 | } | |
414 | ||
415 | void OPPROTO op_shld_T0_T1(void) | |
416 | { | |
417 | if ((T0 & 0x80000000) == 0) | |
418 | T1 <<= (T0 & 0x1f); | |
419 | else if ((T0 & 0x1f) == 0) | |
420 | T1 = 0; | |
421 | else | |
422 | T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1); | |
423 | RETURN(); | |
424 | } | |
425 | ||
426 | void OPPROTO op_subc_T0_T1(void) | |
427 | { | |
428 | helper_subc_T0_T1(); | |
429 | RETURN(); | |
430 | } | |
431 | ||
432 | void OPPROTO op_subv_T0_T1(void) | |
433 | { | |
434 | helper_subv_T0_T1(); | |
435 | RETURN(); | |
436 | } | |
437 | ||
438 | void OPPROTO op_trapa(void) | |
439 | { | |
440 | env->tra = PARAM1 * 2; | |
441 | env->exception_index = 0x160; | |
442 | do_raise_exception(); | |
443 | RETURN(); | |
444 | } | |
445 | ||
446 | void OPPROTO op_cmp_pl_T0(void) | |
447 | { | |
448 | cond_t((int32_t) T0 > 0); | |
449 | RETURN(); | |
450 | } | |
451 | ||
452 | void OPPROTO op_cmp_pz_T0(void) | |
453 | { | |
454 | cond_t((int32_t) T0 >= 0); | |
455 | RETURN(); | |
456 | } | |
457 | ||
458 | void OPPROTO op_jmp_T0(void) | |
459 | { | |
460 | env->delayed_pc = T0; | |
461 | set_flag(DELAY_SLOT); | |
462 | RETURN(); | |
463 | } | |
464 | ||
465 | void OPPROTO op_movl_rN_rN(void) | |
466 | { | |
467 | env->gregs[PARAM2] = env->gregs[PARAM1]; | |
468 | RETURN(); | |
469 | } | |
470 | ||
471 | void OPPROTO op_ldcl_rMplus_rN_bank(void) | |
472 | { | |
473 | env->gregs[PARAM2] = env->gregs[PARAM1]; | |
474 | env->gregs[PARAM1] += 4; | |
475 | RETURN(); | |
476 | } | |
477 | ||
eda9b09b FB |
478 | void OPPROTO op_ldc_T0_sr(void) |
479 | { | |
480 | env->sr = T0 & 0x700083f3; | |
481 | RETURN(); | |
482 | } | |
483 | ||
484 | void OPPROTO op_stc_sr_T0(void) | |
485 | { | |
486 | T0 = env->sr; | |
487 | RETURN(); | |
488 | } | |
489 | ||
fdf9b3e8 FB |
490 | #define LDSTOPS(target,load,store) \ |
491 | void OPPROTO op_##load##_T0_##target (void) \ | |
492 | { env ->target = T0; RETURN(); \ | |
493 | } \ | |
494 | void OPPROTO op_##store##_##target##_T0 (void) \ | |
495 | { T0 = env->target; RETURN(); \ | |
496 | } \ | |
497 | ||
fdf9b3e8 FB |
498 | LDSTOPS(gbr, ldc, stc) |
499 | LDSTOPS(vbr, ldc, stc) | |
500 | LDSTOPS(ssr, ldc, stc) | |
501 | LDSTOPS(spc, ldc, stc) | |
502 | LDSTOPS(sgr, ldc, stc) | |
503 | LDSTOPS(dbr, ldc, stc) | |
504 | LDSTOPS(mach, lds, sts) | |
505 | LDSTOPS(macl, lds, sts) | |
506 | LDSTOPS(pr, lds, sts) | |
eda9b09b FB |
507 | LDSTOPS(fpul, lds, sts) |
508 | ||
509 | void OPPROTO op_lds_T0_fpscr(void) | |
510 | { | |
511 | env->fpscr = T0 & 0x003fffff; | |
ea6cf6be TS |
512 | env->fp_status.float_rounding_mode = T0 & 0x01 ? |
513 | float_round_to_zero : float_round_nearest_even; | |
514 | ||
eda9b09b FB |
515 | RETURN(); |
516 | } | |
517 | ||
518 | void OPPROTO op_sts_fpscr_T0(void) | |
519 | { | |
520 | T0 = env->fpscr & 0x003fffff; | |
521 | RETURN(); | |
522 | } | |
fdf9b3e8 FB |
523 | |
524 | void OPPROTO op_movt_rN(void) | |
525 | { | |
526 | env->gregs[PARAM1] = env->sr & SR_T; | |
527 | RETURN(); | |
528 | } | |
529 | ||
530 | void OPPROTO op_rotcl_Rn(void) | |
531 | { | |
532 | helper_rotcl(&env->gregs[PARAM1]); | |
533 | RETURN(); | |
534 | } | |
535 | ||
536 | void OPPROTO op_rotcr_Rn(void) | |
537 | { | |
538 | helper_rotcr(&env->gregs[PARAM1]); | |
539 | RETURN(); | |
540 | } | |
541 | ||
542 | void OPPROTO op_rotl_Rn(void) | |
543 | { | |
544 | cond_t(env->gregs[PARAM1] & 0x80000000); | |
545 | env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T); | |
546 | RETURN(); | |
547 | } | |
548 | ||
549 | void OPPROTO op_rotr_Rn(void) | |
550 | { | |
551 | cond_t(env->gregs[PARAM1] & 1); | |
552 | env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) | | |
553 | ((env->sr & SR_T) ? 0x80000000 : 0); | |
554 | RETURN(); | |
555 | } | |
556 | ||
557 | void OPPROTO op_shal_Rn(void) | |
558 | { | |
559 | cond_t(env->gregs[PARAM1] & 0x80000000); | |
560 | env->gregs[PARAM1] <<= 1; | |
561 | RETURN(); | |
562 | } | |
563 | ||
564 | void OPPROTO op_shar_Rn(void) | |
565 | { | |
566 | cond_t(env->gregs[PARAM1] & 1); | |
a5d251bd | 567 | env->gregs[PARAM1] >>= 1; |
fdf9b3e8 FB |
568 | RETURN(); |
569 | } | |
570 | ||
571 | void OPPROTO op_shlr_Rn(void) | |
572 | { | |
573 | cond_t(env->gregs[PARAM1] & 1); | |
a5d251bd | 574 | env->gregs[PARAM1] >>= 1; |
fdf9b3e8 FB |
575 | RETURN(); |
576 | } | |
577 | ||
578 | void OPPROTO op_shll2_Rn(void) | |
579 | { | |
580 | env->gregs[PARAM1] <<= 2; | |
581 | RETURN(); | |
582 | } | |
583 | ||
584 | void OPPROTO op_shll8_Rn(void) | |
585 | { | |
586 | env->gregs[PARAM1] <<= 8; | |
587 | RETURN(); | |
588 | } | |
589 | ||
590 | void OPPROTO op_shll16_Rn(void) | |
591 | { | |
592 | env->gregs[PARAM1] <<= 16; | |
593 | RETURN(); | |
594 | } | |
595 | ||
596 | void OPPROTO op_shlr2_Rn(void) | |
597 | { | |
a5d251bd | 598 | env->gregs[PARAM1] >>= 2; |
fdf9b3e8 FB |
599 | RETURN(); |
600 | } | |
601 | ||
602 | void OPPROTO op_shlr8_Rn(void) | |
603 | { | |
a5d251bd | 604 | env->gregs[PARAM1] >>= 8; |
fdf9b3e8 FB |
605 | RETURN(); |
606 | } | |
607 | ||
608 | void OPPROTO op_shlr16_Rn(void) | |
609 | { | |
a5d251bd | 610 | env->gregs[PARAM1] >>= 16; |
fdf9b3e8 FB |
611 | RETURN(); |
612 | } | |
613 | ||
614 | void OPPROTO op_tasb_rN(void) | |
615 | { | |
616 | cond_t(*(int8_t *) env->gregs[PARAM1] == 0); | |
617 | *(int8_t *) env->gregs[PARAM1] |= 0x80; | |
618 | RETURN(); | |
619 | } | |
620 | ||
621 | void OPPROTO op_movl_T0_rN(void) | |
622 | { | |
623 | env->gregs[PARAM1] = T0; | |
624 | RETURN(); | |
625 | } | |
626 | ||
627 | void OPPROTO op_movl_T1_rN(void) | |
628 | { | |
629 | env->gregs[PARAM1] = T1; | |
630 | RETURN(); | |
631 | } | |
632 | ||
633 | void OPPROTO op_movb_rN_T0(void) | |
634 | { | |
635 | T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff); | |
636 | RETURN(); | |
637 | } | |
638 | ||
639 | void OPPROTO op_movub_rN_T0(void) | |
640 | { | |
641 | T0 = env->gregs[PARAM1] & 0xff; | |
642 | RETURN(); | |
643 | } | |
644 | ||
645 | void OPPROTO op_movw_rN_T0(void) | |
646 | { | |
647 | T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff); | |
648 | RETURN(); | |
649 | } | |
650 | ||
651 | void OPPROTO op_movuw_rN_T0(void) | |
652 | { | |
653 | T0 = env->gregs[PARAM1] & 0xffff; | |
654 | RETURN(); | |
655 | } | |
656 | ||
657 | void OPPROTO op_movl_rN_T0(void) | |
658 | { | |
659 | T0 = env->gregs[PARAM1]; | |
660 | RETURN(); | |
661 | } | |
662 | ||
663 | void OPPROTO op_movb_rN_T1(void) | |
664 | { | |
665 | T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff); | |
666 | RETURN(); | |
667 | } | |
668 | ||
669 | void OPPROTO op_movub_rN_T1(void) | |
670 | { | |
671 | T1 = env->gregs[PARAM1] & 0xff; | |
672 | RETURN(); | |
673 | } | |
674 | ||
675 | void OPPROTO op_movw_rN_T1(void) | |
676 | { | |
677 | T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff); | |
678 | RETURN(); | |
679 | } | |
680 | ||
681 | void OPPROTO op_movuw_rN_T1(void) | |
682 | { | |
683 | T1 = env->gregs[PARAM1] & 0xffff; | |
684 | RETURN(); | |
685 | } | |
686 | ||
687 | void OPPROTO op_movl_rN_T1(void) | |
688 | { | |
689 | T1 = env->gregs[PARAM1]; | |
690 | RETURN(); | |
691 | } | |
692 | ||
693 | void OPPROTO op_movl_imm_rN(void) | |
694 | { | |
695 | env->gregs[PARAM2] = PARAM1; | |
696 | RETURN(); | |
697 | } | |
698 | ||
eda9b09b FB |
699 | void OPPROTO op_fmov_frN_FT0(void) |
700 | { | |
e04ea3dc | 701 | FT0 = env->fregs[PARAM1]; |
eda9b09b FB |
702 | RETURN(); |
703 | } | |
704 | ||
705 | void OPPROTO op_fmov_drN_DT0(void) | |
706 | { | |
e04ea3dc TS |
707 | CPU_DoubleU d; |
708 | ||
709 | d.l.upper = *(uint32_t *)&env->fregs[PARAM1]; | |
710 | d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1]; | |
711 | DT0 = d.d; | |
eda9b09b FB |
712 | RETURN(); |
713 | } | |
714 | ||
ea6cf6be TS |
715 | void OPPROTO op_fmov_frN_FT1(void) |
716 | { | |
e04ea3dc | 717 | FT1 = env->fregs[PARAM1]; |
ea6cf6be TS |
718 | RETURN(); |
719 | } | |
720 | ||
721 | void OPPROTO op_fmov_drN_DT1(void) | |
722 | { | |
e04ea3dc TS |
723 | CPU_DoubleU d; |
724 | ||
725 | d.l.upper = *(uint32_t *)&env->fregs[PARAM1]; | |
726 | d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1]; | |
727 | DT1 = d.d; | |
ea6cf6be TS |
728 | RETURN(); |
729 | } | |
730 | ||
eda9b09b FB |
731 | void OPPROTO op_fmov_FT0_frN(void) |
732 | { | |
e04ea3dc | 733 | env->fregs[PARAM1] = FT0; |
eda9b09b FB |
734 | RETURN(); |
735 | } | |
736 | ||
737 | void OPPROTO op_fmov_DT0_drN(void) | |
738 | { | |
e04ea3dc TS |
739 | CPU_DoubleU d; |
740 | ||
741 | d.d = DT0; | |
742 | *(uint32_t *)&env->fregs[PARAM1] = d.l.upper; | |
743 | *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower; | |
eda9b09b FB |
744 | RETURN(); |
745 | } | |
746 | ||
ea6cf6be TS |
747 | void OPPROTO op_fadd_FT(void) |
748 | { | |
749 | FT0 = float32_add(FT0, FT1, &env->fp_status); | |
750 | RETURN(); | |
751 | } | |
752 | ||
753 | void OPPROTO op_fadd_DT(void) | |
754 | { | |
755 | DT0 = float64_add(DT0, DT1, &env->fp_status); | |
756 | RETURN(); | |
757 | } | |
758 | ||
759 | void OPPROTO op_fsub_FT(void) | |
760 | { | |
761 | FT0 = float32_sub(FT0, FT1, &env->fp_status); | |
762 | RETURN(); | |
763 | } | |
764 | ||
765 | void OPPROTO op_fsub_DT(void) | |
766 | { | |
767 | DT0 = float64_sub(DT0, DT1, &env->fp_status); | |
768 | RETURN(); | |
769 | } | |
770 | ||
771 | void OPPROTO op_fmul_FT(void) | |
772 | { | |
773 | FT0 = float32_mul(FT0, FT1, &env->fp_status); | |
774 | RETURN(); | |
775 | } | |
776 | ||
777 | void OPPROTO op_fmul_DT(void) | |
778 | { | |
779 | DT0 = float64_mul(DT0, DT1, &env->fp_status); | |
780 | RETURN(); | |
781 | } | |
782 | ||
783 | void OPPROTO op_fdiv_FT(void) | |
784 | { | |
785 | FT0 = float32_div(FT0, FT1, &env->fp_status); | |
786 | RETURN(); | |
787 | } | |
788 | ||
789 | void OPPROTO op_fdiv_DT(void) | |
790 | { | |
791 | DT0 = float64_div(DT0, DT1, &env->fp_status); | |
792 | RETURN(); | |
793 | } | |
794 | ||
795 | void OPPROTO op_float_FT(void) | |
796 | { | |
797 | FT0 = int32_to_float32(env->fpul, &env->fp_status); | |
798 | RETURN(); | |
799 | } | |
800 | ||
801 | void OPPROTO op_float_DT(void) | |
802 | { | |
803 | DT0 = int32_to_float64(env->fpul, &env->fp_status); | |
804 | RETURN(); | |
805 | } | |
806 | ||
807 | void OPPROTO op_ftrc_FT(void) | |
808 | { | |
809 | env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status); | |
810 | RETURN(); | |
811 | } | |
812 | ||
813 | void OPPROTO op_ftrc_DT(void) | |
814 | { | |
815 | env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status); | |
816 | RETURN(); | |
817 | } | |
818 | ||
819 | void OPPROTO op_fmov_T0_frN(void) | |
820 | { | |
821 | *(unsigned int *)&env->fregs[PARAM1] = T0; | |
822 | RETURN(); | |
823 | } | |
824 | ||
fdf9b3e8 FB |
825 | void OPPROTO op_dec1_rN(void) |
826 | { | |
827 | env->gregs[PARAM1] -= 1; | |
828 | RETURN(); | |
829 | } | |
830 | ||
831 | void OPPROTO op_dec2_rN(void) | |
832 | { | |
833 | env->gregs[PARAM1] -= 2; | |
834 | RETURN(); | |
835 | } | |
836 | ||
837 | void OPPROTO op_dec4_rN(void) | |
838 | { | |
839 | env->gregs[PARAM1] -= 4; | |
840 | RETURN(); | |
841 | } | |
842 | ||
eda9b09b FB |
843 | void OPPROTO op_dec8_rN(void) |
844 | { | |
0a618140 | 845 | env->gregs[PARAM1] -= 8; |
eda9b09b FB |
846 | RETURN(); |
847 | } | |
848 | ||
fdf9b3e8 FB |
849 | void OPPROTO op_inc1_rN(void) |
850 | { | |
851 | env->gregs[PARAM1] += 1; | |
852 | RETURN(); | |
853 | } | |
854 | ||
855 | void OPPROTO op_inc2_rN(void) | |
856 | { | |
857 | env->gregs[PARAM1] += 2; | |
858 | RETURN(); | |
859 | } | |
860 | ||
861 | void OPPROTO op_inc4_rN(void) | |
862 | { | |
863 | env->gregs[PARAM1] += 4; | |
864 | RETURN(); | |
865 | } | |
866 | ||
eda9b09b FB |
867 | void OPPROTO op_inc8_rN(void) |
868 | { | |
0a618140 | 869 | env->gregs[PARAM1] += 8; |
eda9b09b FB |
870 | RETURN(); |
871 | } | |
872 | ||
fdf9b3e8 FB |
873 | void OPPROTO op_add_T0_rN(void) |
874 | { | |
875 | env->gregs[PARAM1] += T0; | |
876 | RETURN(); | |
877 | } | |
878 | ||
879 | void OPPROTO op_sub_T0_rN(void) | |
880 | { | |
881 | env->gregs[PARAM1] -= T0; | |
882 | RETURN(); | |
883 | } | |
884 | ||
885 | void OPPROTO op_and_T0_rN(void) | |
886 | { | |
887 | env->gregs[PARAM1] &= T0; | |
888 | RETURN(); | |
889 | } | |
890 | ||
891 | void OPPROTO op_or_T0_rN(void) | |
892 | { | |
893 | env->gregs[PARAM1] |= T0; | |
894 | RETURN(); | |
895 | } | |
896 | ||
897 | void OPPROTO op_xor_T0_rN(void) | |
898 | { | |
899 | env->gregs[PARAM1] ^= T0; | |
900 | RETURN(); | |
901 | } | |
902 | ||
903 | void OPPROTO op_add_rN_T0(void) | |
904 | { | |
905 | T0 += env->gregs[PARAM1]; | |
906 | RETURN(); | |
907 | } | |
908 | ||
909 | void OPPROTO op_add_rN_T1(void) | |
910 | { | |
911 | T1 += env->gregs[PARAM1]; | |
912 | RETURN(); | |
913 | } | |
914 | ||
915 | void OPPROTO op_add_imm_rN(void) | |
916 | { | |
917 | env->gregs[PARAM2] += PARAM1; | |
918 | RETURN(); | |
919 | } | |
920 | ||
921 | void OPPROTO op_and_imm_rN(void) | |
922 | { | |
923 | env->gregs[PARAM2] &= PARAM1; | |
924 | RETURN(); | |
925 | } | |
926 | ||
927 | void OPPROTO op_or_imm_rN(void) | |
928 | { | |
929 | env->gregs[PARAM2] |= PARAM1; | |
930 | RETURN(); | |
931 | } | |
932 | ||
933 | void OPPROTO op_xor_imm_rN(void) | |
934 | { | |
935 | env->gregs[PARAM2] ^= PARAM1; | |
936 | RETURN(); | |
937 | } | |
938 | ||
939 | void OPPROTO op_dt_rN(void) | |
940 | { | |
941 | cond_t((--env->gregs[PARAM1]) == 0); | |
942 | RETURN(); | |
943 | } | |
944 | ||
945 | void OPPROTO op_tst_imm_rN(void) | |
946 | { | |
947 | cond_t((env->gregs[PARAM2] & PARAM1) == 0); | |
948 | RETURN(); | |
949 | } | |
950 | ||
951 | void OPPROTO op_movl_T0_T1(void) | |
952 | { | |
953 | T1 = T0; | |
954 | RETURN(); | |
955 | } | |
956 | ||
eda9b09b FB |
957 | void OPPROTO op_movl_fpul_FT0(void) |
958 | { | |
959 | FT0 = *(float32 *)&env->fpul; | |
960 | RETURN(); | |
961 | } | |
962 | ||
963 | void OPPROTO op_movl_FT0_fpul(void) | |
964 | { | |
965 | *(float32 *)&env->fpul = FT0; | |
966 | RETURN(); | |
967 | } | |
968 | ||
fdf9b3e8 FB |
969 | void OPPROTO op_goto_tb0(void) |
970 | { | |
971 | GOTO_TB(op_goto_tb0, PARAM1, 0); | |
972 | RETURN(); | |
973 | } | |
974 | ||
975 | void OPPROTO op_goto_tb1(void) | |
976 | { | |
977 | GOTO_TB(op_goto_tb1, PARAM1, 1); | |
978 | RETURN(); | |
979 | } | |
980 | ||
981 | void OPPROTO op_movl_imm_PC(void) | |
982 | { | |
983 | env->pc = PARAM1; | |
984 | RETURN(); | |
985 | } | |
986 | ||
987 | void OPPROTO op_jT(void) | |
988 | { | |
989 | if (env->sr & SR_T) | |
990 | GOTO_LABEL_PARAM(1); | |
991 | RETURN(); | |
992 | } | |
993 | ||
9c2a9ea1 | 994 | void OPPROTO op_jdelayed(void) |
fdf9b3e8 | 995 | { |
9c2a9ea1 PB |
996 | uint32_t flags; |
997 | flags = env->flags; | |
998 | env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL); | |
999 | if (flags & DELAY_SLOT) | |
fdf9b3e8 FB |
1000 | GOTO_LABEL_PARAM(1); |
1001 | RETURN(); | |
1002 | } | |
1003 | ||
1004 | void OPPROTO op_movl_delayed_pc_PC(void) | |
1005 | { | |
1006 | env->pc = env->delayed_pc; | |
1007 | RETURN(); | |
1008 | } | |
1009 | ||
1010 | void OPPROTO op_addl_GBR_T0(void) | |
1011 | { | |
1012 | T0 += env->gbr; | |
1013 | RETURN(); | |
1014 | } | |
1015 | ||
1016 | void OPPROTO op_and_imm_T0(void) | |
1017 | { | |
1018 | T0 &= PARAM1; | |
1019 | RETURN(); | |
1020 | } | |
1021 | ||
1022 | void OPPROTO op_or_imm_T0(void) | |
1023 | { | |
1024 | T0 |= PARAM1; | |
1025 | RETURN(); | |
1026 | } | |
1027 | ||
1028 | void OPPROTO op_xor_imm_T0(void) | |
1029 | { | |
1030 | T0 ^= PARAM1; | |
1031 | RETURN(); | |
1032 | } | |
1033 | ||
1034 | void OPPROTO op_tst_imm_T0(void) | |
1035 | { | |
1036 | cond_t((T0 & PARAM1) == 0); | |
1037 | RETURN(); | |
1038 | } | |
1039 | ||
1040 | void OPPROTO op_raise_illegal_instruction(void) | |
1041 | { | |
1042 | env->exception_index = 0x180; | |
1043 | do_raise_exception(); | |
1044 | RETURN(); | |
1045 | } | |
1046 | ||
1047 | void OPPROTO op_raise_slot_illegal_instruction(void) | |
1048 | { | |
1049 | env->exception_index = 0x1a0; | |
1050 | do_raise_exception(); | |
1051 | RETURN(); | |
1052 | } | |
1053 | ||
1054 | void OPPROTO op_debug(void) | |
1055 | { | |
1056 | env->exception_index = EXCP_DEBUG; | |
1057 | cpu_loop_exit(); | |
1058 | } | |
1059 | ||
1060 | /* Load and store */ | |
1061 | #define MEMSUFFIX _raw | |
1062 | #include "op_mem.c" | |
1063 | #undef MEMSUFFIX | |
1064 | #if !defined(CONFIG_USER_ONLY) | |
1065 | #define MEMSUFFIX _user | |
1066 | #include "op_mem.c" | |
1067 | #undef MEMSUFFIX | |
1068 | ||
1069 | #define MEMSUFFIX _kernel | |
1070 | #include "op_mem.c" | |
1071 | #undef MEMSUFFIX | |
1072 | #endif |