4 * Copyright (c) 2005 Samuel Tardieu
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.
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.
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
22 static inline void set_t(void)
27 static inline void clr_t(void)
32 static inline void cond_t(int cond)
40 void OPPROTO op_bf_s(void)
42 env->delayed_pc = PARAM1;
43 if (!(env->sr & SR_T)) {
44 env->flags |= DELAY_SLOT_TRUE;
49 void OPPROTO op_bt_s(void)
51 env->delayed_pc = PARAM1;
53 env->flags |= DELAY_SLOT_TRUE;
58 void OPPROTO op_store_flags(void)
60 env->flags &= DELAY_SLOT_TRUE;
65 void OPPROTO op_bra(void)
67 env->delayed_pc = PARAM1;
71 void OPPROTO op_braf_T0(void)
73 env->delayed_pc = PARAM1 + T0;
77 void OPPROTO op_bsr(void)
80 env->delayed_pc = PARAM2;
84 void OPPROTO op_bsrf_T0(void)
87 env->delayed_pc = PARAM1 + T0;
91 void OPPROTO op_jsr_T0(void)
98 void OPPROTO op_rts(void)
100 env->delayed_pc = env->pr;
104 void OPPROTO op_ldtlb(void)
110 void OPPROTO op_frchg(void)
112 env->fpscr ^= FPSCR_FR;
116 void OPPROTO op_fschg(void)
118 env->fpscr ^= FPSCR_SZ;
122 void OPPROTO op_rte(void)
125 env->delayed_pc = env->spc;
129 void OPPROTO op_addc_T0_T1(void)
135 void OPPROTO op_addv_T0_T1(void)
141 void OPPROTO op_cmp_str_T0_T1(void)
143 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
144 (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
145 (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
146 (T0 & 0xff000000) == (T1 & 0xff000000));
150 void OPPROTO op_div0s_T0_T1(void)
160 cond_t((T1 ^ T0) & 0x80000000);
164 void OPPROTO op_div1_T0_T1(void)
170 void OPPROTO op_dmulsl_T0_T1(void)
172 helper_dmulsl_T0_T1();
176 void OPPROTO op_dmulul_T0_T1(void)
178 helper_dmulul_T0_T1();
182 void OPPROTO op_macl_T0_T1(void)
188 void OPPROTO op_macw_T0_T1(void)
194 void OPPROTO op_mull_T0_T1(void)
196 env->macl = (T0 * T1) & 0xffffffff;
200 void OPPROTO op_mulsw_T0_T1(void)
202 env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
206 void OPPROTO op_muluw_T0_T1(void)
208 env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
212 void OPPROTO op_negc_T0(void)
218 void OPPROTO op_shad_T0_T1(void)
220 if ((T0 & 0x80000000) == 0)
222 else if ((T0 & 0x1f) == 0)
223 T1 = (T1 & 0x80000000)? 0xffffffff : 0;
225 T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
229 void OPPROTO op_shld_T0_T1(void)
231 if ((T0 & 0x80000000) == 0)
233 else if ((T0 & 0x1f) == 0)
236 T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
240 void OPPROTO op_subc_T0_T1(void)
246 void OPPROTO op_subv_T0_T1(void)
252 void OPPROTO op_trapa(void)
254 env->tra = PARAM1 << 2;
255 env->exception_index = 0x160;
256 do_raise_exception();
260 void OPPROTO op_jmp_T0(void)
262 env->delayed_pc = T0;
266 void OPPROTO op_ldcl_rMplus_rN_bank(void)
268 env->gregs[PARAM2] = env->gregs[PARAM1];
269 env->gregs[PARAM1] += 4;
273 void OPPROTO op_ldc_T0_sr(void)
275 env->sr = T0 & 0x700083f3;
279 void OPPROTO op_stc_sr_T0(void)
285 #define LDSTOPS(target,load,store) \
286 void OPPROTO op_##load##_T0_##target (void) \
287 { env ->target = T0; RETURN(); \
289 void OPPROTO op_##store##_##target##_T0 (void) \
290 { T0 = env->target; RETURN(); \
293 LDSTOPS(gbr, ldc, stc)
294 LDSTOPS(vbr, ldc, stc)
295 LDSTOPS(ssr, ldc, stc)
296 LDSTOPS(spc, ldc, stc)
297 LDSTOPS(sgr, ldc, stc)
298 LDSTOPS(dbr, ldc, stc)
299 LDSTOPS(mach, lds, sts)
300 LDSTOPS(macl, lds, sts)
301 LDSTOPS(pr, lds, sts)
302 LDSTOPS(fpul, lds, sts)
304 void OPPROTO op_lds_T0_fpscr(void)
306 env->fpscr = T0 & 0x003fffff;
307 env->fp_status.float_rounding_mode = T0 & 0x01 ?
308 float_round_to_zero : float_round_nearest_even;
313 void OPPROTO op_sts_fpscr_T0(void)
315 T0 = env->fpscr & 0x003fffff;
319 void OPPROTO op_rotcl_Rn(void)
321 helper_rotcl(&env->gregs[PARAM1]);
325 void OPPROTO op_rotcr_Rn(void)
327 helper_rotcr(&env->gregs[PARAM1]);
331 void OPPROTO op_rotl_Rn(void)
333 cond_t(env->gregs[PARAM1] & 0x80000000);
334 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
338 void OPPROTO op_rotr_Rn(void)
340 cond_t(env->gregs[PARAM1] & 1);
341 env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
342 ((env->sr & SR_T) ? 0x80000000 : 0);
346 void OPPROTO op_shal_Rn(void)
348 cond_t(env->gregs[PARAM1] & 0x80000000);
349 env->gregs[PARAM1] <<= 1;
353 void OPPROTO op_shar_Rn(void)
355 cond_t(env->gregs[PARAM1] & 1);
356 *(int32_t *)&env->gregs[PARAM1] >>= 1;
360 void OPPROTO op_shlr_Rn(void)
362 cond_t(env->gregs[PARAM1] & 1);
363 env->gregs[PARAM1] >>= 1;
367 void OPPROTO op_fmov_frN_FT0(void)
369 FT0 = env->fregs[PARAM1];
373 void OPPROTO op_fmov_drN_DT0(void)
377 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
378 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
383 void OPPROTO op_fmov_frN_FT1(void)
385 FT1 = env->fregs[PARAM1];
389 void OPPROTO op_fmov_drN_DT1(void)
393 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
394 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
399 void OPPROTO op_fmov_FT0_frN(void)
401 env->fregs[PARAM1] = FT0;
405 void OPPROTO op_fmov_DT0_drN(void)
410 *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
411 *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
415 void OPPROTO op_fadd_FT(void)
417 FT0 = float32_add(FT0, FT1, &env->fp_status);
421 void OPPROTO op_fadd_DT(void)
423 DT0 = float64_add(DT0, DT1, &env->fp_status);
427 void OPPROTO op_fsub_FT(void)
429 FT0 = float32_sub(FT0, FT1, &env->fp_status);
433 void OPPROTO op_fsub_DT(void)
435 DT0 = float64_sub(DT0, DT1, &env->fp_status);
439 void OPPROTO op_fmul_FT(void)
441 FT0 = float32_mul(FT0, FT1, &env->fp_status);
445 void OPPROTO op_fmul_DT(void)
447 DT0 = float64_mul(DT0, DT1, &env->fp_status);
451 void OPPROTO op_fdiv_FT(void)
453 FT0 = float32_div(FT0, FT1, &env->fp_status);
457 void OPPROTO op_fdiv_DT(void)
459 DT0 = float64_div(DT0, DT1, &env->fp_status);
463 void OPPROTO op_fcmp_eq_FT(void)
465 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
469 void OPPROTO op_fcmp_eq_DT(void)
471 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
475 void OPPROTO op_fcmp_gt_FT(void)
477 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
481 void OPPROTO op_fcmp_gt_DT(void)
483 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
487 void OPPROTO op_float_FT(void)
489 FT0 = int32_to_float32(env->fpul, &env->fp_status);
493 void OPPROTO op_float_DT(void)
495 DT0 = int32_to_float64(env->fpul, &env->fp_status);
499 void OPPROTO op_ftrc_FT(void)
501 env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
505 void OPPROTO op_ftrc_DT(void)
507 env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
511 void OPPROTO op_fneg_frN(void)
513 env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
517 void OPPROTO op_fabs_FT(void)
519 FT0 = float32_abs(FT0);
523 void OPPROTO op_fabs_DT(void)
525 DT0 = float64_abs(DT0);
529 void OPPROTO op_fcnvsd_FT_DT(void)
531 DT0 = float32_to_float64(FT0, &env->fp_status);
535 void OPPROTO op_fcnvds_DT_FT(void)
537 FT0 = float64_to_float32(DT0, &env->fp_status);
541 void OPPROTO op_fsqrt_FT(void)
543 FT0 = float32_sqrt(FT0, &env->fp_status);
547 void OPPROTO op_fsqrt_DT(void)
549 DT0 = float64_sqrt(DT0, &env->fp_status);
553 void OPPROTO op_fmov_T0_frN(void)
555 *(uint32_t *)&env->fregs[PARAM1] = T0;
559 void OPPROTO op_movl_fpul_FT0(void)
561 FT0 = *(float32 *)&env->fpul;
565 void OPPROTO op_movl_FT0_fpul(void)
567 *(float32 *)&env->fpul = FT0;
571 void OPPROTO op_jT(void)
578 void OPPROTO op_jdelayed(void)
580 if (env->flags & DELAY_SLOT_TRUE) {
581 env->flags &= ~DELAY_SLOT_TRUE;
587 void OPPROTO op_movl_delayed_pc_PC(void)
589 env->pc = env->delayed_pc;
593 void OPPROTO op_raise_illegal_instruction(void)
595 env->exception_index = 0x180;
596 do_raise_exception();
600 void OPPROTO op_raise_slot_illegal_instruction(void)
602 env->exception_index = 0x1a0;
603 do_raise_exception();
607 void OPPROTO op_debug(void)
609 env->exception_index = EXCP_DEBUG;
613 void OPPROTO op_sleep(void)
616 env->exception_index = EXCP_HLT;
621 #define MEMSUFFIX _raw
624 #if !defined(CONFIG_USER_ONLY)
625 #define MEMSUFFIX _user
629 #define MEMSUFFIX _kernel