void helper_cmpxchg16b(CPUX86State *env, target_ulong a0) { uintptr_t ra = GETPC(); if ((a0 & 0xf) != 0) { raise_exception_ra(env, EXCP0D_GPF, ra); } else { #ifndef CONFIG_ATOMIC128 cpu_loop_exit_atomic(ENV_GET_CPU(env), ra); #else int eflags = cpu_cc_compute_all(env, CC_OP); Int128 cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]); Int128 newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]); int mem_idx = cpu_mmu_index(env, false); TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx); Int128 oldv = helper_atomic_cmpxchgo_le_mmu(env, a0, cmpv, newv, oi, ra); if (int128_eq(oldv, cmpv)) { eflags |= CC_Z; } else { env->regs[R_EAX] = int128_getlo(oldv); env->regs[R_EDX] = int128_gethi(oldv); eflags &= ~CC_Z; } CC_SRC = eflags; #endif } }
void helper_bndck(CPUX86State *env, uint32_t fail) { if (unlikely(fail)) { env->bndcs_regs.sts = 1; raise_exception_ra(env, EXCP05_BOUND, GETPC()); } }
void helper_sti_vm(CPUX86State *env) { env->eflags |= VIF_MASK; if (env->eflags & VIP_MASK) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } }
void helper_monitor(CPUX86State *env, target_ulong ptr) { if ((uint32_t)env->regs[R_ECX] != 0) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } /* XXX: store address? */ cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC()); }
void helper_rdpmc(CPUX86State *env) { if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0, GETPC()); /* currently unimplemented */ qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n"); raise_exception_err(env, EXCP06_ILLOP, 0); }
void helper_boundl(CPUX86State *env, target_ulong a0, int v) { int low, high; low = cpu_ldl_data_ra(env, a0, GETPC()); high = cpu_ldl_data_ra(env, a0 + 4, GETPC()); if (v < low || v > high) { if (env->hflags & HF_MPX_EN_MASK) { env->bndcs_regs.sts = 0; } raise_exception_ra(env, EXCP05_BOUND, GETPC()); } }
void helper_rdtsc(CPUX86State *env) { uint64_t val; if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0); val = cpu_get_tsc(env) + env->tsc_offset; env->regs[R_EAX] = (uint32_t)(val); env->regs[R_EDX] = (uint32_t)(val >> 32); }
static uint32_t lookup_bte32(CPUX86State *env, uint32_t base, uintptr_t ra) { uint32_t bndcsr, bde, bt; if ((env->hflags & HF_CPL_MASK) == 3) { bndcsr = env->bndcs_regs.cfgu; } else { bndcsr = env->msr_bndcfgs; } bde = (extract32(base, 12, 20) << 2) + (bndcsr & TARGET_PAGE_MASK); bt = cpu_ldl_data_ra(env, bde, ra); if ((bt & 1) == 0) { env->bndcs_regs.sts = bde | 2; raise_exception_ra(env, EXCP05_BOUND, ra); } return (extract32(base, 2, 10) << 4) + (bt & ~3); }
static uint64_t lookup_bte64(CPUX86State *env, uint64_t base, uintptr_t ra) { uint64_t bndcsr, bde, bt; if ((env->hflags & HF_CPL_MASK) == 3) { bndcsr = env->bndcs_regs.cfgu; } else { bndcsr = env->msr_bndcfgs; } bde = (extract64(base, 20, 28) << 3) + (extract64(bndcsr, 20, 44) << 12); bt = cpu_ldq_data_ra(env, bde, ra); if ((bt & 1) == 0) { env->bndcs_regs.sts = bde | 2; raise_exception_ra(env, EXCP05_BOUND, ra); } return (extract64(base, 3, 17) << 5) + (bt & ~7); }
void helper_mwait(CPUX86State *env, int next_eip_addend) { CPUState *cs; X86CPU *cpu; if ((uint32_t)env->regs[R_ECX] != 0) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC()); env->eip += next_eip_addend; cpu = x86_env_get_cpu(env); cs = CPU(cpu); /* XXX: not complete but not completely erroneous */ if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) { do_pause(cpu); } else { do_hlt(cpu); } }
void helper_rdtsc(CPUX86State *env) { uint64_t val; if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0, GETPC()); #ifdef CONFIG_SOFTMMU RR_DO_RECORD_OR_REPLAY( /*action=*/val = cpu_get_tsc(env) + env->tsc_offset, /*record=*/rr_input_8(&val), /*replay=*/rr_input_8(&val), /*location=*/RR_CALLSITE_RDTSC); #else val = cpu_get_tsc(env) + env->tsc_offset; #endif env->regs[R_EAX] = (uint32_t)(val); env->regs[R_EDX] = (uint32_t)(val >> 32); }
void helper_cmpxchg16b_unlocked(CPUX86State *env, target_ulong a0) { uintptr_t ra = GETPC(); Int128 oldv, cmpv, newv; uint64_t o0, o1; int eflags; bool success; if ((a0 & 0xf) != 0) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } eflags = cpu_cc_compute_all(env, CC_OP); cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]); newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]); o0 = cpu_ldq_data_ra(env, a0 + 0, ra); o1 = cpu_ldq_data_ra(env, a0 + 8, ra); oldv = int128_make128(o0, o1); success = int128_eq(oldv, cmpv); if (!success) { newv = oldv; } cpu_stq_data_ra(env, a0 + 0, int128_getlo(newv), ra); cpu_stq_data_ra(env, a0 + 8, int128_gethi(newv), ra); if (success) { eflags |= CC_Z; } else { env->regs[R_EAX] = int128_getlo(oldv); env->regs[R_EDX] = int128_gethi(oldv); eflags &= ~CC_Z; } CC_SRC = eflags; }