?? op_helper.c
字號:
break;#endif } helper_st_asi(asi, size); T1 = tmp_T1;}#endif /* TARGET_SPARC64 */#ifndef TARGET_SPARC64void helper_rett(){ unsigned int cwp; if (env->psret == 1) raise_exception(TT_ILL_INSN); env->psret = 1; cwp = (env->cwp + 1) & (NWINDOWS - 1); if (env->wim & (1 << cwp)) { raise_exception(TT_WIN_UNF); } set_cwp(cwp); env->psrs = env->psrps;}#endifvoid helper_ldfsr(void){ int rnd_mode; switch (env->fsr & FSR_RD_MASK) { case FSR_RD_NEAREST: rnd_mode = float_round_nearest_even; break; default: case FSR_RD_ZERO: rnd_mode = float_round_to_zero; break; case FSR_RD_POS: rnd_mode = float_round_up; break; case FSR_RD_NEG: rnd_mode = float_round_down; break; } set_float_rounding_mode(rnd_mode, &env->fp_status);}void helper_debug(){ env->exception_index = EXCP_DEBUG; cpu_loop_exit();}#ifndef TARGET_SPARC64void do_wrpsr(){ if ((T0 & PSR_CWP) >= NWINDOWS) raise_exception(TT_ILL_INSN); else PUT_PSR(env, T0);}void do_rdpsr(){ T0 = GET_PSR(env);}#elsevoid do_popc(){ T0 = ctpop64(T1);}static inline uint64_t *get_gregset(uint64_t pstate){ switch (pstate) { default: case 0: return env->bgregs; case PS_AG: return env->agregs; case PS_MG: return env->mgregs; case PS_IG: return env->igregs; }}static inline void change_pstate(uint64_t new_pstate){ uint64_t pstate_regs, new_pstate_regs; uint64_t *src, *dst; pstate_regs = env->pstate & 0xc01; new_pstate_regs = new_pstate & 0xc01; if (new_pstate_regs != pstate_regs) { // Switch global register bank src = get_gregset(new_pstate_regs); dst = get_gregset(pstate_regs); memcpy32(dst, env->gregs); memcpy32(env->gregs, src); } env->pstate = new_pstate;}void do_wrpstate(void){ change_pstate(T0 & 0xf3f);}void do_done(void){ env->tl--; env->pc = env->tnpc[env->tl]; env->npc = env->tnpc[env->tl] + 4; PUT_CCR(env, env->tstate[env->tl] >> 32); env->asi = (env->tstate[env->tl] >> 24) & 0xff; change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); PUT_CWP64(env, env->tstate[env->tl] & 0xff);}void do_retry(void){ env->tl--; env->pc = env->tpc[env->tl]; env->npc = env->tnpc[env->tl]; PUT_CCR(env, env->tstate[env->tl] >> 32); env->asi = (env->tstate[env->tl] >> 24) & 0xff; change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); PUT_CWP64(env, env->tstate[env->tl] & 0xff);}#endifvoid set_cwp(int new_cwp){ /* put the modified wrap registers at their proper location */ if (env->cwp == (NWINDOWS - 1)) memcpy32(env->regbase, env->regbase + NWINDOWS * 16); env->cwp = new_cwp; /* put the wrap registers at their temporary location */ if (new_cwp == (NWINDOWS - 1)) memcpy32(env->regbase + NWINDOWS * 16, env->regbase); env->regwptr = env->regbase + (new_cwp * 16); REGWPTR = env->regwptr;}void cpu_set_cwp(CPUState *env1, int new_cwp){ CPUState *saved_env;#ifdef reg_REGWPTR target_ulong *saved_regwptr;#endif saved_env = env;#ifdef reg_REGWPTR saved_regwptr = REGWPTR;#endif env = env1; set_cwp(new_cwp); env = saved_env;#ifdef reg_REGWPTR REGWPTR = saved_regwptr;#endif}#ifdef TARGET_SPARC64#ifdef DEBUG_PCALLstatic const char * const excp_names[0x50] = { [TT_TFAULT] = "Instruction Access Fault", [TT_TMISS] = "Instruction Access MMU Miss", [TT_CODE_ACCESS] = "Instruction Access Error", [TT_ILL_INSN] = "Illegal Instruction", [TT_PRIV_INSN] = "Privileged Instruction", [TT_NFPU_INSN] = "FPU Disabled", [TT_FP_EXCP] = "FPU Exception", [TT_TOVF] = "Tag Overflow", [TT_CLRWIN] = "Clean Windows", [TT_DIV_ZERO] = "Division By Zero", [TT_DFAULT] = "Data Access Fault", [TT_DMISS] = "Data Access MMU Miss", [TT_DATA_ACCESS] = "Data Access Error", [TT_DPROT] = "Data Protection Error", [TT_UNALIGNED] = "Unaligned Memory Access", [TT_PRIV_ACT] = "Privileged Action", [TT_EXTINT | 0x1] = "External Interrupt 1", [TT_EXTINT | 0x2] = "External Interrupt 2", [TT_EXTINT | 0x3] = "External Interrupt 3", [TT_EXTINT | 0x4] = "External Interrupt 4", [TT_EXTINT | 0x5] = "External Interrupt 5", [TT_EXTINT | 0x6] = "External Interrupt 6", [TT_EXTINT | 0x7] = "External Interrupt 7", [TT_EXTINT | 0x8] = "External Interrupt 8", [TT_EXTINT | 0x9] = "External Interrupt 9", [TT_EXTINT | 0xa] = "External Interrupt 10", [TT_EXTINT | 0xb] = "External Interrupt 11", [TT_EXTINT | 0xc] = "External Interrupt 12", [TT_EXTINT | 0xd] = "External Interrupt 13", [TT_EXTINT | 0xe] = "External Interrupt 14", [TT_EXTINT | 0xf] = "External Interrupt 15",};#endifvoid do_interrupt(int intno){#ifdef DEBUG_PCALL if (loglevel & CPU_LOG_INT) { static int count; const char *name; if (intno < 0 || intno >= 0x180 || (intno > 0x4f && intno < 0x80)) name = "Unknown"; else if (intno >= 0x100) name = "Trap Instruction"; else if (intno >= 0xc0) name = "Window Fill"; else if (intno >= 0x80) name = "Window Spill"; else { name = excp_names[intno]; if (!name) name = "Unknown"; } fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n", count, name, intno, env->pc, env->npc, env->regwptr[6]); cpu_dump_state(env, logfile, fprintf, 0);#if 0 { int i; uint8_t *ptr; fprintf(logfile, " code="); ptr = (uint8_t *)env->pc; for(i = 0; i < 16; i++) { fprintf(logfile, " %02x", ldub(ptr + i)); } fprintf(logfile, "\n"); }#endif count++; }#endif#if !defined(CONFIG_USER_ONLY) if (env->tl == MAXTL) { cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index); return; }#endif env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) | GET_CWP64(env); env->tpc[env->tl] = env->pc; env->tnpc[env->tl] = env->npc; env->tt[env->tl] = intno; change_pstate(PS_PEF | PS_PRIV | PS_AG); if (intno == TT_CLRWIN) set_cwp((env->cwp - 1) & (NWINDOWS - 1)); else if ((intno & 0x1c0) == TT_SPILL) set_cwp((env->cwp - env->cansave - 2) & (NWINDOWS - 1)); else if ((intno & 0x1c0) == TT_FILL) set_cwp((env->cwp + 1) & (NWINDOWS - 1)); env->tbr &= ~0x7fffULL; env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); if (env->tl < MAXTL - 1) { env->tl++; } else { env->pstate |= PS_RED; if (env->tl != MAXTL) env->tl++; } env->pc = env->tbr; env->npc = env->pc + 4; env->exception_index = 0;}#else#ifdef DEBUG_PCALLstatic const char * const excp_names[0x80] = { [TT_TFAULT] = "Instruction Access Fault", [TT_ILL_INSN] = "Illegal Instruction", [TT_PRIV_INSN] = "Privileged Instruction", [TT_NFPU_INSN] = "FPU Disabled", [TT_WIN_OVF] = "Window Overflow", [TT_WIN_UNF] = "Window Underflow", [TT_UNALIGNED] = "Unaligned Memory Access", [TT_FP_EXCP] = "FPU Exception", [TT_DFAULT] = "Data Access Fault", [TT_TOVF] = "Tag Overflow", [TT_EXTINT | 0x1] = "External Interrupt 1", [TT_EXTINT | 0x2] = "External Interrupt 2", [TT_EXTINT | 0x3] = "External Interrupt 3", [TT_EXTINT | 0x4] = "External Interrupt 4", [TT_EXTINT | 0x5] = "External Interrupt 5", [TT_EXTINT | 0x6] = "External Interrupt 6", [TT_EXTINT | 0x7] = "External Interrupt 7", [TT_EXTINT | 0x8] = "External Interrupt 8", [TT_EXTINT | 0x9] = "External Interrupt 9", [TT_EXTINT | 0xa] = "External Interrupt 10", [TT_EXTINT | 0xb] = "External Interrupt 11", [TT_EXTINT | 0xc] = "External Interrupt 12", [TT_EXTINT | 0xd] = "External Interrupt 13", [TT_EXTINT | 0xe] = "External Interrupt 14", [TT_EXTINT | 0xf] = "External Interrupt 15", [TT_TOVF] = "Tag Overflow", [TT_CODE_ACCESS] = "Instruction Access Error", [TT_DATA_ACCESS] = "Data Access Error", [TT_DIV_ZERO] = "Division By Zero", [TT_NCP_INSN] = "Coprocessor Disabled",};#endifvoid do_interrupt(int intno){ int cwp;#ifdef DEBUG_PCALL if (loglevel & CPU_LOG_INT) { static int count; const char *name; if (intno < 0 || intno >= 0x100) name = "Unknown"; else if (intno >= 0x80) name = "Trap Instruction"; else { name = excp_names[intno]; if (!name) name = "Unknown"; } fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n", count, name, intno, env->pc, env->npc, env->regwptr[6]); cpu_dump_state(env, logfile, fprintf, 0);#if 0 { int i; uint8_t *ptr; fprintf(logfile, " code="); ptr = (uint8_t *)env->pc; for(i = 0; i < 16; i++) { fprintf(logfile, " %02x", ldub(ptr + i)); } fprintf(logfile, "\n"); }#endif count++; }#endif#if !defined(CONFIG_USER_ONLY) if (env->psret == 0) { cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index); return; }#endif env->psret = 0; cwp = (env->cwp - 1) & (NWINDOWS - 1); set_cwp(cwp); env->regwptr[9] = env->pc; env->regwptr[10] = env->npc; env->psrps = env->psrs; env->psrs = 1; env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); env->pc = env->tbr; env->npc = env->pc + 4; env->exception_index = 0;}#endif#if !defined(CONFIG_USER_ONLY)static void do_unaligned_access(target_ulong addr, int is_write, int is_user, void *retaddr);#define MMUSUFFIX _mmu#define ALIGNED_ONLY#ifdef __s390__# define GETPC() ((void*)((unsigned long)__builtin_return_address(0) & 0x7fffffffUL))#else# define GETPC() (__builtin_return_address(0))#endif#define SHIFT 0#include "softmmu_template.h"#define SHIFT 1#include "softmmu_template.h"#define SHIFT 2#include "softmmu_template.h"#define SHIFT 3#include "softmmu_template.h"static void do_unaligned_access(target_ulong addr, int is_write, int is_user, void *retaddr){#ifdef DEBUG_UNALIGNED printf("Unaligned access to 0x%x from 0x%x\n", addr, env->pc);#endif raise_exception(TT_UNALIGNED);}/* try to fill the TLB and return an exception if error. If retaddr is NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) *//* XXX: fix it to restore all registers */void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr){ TranslationBlock *tb; int ret; unsigned long pc; CPUState *saved_env; /* XXX: hack to restore env in all cases, even if not called from generated code */ saved_env = env; env = cpu_single_env; ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (ret) { if (retaddr) { /* now we have a real cpu fault */ pc = (unsigned long)retaddr; tb = tb_find_pc(pc); if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ cpu_restore_state(tb, env, pc, (void *)T2); } } cpu_loop_exit(); } env = saved_env;}#endif#ifndef TARGET_SPARC64void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, int is_asi){ CPUState *saved_env; /* XXX: hack to restore env in all cases, even if not called from generated code */ saved_env = env; env = cpu_single_env;#ifdef DEBUG_UNASSIGNED if (is_asi) printf("Unassigned mem %s access to " TARGET_FMT_plx " asi 0x%02x from " TARGET_FMT_lx "\n", is_exec ? "exec" : is_write ? "write" : "read", addr, is_asi, env->pc); else printf("Unassigned mem %s access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n", is_exec ? "exec" : is_write ? "write" : "read", addr, env->pc);#endif if (env->mmuregs[3]) /* Fault status register */ env->mmuregs[3] = 1; /* overflow (not read before another fault) */ if (is_asi) env->mmuregs[3] |= 1 << 16; if (env->psrs) env->mmuregs[3] |= 1 << 5; if (is_exec) env->mmuregs[3] |= 1 << 6; if (is_write) env->mmuregs[3] |= 1 << 7; env->mmuregs[3] |= (5 << 2) | 2; env->mmuregs[4] = addr; /* Fault address register */ if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) { if (is_exec) raise_exception(TT_CODE_ACCESS); else raise_exception(TT_DATA_ACCESS); } env = saved_env;}#elsevoid do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, int is_asi){#ifdef DEBUG_UNASSIGNED CPUState *saved_env; /* XXX: hack to restore env in all cases, even if not called from generated code */ saved_env = env; env = cpu_single_env; printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n", addr, env->pc); env = saved_env;#endif if (is_exec) raise_exception(TT_CODE_ACCESS); else raise_exception(TT_DATA_ACCESS);}#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -