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