Statistics
| Branch: | Revision:

root / target-i386 / exec.h @ 66fcf8ff

History | View | Annotate | Download (5.1 kB)

1
/*
2
 *  i386 execution defines
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include "config.h"
20
#include "dyngen-exec.h"
21

    
22
/* XXX: factorize this mess */
23
#ifdef TARGET_X86_64
24
#define TARGET_LONG_BITS 64
25
#else
26
#define TARGET_LONG_BITS 32
27
#endif
28

    
29
#include "cpu-defs.h"
30

    
31
register struct CPUX86State *env asm(AREG0);
32

    
33
#include "qemu-common.h"
34
#include "qemu-log.h"
35

    
36
#undef EAX
37
#define EAX (env->regs[R_EAX])
38
#undef ECX
39
#define ECX (env->regs[R_ECX])
40
#undef EDX
41
#define EDX (env->regs[R_EDX])
42
#undef EBX
43
#define EBX (env->regs[R_EBX])
44
#undef ESP
45
#define ESP (env->regs[R_ESP])
46
#undef EBP
47
#define EBP (env->regs[R_EBP])
48
#undef ESI
49
#define ESI (env->regs[R_ESI])
50
#undef EDI
51
#define EDI (env->regs[R_EDI])
52
#undef EIP
53
#define EIP (env->eip)
54
#define DF  (env->df)
55

    
56
#define CC_SRC (env->cc_src)
57
#define CC_DST (env->cc_dst)
58
#define CC_OP  (env->cc_op)
59

    
60
/* float macros */
61
#define FT0    (env->ft0)
62
#define ST0    (env->fpregs[env->fpstt].d)
63
#define ST(n)  (env->fpregs[(env->fpstt + (n)) & 7].d)
64
#define ST1    ST(1)
65

    
66
#include "cpu.h"
67
#include "exec-all.h"
68

    
69
/* op_helper.c */
70
void do_interrupt(int intno, int is_int, int error_code,
71
                  target_ulong next_eip, int is_hw);
72
void do_interrupt_user(int intno, int is_int, int error_code,
73
                       target_ulong next_eip);
74
void QEMU_NORETURN raise_exception_err(int exception_index, int error_code);
75
void QEMU_NORETURN raise_exception(int exception_index);
76
void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv);
77
void do_smm_enter(void);
78

    
79
/* n must be a constant to be efficient */
80
static inline target_long lshift(target_long x, int n)
81
{
82
    if (n >= 0)
83
        return x << n;
84
    else
85
        return x >> (-n);
86
}
87

    
88
#include "helper.h"
89

    
90
static inline void svm_check_intercept(uint32_t type)
91
{
92
    helper_svm_check_intercept_param(type, 0);
93
}
94

    
95
#if !defined(CONFIG_USER_ONLY)
96

    
97
#include "softmmu_exec.h"
98

    
99
#endif /* !defined(CONFIG_USER_ONLY) */
100

    
101
#define RC_MASK         0xc00
102
#define RC_NEAR                0x000
103
#define RC_DOWN                0x400
104
#define RC_UP                0x800
105
#define RC_CHOP                0xc00
106

    
107
#define MAXTAN 9223372036854775808.0
108

    
109
/* the following deal with x86 long double-precision numbers */
110
#define MAXEXPD 0x7fff
111
#define EXPBIAS 16383
112
#define EXPD(fp)        (fp.l.upper & 0x7fff)
113
#define SIGND(fp)        ((fp.l.upper) & 0x8000)
114
#define MANTD(fp)       (fp.l.lower)
115
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
116

    
117
static inline void fpush(void)
118
{
119
    env->fpstt = (env->fpstt - 1) & 7;
120
    env->fptags[env->fpstt] = 0; /* validate stack entry */
121
}
122

    
123
static inline void fpop(void)
124
{
125
    env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
126
    env->fpstt = (env->fpstt + 1) & 7;
127
}
128

    
129
static inline floatx80 helper_fldt(target_ulong ptr)
130
{
131
    CPU_LDoubleU temp;
132

    
133
    temp.l.lower = ldq(ptr);
134
    temp.l.upper = lduw(ptr + 8);
135
    return temp.d;
136
}
137

    
138
static inline void helper_fstt(floatx80 f, target_ulong ptr)
139
{
140
    CPU_LDoubleU temp;
141

    
142
    temp.d = f;
143
    stq(ptr, temp.l.lower);
144
    stw(ptr + 8, temp.l.upper);
145
}
146

    
147
#define FPUS_IE (1 << 0)
148
#define FPUS_DE (1 << 1)
149
#define FPUS_ZE (1 << 2)
150
#define FPUS_OE (1 << 3)
151
#define FPUS_UE (1 << 4)
152
#define FPUS_PE (1 << 5)
153
#define FPUS_SF (1 << 6)
154
#define FPUS_SE (1 << 7)
155
#define FPUS_B  (1 << 15)
156

    
157
#define FPUC_EM 0x3f
158

    
159
static inline uint32_t compute_eflags(void)
160
{
161
    return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
162
}
163

    
164
/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
165
static inline void load_eflags(int eflags, int update_mask)
166
{
167
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
168
    DF = 1 - (2 * ((eflags >> 10) & 1));
169
    env->eflags = (env->eflags & ~update_mask) |
170
        (eflags & update_mask) | 0x2;
171
}
172

    
173
static inline int cpu_has_work(CPUState *env)
174
{
175
    return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
176
            (env->eflags & IF_MASK)) ||
177
           (env->interrupt_request & (CPU_INTERRUPT_NMI |
178
                                      CPU_INTERRUPT_INIT |
179
                                      CPU_INTERRUPT_SIPI |
180
                                      CPU_INTERRUPT_MCE));
181
}
182

    
183
/* load efer and update the corresponding hflags. XXX: do consistency
184
   checks with cpuid bits ? */
185
static inline void cpu_load_efer(CPUState *env, uint64_t val)
186
{
187
    env->efer = val;
188
    env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
189
    if (env->efer & MSR_EFER_LMA)
190
        env->hflags |= HF_LMA_MASK;
191
    if (env->efer & MSR_EFER_SVME)
192
        env->hflags |= HF_SVME_MASK;
193
}
194

    
195
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
196
{
197
    env->eip = tb->pc - tb->cs_base;
198
}
199