op_helper.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,373 行 · 第 1/5 页
C
2,373 行
tlb_flush(env, 1); } return; } case 0x50: // I-MMU regs { int reg = (addr >> 3) & 0xf; uint64_t oldreg; 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 ((val & 1) == 0) val = 0; // Clear SFSR break; case 5: // TSB access case 6: // Tag access default: break; } env->immuregs[reg] = val; if (oldreg != env->immuregs[reg]) { DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]); }#ifdef DEBUG_MMU 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] = val; 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] = val; return; } } // error state? return; } case 0x55: // I-MMU data access { unsigned int i = (addr >> 3) & 0x3f; env->itlb_tag[i] = env->immuregs[6]; env->itlb_tte[i] = val; return; } case 0x57: // I-MMU demap // XXX return; case 0x58: // D-MMU regs { int reg = (addr >> 3) & 0xf; uint64_t oldreg; oldreg = env->dmmuregs[reg]; switch(reg) { case 0: // RO case 4: return; case 3: // SFSR if ((val & 1) == 0) { val = 0; // Clear SFSR, Fault address env->dmmuregs[4] = 0; } env->dmmuregs[reg] = val; 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] = val; if (oldreg != env->dmmuregs[reg]) { DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]); }#ifdef DEBUG_MMU 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] = val; 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] = val; return; } } // error state? return; } case 0x5d: // D-MMU data access { unsigned int i = (addr >> 3) & 0x3f; env->dtlb_tag[i] = env->dmmuregs[6]; env->dtlb_tte[i] = val; 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: do_unassigned_access(addr, 1, 0, 1); return; }}#endif /* CONFIG_USER_ONLY */void helper_ldf_asi(target_ulong addr, int asi, int size, int rd){ unsigned int i; target_ulong val; helper_check_align(addr, 3); switch (asi) { case 0xf0: // Block load primary case 0xf1: // Block load secondary case 0xf8: // Block load primary LE case 0xf9: // Block load secondary LE if (rd & 7) { raise_exception(TT_ILL_INSN); return; } helper_check_align(addr, 0x3f); for (i = 0; i < 16; i++) { *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4, 0); addr += 4; } return; default: break; } val = helper_ld_asi(addr, asi, size, 0); switch(size) { default: case 4: *((uint32_t *)&FT0) = val; break; case 8: *((int64_t *)&DT0) = val; break; case 16: // XXX break; }}void helper_stf_asi(target_ulong addr, int asi, int size, int rd){ unsigned int i; target_ulong val = 0; helper_check_align(addr, 3); switch (asi) { case 0xf0: // Block store primary case 0xf1: // Block store secondary case 0xf8: // Block store primary LE case 0xf9: // Block store secondary LE if (rd & 7) { raise_exception(TT_ILL_INSN); return; } helper_check_align(addr, 0x3f); for (i = 0; i < 16; i++) { val = *(uint32_t *)&env->fpr[rd++]; helper_st_asi(addr, val, asi & 0x8f, 4); addr += 4; } return; default: break; } switch(size) { default: case 4: val = *((uint32_t *)&FT0); break; case 8: val = *((int64_t *)&DT0); break; case 16: // XXX break; } helper_st_asi(addr, val, asi, size);}target_ulong helper_cas_asi(target_ulong addr, target_ulong val1, target_ulong val2, uint32_t asi){ target_ulong ret; val1 &= 0xffffffffUL; ret = helper_ld_asi(addr, asi, 4, 0); ret &= 0xffffffffUL; if (val1 == ret) helper_st_asi(addr, val2 & 0xffffffffUL, asi, 4); return ret;}target_ulong helper_casx_asi(target_ulong addr, target_ulong val1, target_ulong val2, uint32_t asi){ target_ulong ret; ret = helper_ld_asi(addr, asi, 8, 0); if (val1 == ret) helper_st_asi(addr, val2, asi, 8); return ret;}#endif /* TARGET_SPARC64 */#ifndef TARGET_SPARC64void helper_rett(void){ 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;}#endiftarget_ulong helper_udiv(target_ulong a, target_ulong b){ uint64_t x0; uint32_t x1; x0 = a | ((uint64_t) (env->y) << 32); x1 = b; if (x1 == 0) { raise_exception(TT_DIV_ZERO); } x0 = x0 / x1; if (x0 > 0xffffffff) { env->cc_src2 = 1; return 0xffffffff; } else { env->cc_src2 = 0; return x0; }}target_ulong helper_sdiv(target_ulong a, target_ulong b){ int64_t x0; int32_t x1; x0 = a | ((int64_t) (env->y) << 32); x1 = b; if (x1 == 0) { raise_exception(TT_DIV_ZERO); } x0 = x0 / x1; if ((int32_t) x0 != x0) { env->cc_src2 = 1; return x0 < 0? 0x80000000: 0x7fffffff; } else { env->cc_src2 = 0; return x0; }}uint64_t helper_pack64(target_ulong high, target_ulong low){ return ((uint64_t)high << 32) | (uint64_t)(low & 0xffffffff);}void helper_stdf(target_ulong addr, int mem_idx){ helper_check_align(addr, 7);#if !defined(CONFIG_USER_ONLY) switch (mem_idx) { case 0: stfq_user(addr, DT0); break; case 1: stfq_kernel(addr, DT0); break;#ifdef TARGET_SPARC64 case 2: stfq_hypv(addr, DT0); break;#endif default: break; }#else ABI32_MASK(addr); stfq_raw(addr, DT0);#endif}void helper_lddf(target_ulong addr, int mem_idx){ helper_check_align(addr, 7);#if !defined(CONFIG_USER_ONLY) switch (mem_idx) { case 0: DT0 = ldfq_user(addr); break; case 1: DT0 = ldfq_kernel(addr); break;#ifdef TARGET_SPARC64 case 2: DT0 = ldfq_hypv(addr); break;#endif default: break; }#else ABI32_MASK(addr); DT0 = ldfq_raw(addr);#endif}void helper_ldqf(target_ulong addr, int mem_idx){ // XXX add 128 bit load CPU_QuadU u; helper_check_align(addr, 7);#if !defined(CONFIG_USER_ONLY) switch (mem_idx) { case 0: u.ll.upper = ldq_user(addr); u.ll.lower = ldq_user(addr + 8); QT0 = u.q; break; case 1: u.ll.upper = ldq_kernel(addr); u.ll.lower = ldq_kernel(addr + 8); QT0 = u.q; break;#ifdef TARGET_SPARC64 case 2: u.ll.upper = ldq_hypv(addr); u.ll.lower = ldq_hypv(addr + 8); QT0 = u.q; break;#endif default: break; }#else ABI32_MASK(addr); u.ll.upper = ldq_raw(addr); u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL); QT0 = u.q;#endif}void helper_stqf(target_ulong addr, int mem_idx){ // XXX add 128 bit store CPU_QuadU u; helper_check_align(addr, 7);#if !defined(CONFIG_USER_ONLY) switch (mem_idx) { case 0: u.q = QT0; stq_user(addr, u.ll.upper); stq_user(addr + 8, u.ll.lower); break; case 1: u.q = QT0; stq_kernel(addr, u.ll.upper); stq_kernel(addr + 8, u.ll.lower); break;#ifdef TARGET_SPARC64 case 2: u.q = QT0; stq_hypv(addr, u.ll.upper); stq_hypv(addr + 8, u.ll.lower); break;#endif default: break; }#else u.q = QT0; ABI32_MASK(addr); stq_raw(addr, u.ll.upper); stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower);#endif}void helper_ldfsr(void){ int rnd_mode; PUT_FSR32(env, *((uint32_t *) &FT0)); switch (env->fsr & FSR_RD_MASK) { case FSR_RD_NEAREST: rnd_mode = float_round_nearest_even; break; default: case FSR_RD_ZERO: rnd_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?