📄 op.c.svn-base
字号:
src1 = T0; T0 -= T1; env->psr = 0;#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) env->psr |= PSR_CARRY; if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) env->psr |= PSR_OVF; if ((src1 & 0x03) || (T1 & 0x03)) env->psr |= PSR_OVF; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG; if (src1 < T1) env->xcc |= PSR_CARRY; if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63)) env->xcc |= PSR_OVF;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (src1 < T1) env->psr |= PSR_CARRY; if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) env->psr |= PSR_OVF; if ((src1 & 0x03) || (T1 & 0x03)) env->psr |= PSR_OVF;#endif FORCE_RET();}void OPPROTO op_tsub_T1_T0_ccTV(void){ target_ulong src1; if ((T0 & 0x03) || (T1 & 0x03)) raise_exception(TT_TOVF); src1 = T0; T0 -= T1;#ifdef TARGET_SPARC64 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) raise_exception(TT_TOVF);#else if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) raise_exception(TT_TOVF);#endif env->psr = 0;#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) env->psr |= PSR_CARRY; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG; if (src1 < T1) env->xcc |= PSR_CARRY;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (src1 < T1) env->psr |= PSR_CARRY;#endif FORCE_RET();}void OPPROTO op_and_T1_T0(void){ T0 &= T1;}void OPPROTO op_or_T1_T0(void){ T0 |= T1;}void OPPROTO op_xor_T1_T0(void){ T0 ^= T1;}void OPPROTO op_andn_T1_T0(void){ T0 &= ~T1;}void OPPROTO op_orn_T1_T0(void){ T0 |= ~T1;}void OPPROTO op_xnor_T1_T0(void){ T0 ^= ~T1;}void OPPROTO op_umul_T1_T0(void){ uint64_t res; res = (uint64_t) T0 * (uint64_t) T1;#ifdef TARGET_SPARC64 T0 = res;#else T0 = res & 0xffffffff;#endif env->y = res >> 32;}void OPPROTO op_smul_T1_T0(void){ uint64_t res; res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);#ifdef TARGET_SPARC64 T0 = res;#else T0 = res & 0xffffffff;#endif env->y = res >> 32;}void OPPROTO op_mulscc_T1_T0(void){ unsigned int b1, N, V, b2; target_ulong src1; N = FLAG_SET(PSR_NEG); V = FLAG_SET(PSR_OVF); b1 = N ^ V; b2 = T0 & 1; T0 = (b1 << 31) | (T0 >> 1); if (!(env->y & 1)) T1 = 0; /* do addition and update flags */ src1 = T0; T0 += T1; env->psr = 0; if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (T0 < src1) env->psr |= PSR_CARRY; if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) env->psr |= PSR_OVF; env->y = (b2 << 31) | (env->y >> 1); FORCE_RET();}void OPPROTO op_udiv_T1_T0(void){ uint64_t x0; uint32_t x1; x0 = T0 | ((uint64_t) (env->y) << 32); x1 = T1; if (x1 == 0) { raise_exception(TT_DIV_ZERO); } x0 = x0 / x1; if (x0 > 0xffffffff) { T0 = 0xffffffff; T1 = 1; } else { T0 = x0; T1 = 0; } FORCE_RET();}void OPPROTO op_sdiv_T1_T0(void){ int64_t x0; int32_t x1; x0 = T0 | ((int64_t) (env->y) << 32); x1 = T1; if (x1 == 0) { raise_exception(TT_DIV_ZERO); } x0 = x0 / x1; if ((int32_t) x0 != x0) { T0 = x0 < 0? 0x80000000: 0x7fffffff; T1 = 1; } else { T0 = x0; T1 = 0; } FORCE_RET();}void OPPROTO op_div_cc(void){ env->psr = 0;#ifdef TARGET_SPARC64 if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (T1) env->psr |= PSR_OVF; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (T1) env->psr |= PSR_OVF;#endif FORCE_RET();}#ifdef TARGET_SPARC64void OPPROTO op_mulx_T1_T0(void){ T0 *= T1; FORCE_RET();}void OPPROTO op_udivx_T1_T0(void){ if (T1 == 0) { raise_exception(TT_DIV_ZERO); } T0 /= T1; FORCE_RET();}void OPPROTO op_sdivx_T1_T0(void){ if (T1 == 0) { raise_exception(TT_DIV_ZERO); } if (T0 == INT64_MIN && T1 == -1) T0 = INT64_MIN; else T0 /= (target_long) T1; FORCE_RET();}#endifvoid OPPROTO op_logic_T0_cc(void){ env->psr = 0;#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG;#endif FORCE_RET();}void OPPROTO op_sll(void){ T0 <<= (T1 & 0x1f);}#ifdef TARGET_SPARC64void OPPROTO op_sllx(void){ T0 <<= (T1 & 0x3f);}void OPPROTO op_srl(void){ T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);}void OPPROTO op_srlx(void){ T0 >>= (T1 & 0x3f);}void OPPROTO op_sra(void){ T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f);}void OPPROTO op_srax(void){ T0 = ((int64_t) T0) >> (T1 & 0x3f);}#elsevoid OPPROTO op_srl(void){ T0 >>= (T1 & 0x1f);}void OPPROTO op_sra(void){ T0 = ((int32_t) T0) >> (T1 & 0x1f);}#endif/* Load and store */#define MEMSUFFIX _raw#include "op_mem.h"#if !defined(CONFIG_USER_ONLY)#define MEMSUFFIX _user#include "op_mem.h"#define MEMSUFFIX _kernel#include "op_mem.h"#ifdef TARGET_SPARC64#define MEMSUFFIX _hypv#include "op_mem.h"#endif#endifvoid OPPROTO op_ldfsr(void){ PUT_FSR32(env, *((uint32_t *) &FT0)); helper_ldfsr();}void OPPROTO op_stfsr(void){ *((uint32_t *) &FT0) = GET_FSR32(env);}#ifndef TARGET_SPARC64void OPPROTO op_rdpsr(void){ do_rdpsr();}void OPPROTO op_wrpsr(void){ do_wrpsr(); FORCE_RET();}void OPPROTO op_wrwim(void){#if NWINDOWS == 32 env->wim = T0;#else env->wim = T0 & ((1 << NWINDOWS) - 1);#endif}void OPPROTO op_rett(void){ helper_rett(); FORCE_RET();}/* XXX: use another pointer for %iN registers to avoid slow wrapping handling ? */void OPPROTO op_save(void){ uint32_t cwp; cwp = (env->cwp - 1) & (NWINDOWS - 1); if (env->wim & (1 << cwp)) { raise_exception(TT_WIN_OVF); } set_cwp(cwp); FORCE_RET();}void OPPROTO op_restore(void){ uint32_t cwp; cwp = (env->cwp + 1) & (NWINDOWS - 1); if (env->wim & (1 << cwp)) { raise_exception(TT_WIN_UNF); } set_cwp(cwp); FORCE_RET();}#elsevoid OPPROTO op_rdccr(void){ T0 = GET_CCR(env);}void OPPROTO op_wrccr(void){ PUT_CCR(env, T0);}void OPPROTO op_rdtick(void){ T0 = do_tick_get_count(env->tick);}void OPPROTO op_wrtick(void){ do_tick_set_count(env->tick, T0);}void OPPROTO op_wrtick_cmpr(void){ do_tick_set_limit(env->tick, T0);}void OPPROTO op_rdstick(void){ T0 = do_tick_get_count(env->stick);}void OPPROTO op_wrstick(void){ do_tick_set_count(env->stick, T0); do_tick_set_count(env->hstick, T0);}void OPPROTO op_wrstick_cmpr(void){ do_tick_set_limit(env->stick, T0);}void OPPROTO op_wrhstick_cmpr(void){ do_tick_set_limit(env->hstick, T0);}void OPPROTO op_rdtpc(void){ T0 = env->tpc[env->tl];}void OPPROTO op_wrtpc(void){ env->tpc[env->tl] = T0;}void OPPROTO op_rdtnpc(void){ T0 = env->tnpc[env->tl];}void OPPROTO op_wrtnpc(void){ env->tnpc[env->tl] = T0;}void OPPROTO op_rdtstate(void){ T0 = env->tstate[env->tl];}void OPPROTO op_wrtstate(void){ env->tstate[env->tl] = T0;}void OPPROTO op_rdtt(void){ T0 = env->tt[env->tl];}void OPPROTO op_wrtt(void){ env->tt[env->tl] = T0;}void OPPROTO op_rdpstate(void){ T0 = env->pstate;}void OPPROTO op_wrpstate(void){ do_wrpstate();}// CWP handling is reversed in V9, but we still use the V8 register// order.void OPPROTO op_rdcwp(void){ T0 = GET_CWP64(env);}void OPPROTO op_wrcwp(void){ PUT_CWP64(env, T0);}/* XXX: use another pointer for %iN registers to avoid slow wrapping handling ? */void OPPROTO op_save(void){ uint32_t cwp; cwp = (env->cwp - 1) & (NWINDOWS - 1); if (env->cansave == 0) { raise_exception(TT_SPILL | (env->otherwin != 0 ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)): ((env->wstate & 0x7) << 2))); } else { if (env->cleanwin - env->canrestore == 0) { // XXX Clean windows without trap raise_exception(TT_CLRWIN); } else { env->cansave--; env->canrestore++; set_cwp(cwp); } } FORCE_RET();}void OPPROTO op_restore(void){ uint32_t cwp; cwp = (env->cwp + 1) & (NWINDOWS - 1); if (env->canrestore == 0) { raise_exception(TT_FILL | (env->otherwin != 0 ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)): ((env->wstate & 0x7) << 2))); } else { env->cansave++; env->canrestore--; set_cwp(cwp); } FORCE_RET();}#endifvoid OPPROTO op_exception(void){ env->exception_index = PARAM1; cpu_loop_exit(); FORCE_RET();}void OPPROTO op_trap_T0(void){ env->exception_index = TT_TRAP + (T0 & 0x7f); cpu_loop_exit(); FORCE_RET();}void OPPROTO op_trapcc_T0(void){ if (T2) { env->exception_index = TT_TRAP + (T0 & 0x7f); cpu_loop_exit(); } FORCE_RET();}void OPPROTO op_fpexception_im(void){ env->exception_index = TT_FP_EXCP; env->fsr &= ~FSR_FTT_MASK; env->fsr |= PARAM1; cpu_loop_exit(); FORCE_RET();}void OPPROTO op_debug(void){ helper_debug();}void OPPROTO op_exit_tb(void){ EXIT_TB();}void OPPROTO op_eval_ba(void){ T2 = 1;}void OPPROTO op_eval_be(void){ T2 = FLAG_SET(PSR_ZERO);}void OPPROTO op_eval_ble(void){ target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); T2 = Z | (N ^ V);}void OPPROTO op_eval_bl(void){ target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); T2 = N ^ V;}void OPPROTO op_eval_bleu(void){ target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); T2 = C | Z;}void OPPROTO op_eval_bcs(void){ T2 = FLAG_SET(PSR_CARRY);}void OPPROTO op_eval_bvs(void){ T2 = FLAG_SET(PSR_OVF);}void OPPROTO op_eval_bn(void){ T2 = 0;}void OPPROTO op_eval_bneg(void){ T2 = FLAG_SET(PSR_NEG);}void OPPROTO op_eval_bne(void){ T2 = !FLAG_SET(PSR_ZERO);}void OPPROTO op_eval_bg(void){ target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); T2 = !(Z | (N ^ V));}void OPPROTO op_eval_bge(void){ target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); T2 = !(N ^ V);}void OPPROTO op_eval_bgu(void){ target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); T2 = !(C | Z);}void OPPROTO op_eval_bcc(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -