186797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* 286797937017f52bff088d02edf64fb931177a7eaJun Nakajima * i386 execution defines 386797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 486797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Copyright (c) 2003 Fabrice Bellard 586797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * This library is free software; you can redistribute it and/or 786797937017f52bff088d02edf64fb931177a7eaJun Nakajima * modify it under the terms of the GNU Lesser General Public 886797937017f52bff088d02edf64fb931177a7eaJun Nakajima * License as published by the Free Software Foundation; either 986797937017f52bff088d02edf64fb931177a7eaJun Nakajima * version 2 of the License, or (at your option) any later version. 1086797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 1186797937017f52bff088d02edf64fb931177a7eaJun Nakajima * This library is distributed in the hope that it will be useful, 1286797937017f52bff088d02edf64fb931177a7eaJun Nakajima * but WITHOUT ANY WARRANTY; without even the implied warranty of 1386797937017f52bff088d02edf64fb931177a7eaJun Nakajima * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1486797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Lesser General Public License for more details. 1586797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 1686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * You should have received a copy of the GNU Lesser General Public 1786797937017f52bff088d02edf64fb931177a7eaJun Nakajima * License along with this library; if not, write to the Free Software 1886797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 1986797937017f52bff088d02edf64fb931177a7eaJun Nakajima */ 2086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "config.h" 2186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "dyngen-exec.h" 2286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 2386797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* XXX: factorize this mess */ 2486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef TARGET_X86_64 2586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define TARGET_LONG_BITS 64 2686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else 2786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define TARGET_LONG_BITS 32 2886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 2986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 3086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "cpu-defs.h" 3186797937017f52bff088d02edf64fb931177a7eaJun Nakajima 320b3979707c09e058442c22d046b326ce244edda1Andrew HsiehGLOBAL_REGISTER_VARIABLE_DECL struct CPUX86State *env asm(AREG0); 3386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 3486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "qemu-common.h" 3586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "qemu-log.h" 3686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 3786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EAX (env->regs[R_EAX]) 3886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define ECX (env->regs[R_ECX]) 3986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EDX (env->regs[R_EDX]) 4086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EBX (env->regs[R_EBX]) 4186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define ESP (env->regs[R_ESP]) 4286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EBP (env->regs[R_EBP]) 4386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define ESI (env->regs[R_ESI]) 4486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EDI (env->regs[R_EDI]) 4586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EIP (env->eip) 4686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define DF (env->df) 4786797937017f52bff088d02edf64fb931177a7eaJun Nakajima 4886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define CC_SRC (env->cc_src) 4986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define CC_DST (env->cc_dst) 5086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define CC_OP (env->cc_op) 5186797937017f52bff088d02edf64fb931177a7eaJun Nakajima 5286797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* float macros */ 5386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FT0 (env->ft0) 5486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define ST0 (env->fpregs[env->fpstt].d) 5586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d) 5686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define ST1 ST(1) 5786797937017f52bff088d02edf64fb931177a7eaJun Nakajima 5886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "cpu.h" 5986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "exec-all.h" 6086797937017f52bff088d02edf64fb931177a7eaJun Nakajima 6186797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* op_helper.c */ 6286797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid do_interrupt(int intno, int is_int, int error_code, 6386797937017f52bff088d02edf64fb931177a7eaJun Nakajima target_ulong next_eip, int is_hw); 6486797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid do_interrupt_user(int intno, int is_int, int error_code, 6586797937017f52bff088d02edf64fb931177a7eaJun Nakajima target_ulong next_eip); 6686797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid QEMU_NORETURN raise_exception_err(int exception_index, int error_code); 6786797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid QEMU_NORETURN raise_exception(int exception_index); 6886797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid do_smm_enter(void); 6986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 7086797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* n must be a constant to be efficient */ 7186797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline target_long lshift(target_long x, int n) 7286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 7386797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (n >= 0) 7486797937017f52bff088d02edf64fb931177a7eaJun Nakajima return x << n; 7586797937017f52bff088d02edf64fb931177a7eaJun Nakajima else 7686797937017f52bff088d02edf64fb931177a7eaJun Nakajima return x >> (-n); 7786797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 7886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 7986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "helper.h" 8086797937017f52bff088d02edf64fb931177a7eaJun Nakajima 8186797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void svm_check_intercept(uint32_t type) 8286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 8386797937017f52bff088d02edf64fb931177a7eaJun Nakajima helper_svm_check_intercept_param(type, 0); 8486797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 8586797937017f52bff088d02edf64fb931177a7eaJun Nakajima 8686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if !defined(CONFIG_USER_ONLY) 8786797937017f52bff088d02edf64fb931177a7eaJun Nakajima 8886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "softmmu_exec.h" 8986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 9086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif /* !defined(CONFIG_USER_ONLY) */ 9186797937017f52bff088d02edf64fb931177a7eaJun Nakajima 9286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef USE_X86LDOUBLE 9386797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* use long double functions */ 9486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int32 floatx80_to_int32 9586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int64 floatx80_to_int64 9686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero 9786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero 9886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define int32_to_floatx int32_to_floatx80 9986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define int64_to_floatx int64_to_floatx80 10086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define float32_to_floatx float32_to_floatx80 10186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define float64_to_floatx float64_to_floatx80 10286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_float32 floatx80_to_float32 10386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_float64 floatx80_to_float64 10486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_abs floatx80_abs 10586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_chs floatx80_chs 10686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_round_to_int floatx80_round_to_int 10786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_compare floatx80_compare 10886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_compare_quiet floatx80_compare_quiet 10986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else 11086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int32 float64_to_int32 11186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int64 float64_to_int64 11286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero 11386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero 11486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define int32_to_floatx int32_to_float64 11586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define int64_to_floatx int64_to_float64 11686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define float32_to_floatx float32_to_float64 11786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define float64_to_floatx(x, e) (x) 11886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_float32 float64_to_float32 11986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_to_float64(x, e) (x) 12086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_abs float64_abs 12186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_chs float64_chs 12286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_round_to_int float64_round_to_int 12386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_compare float64_compare 12486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define floatx_compare_quiet float64_compare_quiet 12586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 12686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 12786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define RC_MASK 0xc00 12886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define RC_NEAR 0x000 12986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define RC_DOWN 0x400 13086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define RC_UP 0x800 13186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define RC_CHOP 0xc00 13286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 13386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define MAXTAN 9223372036854775808.0 13486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 13586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef USE_X86LDOUBLE 13686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 13786797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* only for x86 */ 13886797937017f52bff088d02edf64fb931177a7eaJun Nakajimatypedef union { 13986797937017f52bff088d02edf64fb931177a7eaJun Nakajima long double d; 14086797937017f52bff088d02edf64fb931177a7eaJun Nakajima struct { 14186797937017f52bff088d02edf64fb931177a7eaJun Nakajima unsigned long long lower; 14286797937017f52bff088d02edf64fb931177a7eaJun Nakajima unsigned short upper; 14386797937017f52bff088d02edf64fb931177a7eaJun Nakajima } l; 14486797937017f52bff088d02edf64fb931177a7eaJun Nakajima} CPU86_LDoubleU; 14586797937017f52bff088d02edf64fb931177a7eaJun Nakajima 14686797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* the following deal with x86 long double-precision numbers */ 14786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define MAXEXPD 0x7fff 14886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EXPBIAS 16383 14986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EXPD(fp) (fp.l.upper & 0x7fff) 15086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define SIGND(fp) ((fp.l.upper) & 0x8000) 15186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define MANTD(fp) (fp.l.lower) 15286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS 15386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 15486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else 15586797937017f52bff088d02edf64fb931177a7eaJun Nakajima 15686797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ 15786797937017f52bff088d02edf64fb931177a7eaJun Nakajimatypedef union { 15886797937017f52bff088d02edf64fb931177a7eaJun Nakajima double d; 15986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#if !defined(WORDS_BIGENDIAN) && !defined(__arm__) 16086797937017f52bff088d02edf64fb931177a7eaJun Nakajima struct { 16186797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint32_t lower; 16286797937017f52bff088d02edf64fb931177a7eaJun Nakajima int32_t upper; 16386797937017f52bff088d02edf64fb931177a7eaJun Nakajima } l; 16486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else 16586797937017f52bff088d02edf64fb931177a7eaJun Nakajima struct { 16686797937017f52bff088d02edf64fb931177a7eaJun Nakajima int32_t upper; 16786797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint32_t lower; 16886797937017f52bff088d02edf64fb931177a7eaJun Nakajima } l; 16986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 17086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifndef __arm__ 17186797937017f52bff088d02edf64fb931177a7eaJun Nakajima int64_t ll; 17286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 17386797937017f52bff088d02edf64fb931177a7eaJun Nakajima} CPU86_LDoubleU; 17486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 17586797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* the following deal with IEEE double-precision numbers */ 17686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define MAXEXPD 0x7ff 17786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EXPBIAS 1023 17886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) 17986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define SIGND(fp) ((fp.l.upper) & 0x80000000) 18086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef __arm__ 18186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define MANTD(fp) (fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32)) 18286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else 18386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) 18486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 18586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) 18686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 18786797937017f52bff088d02edf64fb931177a7eaJun Nakajima 18886797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void fpush(void) 18986797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 19086797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->fpstt = (env->fpstt - 1) & 7; 19186797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->fptags[env->fpstt] = 0; /* validate stack entry */ 19286797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 19386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 19486797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void fpop(void) 19586797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 19686797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ 19786797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->fpstt = (env->fpstt + 1) & 7; 19886797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 19986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 20086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifndef USE_X86LDOUBLE 20186797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline CPU86_LDouble helper_fldt(target_ulong ptr) 20286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 20386797937017f52bff088d02edf64fb931177a7eaJun Nakajima CPU86_LDoubleU temp; 20486797937017f52bff088d02edf64fb931177a7eaJun Nakajima int upper, e; 20586797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint64_t ll; 20686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 20786797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* mantissa */ 20886797937017f52bff088d02edf64fb931177a7eaJun Nakajima upper = lduw(ptr + 8); 20986797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* XXX: handle overflow ? */ 21086797937017f52bff088d02edf64fb931177a7eaJun Nakajima e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ 21186797937017f52bff088d02edf64fb931177a7eaJun Nakajima e |= (upper >> 4) & 0x800; /* sign */ 21286797937017f52bff088d02edf64fb931177a7eaJun Nakajima ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1); 21386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef __arm__ 21486797937017f52bff088d02edf64fb931177a7eaJun Nakajima temp.l.upper = (e << 20) | (ll >> 32); 21586797937017f52bff088d02edf64fb931177a7eaJun Nakajima temp.l.lower = ll; 21686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else 21786797937017f52bff088d02edf64fb931177a7eaJun Nakajima temp.ll = ll | ((uint64_t)e << 52); 21886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 21986797937017f52bff088d02edf64fb931177a7eaJun Nakajima return temp.d; 22086797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 22186797937017f52bff088d02edf64fb931177a7eaJun Nakajima 22286797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) 22386797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 22486797937017f52bff088d02edf64fb931177a7eaJun Nakajima CPU86_LDoubleU temp; 22586797937017f52bff088d02edf64fb931177a7eaJun Nakajima int e; 22686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 22786797937017f52bff088d02edf64fb931177a7eaJun Nakajima temp.d = f; 22886797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* mantissa */ 22986797937017f52bff088d02edf64fb931177a7eaJun Nakajima stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); 23086797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* exponent + sign */ 23186797937017f52bff088d02edf64fb931177a7eaJun Nakajima e = EXPD(temp) - EXPBIAS + 16383; 23286797937017f52bff088d02edf64fb931177a7eaJun Nakajima e |= SIGND(temp) >> 16; 23386797937017f52bff088d02edf64fb931177a7eaJun Nakajima stw(ptr + 8, e); 23486797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 23586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#else 23686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 23786797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* we use memory access macros */ 23886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 23986797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline CPU86_LDouble helper_fldt(target_ulong ptr) 24086797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 24186797937017f52bff088d02edf64fb931177a7eaJun Nakajima CPU86_LDoubleU temp; 24286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 24386797937017f52bff088d02edf64fb931177a7eaJun Nakajima temp.l.lower = ldq(ptr); 24486797937017f52bff088d02edf64fb931177a7eaJun Nakajima temp.l.upper = lduw(ptr + 8); 24586797937017f52bff088d02edf64fb931177a7eaJun Nakajima return temp.d; 24686797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 24786797937017f52bff088d02edf64fb931177a7eaJun Nakajima 24886797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) 24986797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 25086797937017f52bff088d02edf64fb931177a7eaJun Nakajima CPU86_LDoubleU temp; 25186797937017f52bff088d02edf64fb931177a7eaJun Nakajima 25286797937017f52bff088d02edf64fb931177a7eaJun Nakajima temp.d = f; 25386797937017f52bff088d02edf64fb931177a7eaJun Nakajima stq(ptr, temp.l.lower); 25486797937017f52bff088d02edf64fb931177a7eaJun Nakajima stw(ptr + 8, temp.l.upper); 25586797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 25686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 25786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif /* USE_X86LDOUBLE */ 25886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 25986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_IE (1 << 0) 26086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_DE (1 << 1) 26186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_ZE (1 << 2) 26286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_OE (1 << 3) 26386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_UE (1 << 4) 26486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_PE (1 << 5) 26586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_SF (1 << 6) 26686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_SE (1 << 7) 26786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUS_B (1 << 15) 26886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 26986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define FPUC_EM 0x3f 27086797937017f52bff088d02edf64fb931177a7eaJun Nakajima 27186797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline uint32_t compute_eflags(void) 27286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 27386797937017f52bff088d02edf64fb931177a7eaJun Nakajima return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); 27486797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 27586797937017f52bff088d02edf64fb931177a7eaJun Nakajima 27686797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */ 27786797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void load_eflags(int eflags, int update_mask) 27886797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 27986797937017f52bff088d02edf64fb931177a7eaJun Nakajima CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 28086797937017f52bff088d02edf64fb931177a7eaJun Nakajima DF = 1 - (2 * ((eflags >> 10) & 1)); 28186797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->eflags = (env->eflags & ~update_mask) | 28286797937017f52bff088d02edf64fb931177a7eaJun Nakajima (eflags & update_mask) | 0x2; 28386797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 28486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 28586797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void env_to_regs(void) 28686797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 28786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EAX 28886797937017f52bff088d02edf64fb931177a7eaJun Nakajima EAX = env->regs[R_EAX]; 28986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 29086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_ECX 29186797937017f52bff088d02edf64fb931177a7eaJun Nakajima ECX = env->regs[R_ECX]; 29286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 29386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EDX 29486797937017f52bff088d02edf64fb931177a7eaJun Nakajima EDX = env->regs[R_EDX]; 29586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 29686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EBX 29786797937017f52bff088d02edf64fb931177a7eaJun Nakajima EBX = env->regs[R_EBX]; 29886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 29986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_ESP 30086797937017f52bff088d02edf64fb931177a7eaJun Nakajima ESP = env->regs[R_ESP]; 30186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 30286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EBP 30386797937017f52bff088d02edf64fb931177a7eaJun Nakajima EBP = env->regs[R_EBP]; 30486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 30586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_ESI 30686797937017f52bff088d02edf64fb931177a7eaJun Nakajima ESI = env->regs[R_ESI]; 30786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 30886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EDI 30986797937017f52bff088d02edf64fb931177a7eaJun Nakajima EDI = env->regs[R_EDI]; 31086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 31186797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 31286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 31386797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void regs_to_env(void) 31486797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 31586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EAX 31686797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_EAX] = EAX; 31786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 31886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_ECX 31986797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_ECX] = ECX; 32086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 32186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EDX 32286797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_EDX] = EDX; 32386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 32486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EBX 32586797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_EBX] = EBX; 32686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 32786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_ESP 32886797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_ESP] = ESP; 32986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 33086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EBP 33186797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_EBP] = EBP; 33286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 33386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_ESI 33486797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_ESI] = ESI; 33586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 33686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef reg_EDI 33786797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->regs[R_EDI] = EDI; 33886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 33986797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 34086797937017f52bff088d02edf64fb931177a7eaJun Nakajima 34186797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline int cpu_has_work(CPUState *env) 34286797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 34386797937017f52bff088d02edf64fb931177a7eaJun Nakajima int work; 34486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 34586797937017f52bff088d02edf64fb931177a7eaJun Nakajima work = (env->interrupt_request & CPU_INTERRUPT_HARD) && 34686797937017f52bff088d02edf64fb931177a7eaJun Nakajima (env->eflags & IF_MASK); 34786797937017f52bff088d02edf64fb931177a7eaJun Nakajima work |= env->interrupt_request & CPU_INTERRUPT_NMI; 34886797937017f52bff088d02edf64fb931177a7eaJun Nakajima work |= env->interrupt_request & CPU_INTERRUPT_INIT; 34986797937017f52bff088d02edf64fb931177a7eaJun Nakajima work |= env->interrupt_request & CPU_INTERRUPT_SIPI; 35086797937017f52bff088d02edf64fb931177a7eaJun Nakajima 35186797937017f52bff088d02edf64fb931177a7eaJun Nakajima return work; 35286797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 35386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 35486797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline int cpu_halted(CPUState *env) { 35586797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* handle exit of HALTED state */ 35686797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (!env->halted) 35786797937017f52bff088d02edf64fb931177a7eaJun Nakajima return 0; 35886797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* disable halt condition */ 35986797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (cpu_has_work(env)) { 36086797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->halted = 0; 36186797937017f52bff088d02edf64fb931177a7eaJun Nakajima return 0; 36286797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 36386797937017f52bff088d02edf64fb931177a7eaJun Nakajima return EXCP_HALTED; 36486797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 36586797937017f52bff088d02edf64fb931177a7eaJun Nakajima 36686797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* load efer and update the corresponding hflags. XXX: do consistency 36786797937017f52bff088d02edf64fb931177a7eaJun Nakajima checks with cpuid bits ? */ 36886797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic inline void cpu_load_efer(CPUState *env, uint64_t val) 36986797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 37086797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->efer = val; 37186797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); 37286797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (env->efer & MSR_EFER_LMA) 37386797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->hflags |= HF_LMA_MASK; 37486797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (env->efer & MSR_EFER_SVME) 37586797937017f52bff088d02edf64fb931177a7eaJun Nakajima env->hflags |= HF_SVME_MASK; 37686797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 377