⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 op_helper.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 2 页
字号:
	    oldreg = env->immuregs[reg];            switch(reg) {            case 0: // RO            case 4:                return;            case 1: // Not in I-MMU            case 2:            case 7:            case 8:                return;            case 3: // SFSR		if ((T1 & 1) == 0)		    T1 = 0; // Clear SFSR                break;            case 5: // TSB access            case 6: // Tag access            default:                break;            }	    env->immuregs[reg] = T1;#ifdef DEBUG_MMU            if (oldreg != env->immuregs[reg]) {                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);            }	    dump_mmu(env);#endif	    return;	}    case 0x54: // I-MMU data in	{	    unsigned int i;	    // Try finding an invalid entry	    for (i = 0; i < 64; i++) {		if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {		    env->itlb_tag[i] = env->immuregs[6];		    env->itlb_tte[i] = T1;		    return;		}	    }	    // Try finding an unlocked entry	    for (i = 0; i < 64; i++) {		if ((env->itlb_tte[i] & 0x40) == 0) {		    env->itlb_tag[i] = env->immuregs[6];		    env->itlb_tte[i] = T1;		    return;		}	    }	    // error state?	    return;	}    case 0x55: // I-MMU data access	{	    unsigned int i = (T0 >> 3) & 0x3f;	    env->itlb_tag[i] = env->immuregs[6];	    env->itlb_tte[i] = T1;	    return;	}    case 0x57: // I-MMU demap	// XXX	return;    case 0x58: // D-MMU regs	{	    int reg = (T0 >> 3) & 0xf;	    uint64_t oldreg;	    	    oldreg = env->dmmuregs[reg];            switch(reg) {            case 0: // RO            case 4:                return;            case 3: // SFSR		if ((T1 & 1) == 0) {		    T1 = 0; // Clear SFSR, Fault address		    env->dmmuregs[4] = 0;		}		env->dmmuregs[reg] = T1;                break;            case 1: // Primary context            case 2: // Secondary context            case 5: // TSB access            case 6: // Tag access            case 7: // Virtual Watchpoint            case 8: // Physical Watchpoint            default:                break;            }	    env->dmmuregs[reg] = T1;#ifdef DEBUG_MMU            if (oldreg != env->dmmuregs[reg]) {                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);            }	    dump_mmu(env);#endif	    return;	}    case 0x5c: // D-MMU data in	{	    unsigned int i;	    // Try finding an invalid entry	    for (i = 0; i < 64; i++) {		if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {		    env->dtlb_tag[i] = env->dmmuregs[6];		    env->dtlb_tte[i] = T1;		    return;		}	    }	    // Try finding an unlocked entry	    for (i = 0; i < 64; i++) {		if ((env->dtlb_tte[i] & 0x40) == 0) {		    env->dtlb_tag[i] = env->dmmuregs[6];		    env->dtlb_tte[i] = T1;		    return;		}	    }	    // error state?	    return;	}    case 0x5d: // D-MMU data access	{	    unsigned int i = (T0 >> 3) & 0x3f;	    env->dtlb_tag[i] = env->dmmuregs[6];	    env->dtlb_tte[i] = T1;	    return;	}    case 0x5f: // D-MMU demap    case 0x49: // Interrupt data receive	// XXX	return;    case 0x51: // I-MMU 8k TSB pointer, RO    case 0x52: // I-MMU 64k TSB pointer, RO    case 0x56: // I-MMU tag read, RO    case 0x59: // D-MMU 8k TSB pointer, RO    case 0x5a: // D-MMU 64k TSB pointer, RO    case 0x5b: // D-MMU data pointer, RO    case 0x5e: // D-MMU tag read, RO    case 0x48: // Interrupt dispatch, RO    case 0x7f: // Incoming interrupt vector, RO    case 0x82: // Primary no-fault, RO    case 0x83: // Secondary no-fault, RO    case 0x8a: // Primary no-fault LE, RO    case 0x8b: // Secondary no-fault LE, RO    default:	return;    }}#endif#endif /* !CONFIG_USER_ONLY */#ifndef TARGET_SPARC64void helper_rett(){    unsigned int cwp;    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(){    PUT_PSR(env, T0);}void do_rdpsr(){    T0 = GET_PSR(env);}#elsevoid do_popc(){    T0 = (T1 & 0x5555555555555555ULL) + ((T1 >> 1) & 0x5555555555555555ULL);    T0 = (T0 & 0x3333333333333333ULL) + ((T0 >> 2) & 0x3333333333333333ULL);    T0 = (T0 & 0x0f0f0f0f0f0f0f0fULL) + ((T0 >> 4) & 0x0f0f0f0f0f0f0f0fULL);    T0 = (T0 & 0x00ff00ff00ff00ffULL) + ((T0 >> 8) & 0x00ff00ff00ff00ffULL);    T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);    T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);}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;    }}void do_wrpstate(){    uint64_t new_pstate, pstate_regs, new_pstate_regs;    uint64_t *src, *dst;    new_pstate = T0 & 0xf3f;    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_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;    env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;    set_cwp(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;    env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;    set_cwp(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_SPARC64void do_interrupt(int intno){#ifdef DEBUG_PCALL    if (loglevel & CPU_LOG_INT) {	static int count;	fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",                count, 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 & 0xfff) << 8) | (env->cwp & 0xff);    env->tpc[env->tl] = env->pc;    env->tnpc[env->tl] = env->npc;    env->tt[env->tl] = intno;    env->pstate = PS_PEF | PS_PRIV | PS_AG;    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;}#elsevoid do_interrupt(int intno){    int cwp;#ifdef DEBUG_PCALL    if (loglevel & CPU_LOG_INT) {	static int count;	fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",                count, 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) #define MMUSUFFIX _mmu#define GETPC() (__builtin_return_address(0))#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"/* 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 is_user, 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, is_user, 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -