VirtualBox

source: vbox/trunk/src/recompiler/target-i386/exec.h@ 36125

最後變更 在這個檔案從36125是 36125,由 vboxsync 提交於 14 年 前

recompiler: Removing traces of attempts at making the recompiler compile with the microsoft compiler. (untested)

  • 屬性 svn:eol-style 設為 native
檔案大小: 12.5 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
24 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25 * a choice of LGPL license versions is made available with the language indicating
26 * that LGPLv2 or any later version may be used, or where a choice of which version
27 * of the LGPL is applied is otherwise unspecified.
28 */
29
30#include "config.h"
31#include "dyngen-exec.h"
32
33/* XXX: factorize this mess */
34#ifdef TARGET_X86_64
35#define TARGET_LONG_BITS 64
36#else
37#define TARGET_LONG_BITS 32
38#endif
39
40#include "cpu-defs.h"
41
42/* at least 4 register variables are defined */
43register struct CPUX86State *env asm(AREG0);
44
45#include "qemu-log.h"
46
47#ifndef reg_EAX
48#define EAX (env->regs[R_EAX])
49#endif
50#ifndef reg_ECX
51#define ECX (env->regs[R_ECX])
52#endif
53#ifndef reg_EDX
54#define EDX (env->regs[R_EDX])
55#endif
56#ifndef reg_EBX
57#define EBX (env->regs[R_EBX])
58#endif
59#ifndef reg_ESP
60#define ESP (env->regs[R_ESP])
61#endif
62#ifndef reg_EBP
63#define EBP (env->regs[R_EBP])
64#endif
65#ifndef reg_ESI
66#define ESI (env->regs[R_ESI])
67#endif
68#ifndef reg_EDI
69#define EDI (env->regs[R_EDI])
70#endif
71#define EIP (env->eip)
72#define DF (env->df)
73
74#define CC_SRC (env->cc_src)
75#define CC_DST (env->cc_dst)
76#define CC_OP (env->cc_op)
77
78/* float macros */
79#define FT0 (env->ft0)
80#define ST0 (env->fpregs[env->fpstt].d)
81#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
82#define ST1 ST(1)
83
84#include "cpu.h"
85#include "exec-all.h"
86
87void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
88void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
89int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
90 int is_write, int mmu_idx, int is_softmmu);
91void __hidden cpu_lock(void);
92void __hidden cpu_unlock(void);
93void do_interrupt(int intno, int is_int, int error_code,
94 target_ulong next_eip, int is_hw);
95void do_interrupt_user(int intno, int is_int, int error_code,
96 target_ulong next_eip);
97void raise_interrupt(int intno, int is_int, int error_code,
98 int next_eip_addend);
99void raise_exception_err(int exception_index, int error_code);
100void raise_exception(int exception_index);
101void do_smm_enter(void);
102void __hidden cpu_loop_exit(void);
103
104void OPPROTO op_movl_eflags_T0(void);
105void OPPROTO op_movl_T0_eflags(void);
106#ifdef VBOX
107void OPPROTO op_movl_T0_eflags_vme(void);
108void OPPROTO op_movw_eflags_T0_vme(void);
109void OPPROTO op_cli_vme(void);
110void OPPROTO op_sti_vme(void);
111#endif
112
113/* n must be a constant to be efficient */
114static inline target_long lshift(target_long x, int n)
115{
116 if (n >= 0)
117 return x << n;
118 else
119 return x >> (-n);
120}
121
122#include "helper.h"
123
124static inline void svm_check_intercept(uint32_t type)
125{
126 helper_svm_check_intercept_param(type, 0);
127}
128
129void check_iob_T0(void);
130void check_iow_T0(void);
131void check_iol_T0(void);
132void check_iob_DX(void);
133void check_iow_DX(void);
134void check_iol_DX(void);
135
136#if !defined(CONFIG_USER_ONLY)
137
138#include "softmmu_exec.h"
139
140static inline double ldfq(target_ulong ptr)
141{
142 union {
143 double d;
144 uint64_t i;
145 } u;
146 u.i = ldq(ptr);
147 return u.d;
148}
149
150static inline void stfq(target_ulong ptr, double v)
151{
152 union {
153 double d;
154 uint64_t i;
155 } u;
156 u.d = v;
157 stq(ptr, u.i);
158}
159
160static inline float ldfl(target_ulong ptr)
161{
162 union {
163 float f;
164 uint32_t i;
165 } u;
166 u.i = ldl(ptr);
167 return u.f;
168}
169
170static inline void stfl(target_ulong ptr, float v)
171{
172 union {
173 float f;
174 uint32_t i;
175 } u;
176 u.f = v;
177 stl(ptr, u.i);
178}
179
180#endif /* !defined(CONFIG_USER_ONLY) */
181
182#ifdef USE_X86LDOUBLE
183/* use long double functions */
184#define floatx_to_int32 floatx80_to_int32
185#define floatx_to_int64 floatx80_to_int64
186#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero
187#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero
188#define int32_to_floatx int32_to_floatx80
189#define int64_to_floatx int64_to_floatx80
190#define float32_to_floatx float32_to_floatx80
191#define float64_to_floatx float64_to_floatx80
192#define floatx_to_float32 floatx80_to_float32
193#define floatx_to_float64 floatx80_to_float64
194#define floatx_abs floatx80_abs
195#define floatx_chs floatx80_chs
196#define floatx_round_to_int floatx80_round_to_int
197#define floatx_compare floatx80_compare
198#define floatx_compare_quiet floatx80_compare_quiet
199#ifdef VBOX
200#undef sin
201#undef cos
202#undef sqrt
203#undef pow
204#undef log
205#undef tan
206#undef atan2
207#undef floor
208#undef ceil
209#undef ldexp
210#endif /* !VBOX */
211#if !defined(VBOX) || !defined(_MSC_VER)
212#define sin sinl
213#define cos cosl
214#define sqrt sqrtl
215#define pow powl
216#define log logl
217#define tan tanl
218#define atan2 atan2l
219#define floor floorl
220#define ceil ceill
221#define ldexp ldexpl
222#endif
223#else
224#define floatx_to_int32 float64_to_int32
225#define floatx_to_int64 float64_to_int64
226#define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero
227#define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero
228#define int32_to_floatx int32_to_float64
229#define int64_to_floatx int64_to_float64
230#define float32_to_floatx float32_to_float64
231#define float64_to_floatx(x, e) (x)
232#define floatx_to_float32 float64_to_float32
233#define floatx_to_float64(x, e) (x)
234#define floatx_abs float64_abs
235#define floatx_chs float64_chs
236#define floatx_round_to_int float64_round_to_int
237#define floatx_compare float64_compare
238#define floatx_compare_quiet float64_compare_quiet
239#endif
240
241#ifdef VBOX
242extern CPU86_LDouble sin(CPU86_LDouble x);
243extern CPU86_LDouble cos(CPU86_LDouble x);
244extern CPU86_LDouble sqrt(CPU86_LDouble x);
245extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);
246extern CPU86_LDouble log(CPU86_LDouble x);
247extern CPU86_LDouble tan(CPU86_LDouble x);
248extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
249extern CPU86_LDouble floor(CPU86_LDouble x);
250extern CPU86_LDouble ceil(CPU86_LDouble x);
251#endif /* VBOX */
252
253#define RC_MASK 0xc00
254#ifndef RC_NEAR
255#define RC_NEAR 0x000
256#endif
257#ifndef RC_DOWN
258#define RC_DOWN 0x400
259#endif
260#ifndef RC_UP
261#define RC_UP 0x800
262#endif
263#ifndef RC_CHOP
264#define RC_CHOP 0xc00
265#endif
266
267#define MAXTAN 9223372036854775808.0
268
269#ifdef USE_X86LDOUBLE
270
271/* only for x86 */
272typedef union {
273 long double d;
274 struct {
275 unsigned long long lower;
276 unsigned short upper;
277 } l;
278} CPU86_LDoubleU;
279
280/* the following deal with x86 long double-precision numbers */
281#define MAXEXPD 0x7fff
282#define EXPBIAS 16383
283#define EXPD(fp) (fp.l.upper & 0x7fff)
284#define SIGND(fp) ((fp.l.upper) & 0x8000)
285#define MANTD(fp) (fp.l.lower)
286#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
287
288#else
289
290/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
291typedef union {
292 double d;
293#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
294 struct {
295 uint32_t lower;
296 int32_t upper;
297 } l;
298#else
299 struct {
300 int32_t upper;
301 uint32_t lower;
302 } l;
303#endif
304#ifndef __arm__
305 int64_t ll;
306#endif
307} CPU86_LDoubleU;
308
309/* the following deal with IEEE double-precision numbers */
310#define MAXEXPD 0x7ff
311#define EXPBIAS 1023
312#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
313#define SIGND(fp) ((fp.l.upper) & 0x80000000)
314#ifdef __arm__
315#define MANTD(fp) (fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32))
316#else
317#define MANTD(fp) (fp.ll & ((1LL << 52) - 1))
318#endif
319#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
320#endif
321
322static inline void fpush(void)
323{
324 env->fpstt = (env->fpstt - 1) & 7;
325 env->fptags[env->fpstt] = 0; /* validate stack entry */
326}
327
328static inline void fpop(void)
329{
330 env->fptags[env->fpstt] = 1; /* invalidate stack entry */
331 env->fpstt = (env->fpstt + 1) & 7;
332}
333
334#ifndef USE_X86LDOUBLE
335static inline CPU86_LDouble helper_fldt(target_ulong ptr)
336{
337 CPU86_LDoubleU temp;
338 int upper, e;
339 uint64_t ll;
340
341 /* mantissa */
342 upper = lduw(ptr + 8);
343 /* XXX: handle overflow ? */
344 e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
345 e |= (upper >> 4) & 0x800; /* sign */
346 ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1);
347#ifdef __arm__
348 temp.l.upper = (e << 20) | (ll >> 32);
349 temp.l.lower = ll;
350#else
351 temp.ll = ll | ((uint64_t)e << 52);
352#endif
353 return temp.d;
354}
355
356static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
357{
358 CPU86_LDoubleU temp;
359 int e;
360
361 temp.d = f;
362 /* mantissa */
363 stq(ptr, (MANTD(temp) << 11) | (1LL << 63));
364 /* exponent + sign */
365 e = EXPD(temp) - EXPBIAS + 16383;
366 e |= SIGND(temp) >> 16;
367 stw(ptr + 8, e);
368}
369#else
370
371/* XXX: same endianness assumed */
372
373#ifdef CONFIG_USER_ONLY
374
375static inline CPU86_LDouble helper_fldt(target_ulong ptr)
376{
377 return *(CPU86_LDouble *)ptr;
378}
379
380static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
381{
382 *(CPU86_LDouble *)ptr = f;
383}
384
385#else
386
387/* we use memory access macros */
388
389static inline CPU86_LDouble helper_fldt(target_ulong ptr)
390{
391 CPU86_LDoubleU temp;
392
393 temp.l.lower = ldq(ptr);
394 temp.l.upper = lduw(ptr + 8);
395 return temp.d;
396}
397
398static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr)
399{
400 CPU86_LDoubleU temp;
401
402 temp.d = f;
403 stq(ptr, temp.l.lower);
404 stw(ptr + 8, temp.l.upper);
405}
406
407#endif /* !CONFIG_USER_ONLY */
408
409#endif /* USE_X86LDOUBLE */
410
411#define FPUS_IE (1 << 0)
412#define FPUS_DE (1 << 1)
413#define FPUS_ZE (1 << 2)
414#define FPUS_OE (1 << 3)
415#define FPUS_UE (1 << 4)
416#define FPUS_PE (1 << 5)
417#define FPUS_SF (1 << 6)
418#define FPUS_SE (1 << 7)
419#define FPUS_B (1 << 15)
420
421#define FPUC_EM 0x3f
422
423extern const CPU86_LDouble f15rk[7];
424
425void fpu_raise_exception(void);
426void restore_native_fp_state(CPUState *env);
427void save_native_fp_state(CPUState *env);
428
429extern const uint8_t parity_table[256];
430extern const uint8_t rclw_table[32];
431extern const uint8_t rclb_table[32];
432
433static inline uint32_t compute_eflags(void)
434{
435 return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
436}
437
438/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
439static inline void load_eflags(int eflags, int update_mask)
440{
441 CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
442 DF = 1 - (2 * ((eflags >> 10) & 1));
443 env->eflags = (env->eflags & ~update_mask) |
444 (eflags & update_mask);
445}
446
447static inline void env_to_regs(void)
448{
449#ifdef reg_EAX
450 EAX = env->regs[R_EAX];
451#endif
452#ifdef reg_ECX
453 ECX = env->regs[R_ECX];
454#endif
455#ifdef reg_EDX
456 EDX = env->regs[R_EDX];
457#endif
458#ifdef reg_EBX
459 EBX = env->regs[R_EBX];
460#endif
461#ifdef reg_ESP
462 ESP = env->regs[R_ESP];
463#endif
464#ifdef reg_EBP
465 EBP = env->regs[R_EBP];
466#endif
467#ifdef reg_ESI
468 ESI = env->regs[R_ESI];
469#endif
470#ifdef reg_EDI
471 EDI = env->regs[R_EDI];
472#endif
473}
474
475static inline void regs_to_env(void)
476{
477#ifdef reg_EAX
478 env->regs[R_EAX] = EAX;
479#endif
480#ifdef reg_ECX
481 env->regs[R_ECX] = ECX;
482#endif
483#ifdef reg_EDX
484 env->regs[R_EDX] = EDX;
485#endif
486#ifdef reg_EBX
487 env->regs[R_EBX] = EBX;
488#endif
489#ifdef reg_ESP
490 env->regs[R_ESP] = ESP;
491#endif
492#ifdef reg_EBP
493 env->regs[R_EBP] = EBP;
494#endif
495#ifdef reg_ESI
496 env->regs[R_ESI] = ESI;
497#endif
498#ifdef reg_EDI
499 env->regs[R_EDI] = EDI;
500#endif
501}
502
503static inline int cpu_halted(CPUState *env) {
504 /* handle exit of HALTED state */
505 if (!env->halted)
506 return 0;
507 /* disable halt condition */
508 if (((env->interrupt_request & CPU_INTERRUPT_HARD) &&
509 (env->eflags & IF_MASK)) ||
510 (env->interrupt_request & CPU_INTERRUPT_NMI)) {
511 env->halted = 0;
512 return 0;
513 }
514 return EXCP_HALTED;
515}
516
517/* load efer and update the corresponding hflags. XXX: do consistency
518 checks with cpuid bits ? */
519static inline void cpu_load_efer(CPUState *env, uint64_t val)
520{
521 env->efer = val;
522 env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
523 if (env->efer & MSR_EFER_LMA)
524 env->hflags |= HF_LMA_MASK;
525 if (env->efer & MSR_EFER_SVME)
526 env->hflags |= HF_SVME_MASK;
527}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette