qemu/target-i386/exec.h
<<
>>
Prefs
   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
  31register struct CPUX86State *env asm(AREG0);
  32
  33#include "qemu-common.h"
  34#include "qemu-log.h"
  35
  36#include "cpu.h"
  37
  38/* op_helper.c */
  39void QEMU_NORETURN raise_exception_err(int exception_index, int error_code);
  40void QEMU_NORETURN raise_exception(int exception_index);
  41void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv);
  42
  43/* n must be a constant to be efficient */
  44static inline target_long lshift(target_long x, int n)
  45{
  46    if (n >= 0)
  47        return x << n;
  48    else
  49        return x >> (-n);
  50}
  51
  52#include "helper.h"
  53
  54#if !defined(CONFIG_USER_ONLY)
  55
  56#include "softmmu_exec.h"
  57
  58#endif /* !defined(CONFIG_USER_ONLY) */
  59
  60#define RC_MASK         0xc00
  61#define RC_NEAR         0x000
  62#define RC_DOWN         0x400
  63#define RC_UP           0x800
  64#define RC_CHOP         0xc00
  65
  66#define MAXTAN 9223372036854775808.0
  67
  68/* the following deal with x86 long double-precision numbers */
  69#define MAXEXPD 0x7fff
  70#define EXPBIAS 16383
  71#define EXPD(fp)        (fp.l.upper & 0x7fff)
  72#define SIGND(fp)       ((fp.l.upper) & 0x8000)
  73#define MANTD(fp)       (fp.l.lower)
  74#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
  75
  76static inline void fpush(void)
  77{
  78    env->fpstt = (env->fpstt - 1) & 7;
  79    env->fptags[env->fpstt] = 0; /* validate stack entry */
  80}
  81
  82static inline void fpop(void)
  83{
  84    env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
  85    env->fpstt = (env->fpstt + 1) & 7;
  86}
  87
  88static inline floatx80 helper_fldt(target_ulong ptr)
  89{
  90    CPU_LDoubleU temp;
  91
  92    temp.l.lower = ldq(ptr);
  93    temp.l.upper = lduw(ptr + 8);
  94    return temp.d;
  95}
  96
  97static inline void helper_fstt(floatx80 f, target_ulong ptr)
  98{
  99    CPU_LDoubleU temp;
 100
 101    temp.d = f;
 102    stq(ptr, temp.l.lower);
 103    stw(ptr + 8, temp.l.upper);
 104}
 105
 106#define FPUS_IE (1 << 0)
 107#define FPUS_DE (1 << 1)
 108#define FPUS_ZE (1 << 2)
 109#define FPUS_OE (1 << 3)
 110#define FPUS_UE (1 << 4)
 111#define FPUS_PE (1 << 5)
 112#define FPUS_SF (1 << 6)
 113#define FPUS_SE (1 << 7)
 114#define FPUS_B  (1 << 15)
 115
 116#define FPUC_EM 0x3f
 117
 118static inline uint32_t compute_eflags(void)
 119{
 120    return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
 121}
 122
 123/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
 124static inline void load_eflags(int eflags, int update_mask)
 125{
 126    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
 127    DF = 1 - (2 * ((eflags >> 10) & 1));
 128    env->eflags = (env->eflags & ~update_mask) |
 129        (eflags & update_mask) | 0x2;
 130}
 131
 132/* load efer and update the corresponding hflags. XXX: do consistency
 133   checks with cpuid bits ? */
 134static inline void cpu_load_efer(CPUState *env, uint64_t val)
 135{
 136    env->efer = val;
 137    env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
 138    if (env->efer & MSR_EFER_LMA)
 139        env->hflags |= HF_LMA_MASK;
 140    if (env->efer & MSR_EFER_SVME)
 141        env->hflags |= HF_SVME_MASK;
 142}
 143