Home | History | Annotate | Download | only in target-i386
      1 /*
      2  *  i386 helpers
      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., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
     19  */
     20 #define CPU_NO_GLOBAL_REGS
     21 #include "exec.h"
     22 #include "exec-all.h"
     23 #include "host-utils.h"
     24 
     25 //#define DEBUG_PCALL
     26 
     27 
     28 #ifdef DEBUG_PCALL
     29 #  define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__)
     30 #  define LOG_PCALL_STATE(env) \
     31           log_cpu_state_mask(CPU_LOG_PCALL, (env), X86_DUMP_CCOP)
     32 #else
     33 #  define LOG_PCALL(...) do { } while (0)
     34 #  define LOG_PCALL_STATE(env) do { } while (0)
     35 #endif
     36 
     37 
     38 #if 0
     39 #define raise_exception_err(a, b)\
     40 do {\
     41     qemu_log("raise_exception line=%d\n", __LINE__);\
     42     (raise_exception_err)(a, b);\
     43 } while (0)
     44 #endif
     45 
     46 static const uint8_t parity_table[256] = {
     47     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     48     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     49     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     50     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     51     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     52     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     53     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     54     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     55     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     56     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     57     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     58     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     59     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     60     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     61     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     62     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     63     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     64     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     65     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     66     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     67     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     68     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     69     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     70     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     71     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     72     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     73     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     74     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     75     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     76     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     77     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     78     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     79 };
     80 
     81 /* modulo 17 table */
     82 static const uint8_t rclw_table[32] = {
     83     0, 1, 2, 3, 4, 5, 6, 7,
     84     8, 9,10,11,12,13,14,15,
     85    16, 0, 1, 2, 3, 4, 5, 6,
     86     7, 8, 9,10,11,12,13,14,
     87 };
     88 
     89 /* modulo 9 table */
     90 static const uint8_t rclb_table[32] = {
     91     0, 1, 2, 3, 4, 5, 6, 7,
     92     8, 0, 1, 2, 3, 4, 5, 6,
     93     7, 8, 0, 1, 2, 3, 4, 5,
     94     6, 7, 8, 0, 1, 2, 3, 4,
     95 };
     96 
     97 static const CPU86_LDouble f15rk[7] =
     98 {
     99     0.00000000000000000000L,
    100     1.00000000000000000000L,
    101     3.14159265358979323851L,  /*pi*/
    102     0.30102999566398119523L,  /*lg2*/
    103     0.69314718055994530943L,  /*ln2*/
    104     1.44269504088896340739L,  /*l2e*/
    105     3.32192809488736234781L,  /*l2t*/
    106 };
    107 
    108 /* broken thread support */
    109 
    110 static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
    111 
    112 void helper_lock(void)
    113 {
    114     spin_lock(&global_cpu_lock);
    115 }
    116 
    117 void helper_unlock(void)
    118 {
    119     spin_unlock(&global_cpu_lock);
    120 }
    121 
    122 void helper_write_eflags(target_ulong t0, uint32_t update_mask)
    123 {
    124     load_eflags(t0, update_mask);
    125 }
    126 
    127 target_ulong helper_read_eflags(void)
    128 {
    129     uint32_t eflags;
    130     eflags = helper_cc_compute_all(CC_OP);
    131     eflags |= (DF & DF_MASK);
    132     eflags |= env->eflags & ~(VM_MASK | RF_MASK);
    133     return eflags;
    134 }
    135 
    136 /* return non zero if error */
    137 static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
    138                                int selector)
    139 {
    140     SegmentCache *dt;
    141     int index;
    142     target_ulong ptr;
    143 
    144     if (selector & 0x4)
    145         dt = &env->ldt;
    146     else
    147         dt = &env->gdt;
    148     index = selector & ~7;
    149     if ((index + 7) > dt->limit)
    150         return -1;
    151     ptr = dt->base + index;
    152     *e1_ptr = ldl_kernel(ptr);
    153     *e2_ptr = ldl_kernel(ptr + 4);
    154     return 0;
    155 }
    156 
    157 static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2)
    158 {
    159     unsigned int limit;
    160     limit = (e1 & 0xffff) | (e2 & 0x000f0000);
    161     if (e2 & DESC_G_MASK)
    162         limit = (limit << 12) | 0xfff;
    163     return limit;
    164 }
    165 
    166 static inline uint32_t get_seg_base(uint32_t e1, uint32_t e2)
    167 {
    168     return ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
    169 }
    170 
    171 static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2)
    172 {
    173     sc->base = get_seg_base(e1, e2);
    174     sc->limit = get_seg_limit(e1, e2);
    175     sc->flags = e2;
    176 }
    177 
    178 /* init the segment cache in vm86 mode. */
    179 static inline void load_seg_vm(int seg, int selector)
    180 {
    181     selector &= 0xffff;
    182     cpu_x86_load_seg_cache(env, seg, selector,
    183                            (selector << 4), 0xffff, 0);
    184 }
    185 
    186 static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
    187                                        uint32_t *esp_ptr, int dpl)
    188 {
    189     int type, index, shift;
    190 
    191 #if 0
    192     {
    193         int i;
    194         printf("TR: base=%p limit=%x\n", env->tr.base, env->tr.limit);
    195         for(i=0;i<env->tr.limit;i++) {
    196             printf("%02x ", env->tr.base[i]);
    197             if ((i & 7) == 7) printf("\n");
    198         }
    199         printf("\n");
    200     }
    201 #endif
    202 
    203     if (!(env->tr.flags & DESC_P_MASK))
    204         cpu_abort(env, "invalid tss");
    205     type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
    206     if ((type & 7) != 1)
    207         cpu_abort(env, "invalid tss type");
    208     shift = type >> 3;
    209     index = (dpl * 4 + 2) << shift;
    210     if (index + (4 << shift) - 1 > env->tr.limit)
    211         raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
    212     if (shift == 0) {
    213         *esp_ptr = lduw_kernel(env->tr.base + index);
    214         *ss_ptr = lduw_kernel(env->tr.base + index + 2);
    215     } else {
    216         *esp_ptr = ldl_kernel(env->tr.base + index);
    217         *ss_ptr = lduw_kernel(env->tr.base + index + 4);
    218     }
    219 }
    220 
    221 /* XXX: merge with load_seg() */
    222 static void tss_load_seg(int seg_reg, int selector)
    223 {
    224     uint32_t e1, e2;
    225     int rpl, dpl, cpl;
    226 
    227     if ((selector & 0xfffc) != 0) {
    228         if (load_segment(&e1, &e2, selector) != 0)
    229             raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    230         if (!(e2 & DESC_S_MASK))
    231             raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    232         rpl = selector & 3;
    233         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
    234         cpl = env->hflags & HF_CPL_MASK;
    235         if (seg_reg == R_CS) {
    236             if (!(e2 & DESC_CS_MASK))
    237                 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    238             /* XXX: is it correct ? */
    239             if (dpl != rpl)
    240                 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    241             if ((e2 & DESC_C_MASK) && dpl > rpl)
    242                 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    243         } else if (seg_reg == R_SS) {
    244             /* SS must be writable data */
    245             if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK))
    246                 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    247             if (dpl != cpl || dpl != rpl)
    248                 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    249         } else {
    250             /* not readable code */
    251             if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK))
    252                 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    253             /* if data or non conforming code, checks the rights */
    254             if (((e2 >> DESC_TYPE_SHIFT) & 0xf) < 12) {
    255                 if (dpl < cpl || dpl < rpl)
    256                     raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    257             }
    258         }
    259         if (!(e2 & DESC_P_MASK))
    260             raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
    261         cpu_x86_load_seg_cache(env, seg_reg, selector,
    262                        get_seg_base(e1, e2),
    263                        get_seg_limit(e1, e2),
    264                        e2);
    265     } else {
    266         if (seg_reg == R_SS || seg_reg == R_CS)
    267             raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    268     }
    269 }
    270 
    271 #define SWITCH_TSS_JMP  0
    272 #define SWITCH_TSS_IRET 1
    273 #define SWITCH_TSS_CALL 2
    274 
    275 /* XXX: restore CPU state in registers (PowerPC case) */
    276 static void switch_tss(int tss_selector,
    277                        uint32_t e1, uint32_t e2, int source,
    278                        uint32_t next_eip)
    279 {
    280     int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, v1, v2, i;
    281     target_ulong tss_base;
    282     uint32_t new_regs[8], new_segs[6];
    283     uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap;
    284     uint32_t old_eflags, eflags_mask;
    285     SegmentCache *dt;
    286     int index;
    287     target_ulong ptr;
    288 
    289     type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
    290     LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, source);
    291 
    292     /* if task gate, we read the TSS segment and we load it */
    293     if (type == 5) {
    294         if (!(e2 & DESC_P_MASK))
    295             raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc);
    296         tss_selector = e1 >> 16;
    297         if (tss_selector & 4)
    298             raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
    299         if (load_segment(&e1, &e2, tss_selector) != 0)
    300             raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
    301         if (e2 & DESC_S_MASK)
    302             raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
    303         type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
    304         if ((type & 7) != 1)
    305             raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
    306     }
    307 
    308     if (!(e2 & DESC_P_MASK))
    309         raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc);
    310 
    311     if (type & 8)
    312         tss_limit_max = 103;
    313     else
    314         tss_limit_max = 43;
    315     tss_limit = get_seg_limit(e1, e2);
    316     tss_base = get_seg_base(e1, e2);
    317     if ((tss_selector & 4) != 0 ||
    318         tss_limit < tss_limit_max)
    319         raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
    320     old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
    321     if (old_type & 8)
    322         old_tss_limit_max = 103;
    323     else
    324         old_tss_limit_max = 43;
    325 
    326     /* read all the registers from the new TSS */
    327     if (type & 8) {
    328         /* 32 bit */
    329         new_cr3 = ldl_kernel(tss_base + 0x1c);
    330         new_eip = ldl_kernel(tss_base + 0x20);
    331         new_eflags = ldl_kernel(tss_base + 0x24);
    332         for(i = 0; i < 8; i++)
    333             new_regs[i] = ldl_kernel(tss_base + (0x28 + i * 4));
    334         for(i = 0; i < 6; i++)
    335             new_segs[i] = lduw_kernel(tss_base + (0x48 + i * 4));
    336         new_ldt = lduw_kernel(tss_base + 0x60);
    337         new_trap = ldl_kernel(tss_base + 0x64);
    338     } else {
    339         /* 16 bit */
    340         new_cr3 = 0;
    341         new_eip = lduw_kernel(tss_base + 0x0e);
    342         new_eflags = lduw_kernel(tss_base + 0x10);
    343         for(i = 0; i < 8; i++)
    344             new_regs[i] = lduw_kernel(tss_base + (0x12 + i * 2)) | 0xffff0000;
    345         for(i = 0; i < 4; i++)
    346             new_segs[i] = lduw_kernel(tss_base + (0x22 + i * 4));
    347         new_ldt = lduw_kernel(tss_base + 0x2a);
    348         new_segs[R_FS] = 0;
    349         new_segs[R_GS] = 0;
    350         new_trap = 0;
    351     }
    352 
    353     /* NOTE: we must avoid memory exceptions during the task switch,
    354        so we make dummy accesses before */
    355     /* XXX: it can still fail in some cases, so a bigger hack is
    356        necessary to valid the TLB after having done the accesses */
    357 
    358     v1 = ldub_kernel(env->tr.base);
    359     v2 = ldub_kernel(env->tr.base + old_tss_limit_max);
    360     stb_kernel(env->tr.base, v1);
    361     stb_kernel(env->tr.base + old_tss_limit_max, v2);
    362 
    363     /* clear busy bit (it is restartable) */
    364     if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) {
    365         target_ulong ptr;
    366         uint32_t e2;
    367         ptr = env->gdt.base + (env->tr.selector & ~7);
    368         e2 = ldl_kernel(ptr + 4);
    369         e2 &= ~DESC_TSS_BUSY_MASK;
    370         stl_kernel(ptr + 4, e2);
    371     }
    372     old_eflags = compute_eflags();
    373     if (source == SWITCH_TSS_IRET)
    374         old_eflags &= ~NT_MASK;
    375 
    376     /* save the current state in the old TSS */
    377     if (type & 8) {
    378         /* 32 bit */
    379         stl_kernel(env->tr.base + 0x20, next_eip);
    380         stl_kernel(env->tr.base + 0x24, old_eflags);
    381         stl_kernel(env->tr.base + (0x28 + 0 * 4), EAX);
    382         stl_kernel(env->tr.base + (0x28 + 1 * 4), ECX);
    383         stl_kernel(env->tr.base + (0x28 + 2 * 4), EDX);
    384         stl_kernel(env->tr.base + (0x28 + 3 * 4), EBX);
    385         stl_kernel(env->tr.base + (0x28 + 4 * 4), ESP);
    386         stl_kernel(env->tr.base + (0x28 + 5 * 4), EBP);
    387         stl_kernel(env->tr.base + (0x28 + 6 * 4), ESI);
    388         stl_kernel(env->tr.base + (0x28 + 7 * 4), EDI);
    389         for(i = 0; i < 6; i++)
    390             stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
    391     } else {
    392         /* 16 bit */
    393         stw_kernel(env->tr.base + 0x0e, next_eip);
    394         stw_kernel(env->tr.base + 0x10, old_eflags);
    395         stw_kernel(env->tr.base + (0x12 + 0 * 2), EAX);
    396         stw_kernel(env->tr.base + (0x12 + 1 * 2), ECX);
    397         stw_kernel(env->tr.base + (0x12 + 2 * 2), EDX);
    398         stw_kernel(env->tr.base + (0x12 + 3 * 2), EBX);
    399         stw_kernel(env->tr.base + (0x12 + 4 * 2), ESP);
    400         stw_kernel(env->tr.base + (0x12 + 5 * 2), EBP);
    401         stw_kernel(env->tr.base + (0x12 + 6 * 2), ESI);
    402         stw_kernel(env->tr.base + (0x12 + 7 * 2), EDI);
    403         for(i = 0; i < 4; i++)
    404             stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector);
    405     }
    406 
    407     /* now if an exception occurs, it will occurs in the next task
    408        context */
    409 
    410     if (source == SWITCH_TSS_CALL) {
    411         stw_kernel(tss_base, env->tr.selector);
    412         new_eflags |= NT_MASK;
    413     }
    414 
    415     /* set busy bit */
    416     if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_CALL) {
    417         target_ulong ptr;
    418         uint32_t e2;
    419         ptr = env->gdt.base + (tss_selector & ~7);
    420         e2 = ldl_kernel(ptr + 4);
    421         e2 |= DESC_TSS_BUSY_MASK;
    422         stl_kernel(ptr + 4, e2);
    423     }
    424 
    425     /* set the new CPU state */
    426     /* from this point, any exception which occurs can give problems */
    427     env->cr[0] |= CR0_TS_MASK;
    428     env->hflags |= HF_TS_MASK;
    429     env->tr.selector = tss_selector;
    430     env->tr.base = tss_base;
    431     env->tr.limit = tss_limit;
    432     env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK;
    433 
    434     if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) {
    435         cpu_x86_update_cr3(env, new_cr3);
    436     }
    437 
    438     /* load all registers without an exception, then reload them with
    439        possible exception */
    440     env->eip = new_eip;
    441     eflags_mask = TF_MASK | AC_MASK | ID_MASK |
    442         IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK;
    443     if (!(type & 8))
    444         eflags_mask &= 0xffff;
    445     load_eflags(new_eflags, eflags_mask);
    446     /* XXX: what to do in 16 bit case ? */
    447     EAX = new_regs[0];
    448     ECX = new_regs[1];
    449     EDX = new_regs[2];
    450     EBX = new_regs[3];
    451     ESP = new_regs[4];
    452     EBP = new_regs[5];
    453     ESI = new_regs[6];
    454     EDI = new_regs[7];
    455     if (new_eflags & VM_MASK) {
    456         for(i = 0; i < 6; i++)
    457             load_seg_vm(i, new_segs[i]);
    458         /* in vm86, CPL is always 3 */
    459         cpu_x86_set_cpl(env, 3);
    460     } else {
    461         /* CPL is set the RPL of CS */
    462         cpu_x86_set_cpl(env, new_segs[R_CS] & 3);
    463         /* first just selectors as the rest may trigger exceptions */
    464         for(i = 0; i < 6; i++)
    465             cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0);
    466     }
    467 
    468     env->ldt.selector = new_ldt & ~4;
    469     env->ldt.base = 0;
    470     env->ldt.limit = 0;
    471     env->ldt.flags = 0;
    472 
    473     /* load the LDT */
    474     if (new_ldt & 4)
    475         raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
    476 
    477     if ((new_ldt & 0xfffc) != 0) {
    478         dt = &env->gdt;
    479         index = new_ldt & ~7;
    480         if ((index + 7) > dt->limit)
    481             raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
    482         ptr = dt->base + index;
    483         e1 = ldl_kernel(ptr);
    484         e2 = ldl_kernel(ptr + 4);
    485         if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)
    486             raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
    487         if (!(e2 & DESC_P_MASK))
    488             raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
    489         load_seg_cache_raw_dt(&env->ldt, e1, e2);
    490     }
    491 
    492     /* load the segments */
    493     if (!(new_eflags & VM_MASK)) {
    494         tss_load_seg(R_CS, new_segs[R_CS]);
    495         tss_load_seg(R_SS, new_segs[R_SS]);
    496         tss_load_seg(R_ES, new_segs[R_ES]);
    497         tss_load_seg(R_DS, new_segs[R_DS]);
    498         tss_load_seg(R_FS, new_segs[R_FS]);
    499         tss_load_seg(R_GS, new_segs[R_GS]);
    500     }
    501 
    502     /* check that EIP is in the CS segment limits */
    503     if (new_eip > env->segs[R_CS].limit) {
    504         /* XXX: different exception if CALL ? */
    505         raise_exception_err(EXCP0D_GPF, 0);
    506     }
    507 
    508 #ifndef CONFIG_USER_ONLY
    509     /* reset local breakpoints */
    510     if (env->dr[7] & 0x55) {
    511         for (i = 0; i < 4; i++) {
    512             if (hw_breakpoint_enabled(env->dr[7], i) == 0x1)
    513                 hw_breakpoint_remove(env, i);
    514         }
    515         env->dr[7] &= ~0x55;
    516     }
    517 #endif
    518 }
    519 
    520 /* check if Port I/O is allowed in TSS */
    521 static inline void check_io(int addr, int size)
    522 {
    523     int io_offset, val, mask;
    524 
    525     /* TSS must be a valid 32 bit one */
    526     if (!(env->tr.flags & DESC_P_MASK) ||
    527         ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
    528         env->tr.limit < 103)
    529         goto fail;
    530     io_offset = lduw_kernel(env->tr.base + 0x66);
    531     io_offset += (addr >> 3);
    532     /* Note: the check needs two bytes */
    533     if ((io_offset + 1) > env->tr.limit)
    534         goto fail;
    535     val = lduw_kernel(env->tr.base + io_offset);
    536     val >>= (addr & 7);
    537     mask = (1 << size) - 1;
    538     /* all bits must be zero to allow the I/O */
    539     if ((val & mask) != 0) {
    540     fail:
    541         raise_exception_err(EXCP0D_GPF, 0);
    542     }
    543 }
    544 
    545 void helper_check_iob(uint32_t t0)
    546 {
    547     check_io(t0, 1);
    548 }
    549 
    550 void helper_check_iow(uint32_t t0)
    551 {
    552     check_io(t0, 2);
    553 }
    554 
    555 void helper_check_iol(uint32_t t0)
    556 {
    557     check_io(t0, 4);
    558 }
    559 
    560 void helper_outb(uint32_t port, uint32_t data)
    561 {
    562     cpu_outb(port, data & 0xff);
    563 }
    564 
    565 target_ulong helper_inb(uint32_t port)
    566 {
    567     return cpu_inb(port);
    568 }
    569 
    570 void helper_outw(uint32_t port, uint32_t data)
    571 {
    572     cpu_outw(port, data & 0xffff);
    573 }
    574 
    575 target_ulong helper_inw(uint32_t port)
    576 {
    577     return cpu_inw(port);
    578 }
    579 
    580 void helper_outl(uint32_t port, uint32_t data)
    581 {
    582     cpu_outl(port, data);
    583 }
    584 
    585 target_ulong helper_inl(uint32_t port)
    586 {
    587     return cpu_inl(port);
    588 }
    589 
    590 static inline unsigned int get_sp_mask(unsigned int e2)
    591 {
    592     if (e2 & DESC_B_MASK)
    593         return 0xffffffff;
    594     else
    595         return 0xffff;
    596 }
    597 
    598 static int exeption_has_error_code(int intno)
    599 {
    600         switch(intno) {
    601         case 8:
    602         case 10:
    603         case 11:
    604         case 12:
    605         case 13:
    606         case 14:
    607         case 17:
    608             return 1;
    609         }
    610 	return 0;
    611 }
    612 
    613 #ifdef TARGET_X86_64
    614 #define SET_ESP(val, sp_mask)\
    615 do {\
    616     if ((sp_mask) == 0xffff)\
    617         ESP = (ESP & ~0xffff) | ((val) & 0xffff);\
    618     else if ((sp_mask) == 0xffffffffLL)\
    619         ESP = (uint32_t)(val);\
    620     else\
    621         ESP = (val);\
    622 } while (0)
    623 #else
    624 #define SET_ESP(val, sp_mask) ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask))
    625 #endif
    626 
    627 /* in 64-bit machines, this can overflow. So this segment addition macro
    628  * can be used to trim the value to 32-bit whenever needed */
    629 #define SEG_ADDL(ssp, sp, sp_mask) ((uint32_t)((ssp) + (sp & (sp_mask))))
    630 
    631 /* XXX: add a is_user flag to have proper security support */
    632 #define PUSHW(ssp, sp, sp_mask, val)\
    633 {\
    634     sp -= 2;\
    635     stw_kernel((ssp) + (sp & (sp_mask)), (val));\
    636 }
    637 
    638 #define PUSHL(ssp, sp, sp_mask, val)\
    639 {\
    640     sp -= 4;\
    641     stl_kernel(SEG_ADDL(ssp, sp, sp_mask), (uint32_t)(val));\
    642 }
    643 
    644 #define POPW(ssp, sp, sp_mask, val)\
    645 {\
    646     val = lduw_kernel((ssp) + (sp & (sp_mask)));\
    647     sp += 2;\
    648 }
    649 
    650 #define POPL(ssp, sp, sp_mask, val)\
    651 {\
    652     val = (uint32_t)ldl_kernel(SEG_ADDL(ssp, sp, sp_mask));\
    653     sp += 4;\
    654 }
    655 
    656 /* protected mode interrupt */
    657 static void do_interrupt_protected(int intno, int is_int, int error_code,
    658                                    unsigned int next_eip, int is_hw)
    659 {
    660     SegmentCache *dt;
    661     target_ulong ptr, ssp;
    662     int type, dpl, selector, ss_dpl, cpl;
    663     int has_error_code, new_stack, shift;
    664     uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0;
    665     uint32_t old_eip, sp_mask;
    666 
    667     has_error_code = 0;
    668     if (!is_int && !is_hw)
    669         has_error_code = exeption_has_error_code(intno);
    670     if (is_int)
    671         old_eip = next_eip;
    672     else
    673         old_eip = env->eip;
    674 
    675     dt = &env->idt;
    676     if (intno * 8 + 7 > dt->limit)
    677         raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
    678     ptr = dt->base + intno * 8;
    679     e1 = ldl_kernel(ptr);
    680     e2 = ldl_kernel(ptr + 4);
    681     /* check gate type */
    682     type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
    683     switch(type) {
    684     case 5: /* task gate */
    685         /* must do that check here to return the correct error code */
    686         if (!(e2 & DESC_P_MASK))
    687             raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
    688         switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);
    689         if (has_error_code) {
    690             int type;
    691             uint32_t mask;
    692             /* push the error code */
    693             type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
    694             shift = type >> 3;
    695             if (env->segs[R_SS].flags & DESC_B_MASK)
    696                 mask = 0xffffffff;
    697             else
    698                 mask = 0xffff;
    699             esp = (ESP - (2 << shift)) & mask;
    700             ssp = env->segs[R_SS].base + esp;
    701             if (shift)
    702                 stl_kernel(ssp, error_code);
    703             else
    704                 stw_kernel(ssp, error_code);
    705             SET_ESP(esp, mask);
    706         }
    707         return;
    708     case 6: /* 286 interrupt gate */
    709     case 7: /* 286 trap gate */
    710     case 14: /* 386 interrupt gate */
    711     case 15: /* 386 trap gate */
    712         break;
    713     default:
    714         raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
    715         break;
    716     }
    717     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
    718     cpl = env->hflags & HF_CPL_MASK;
    719     /* check privilege if software int */
    720     if (is_int && dpl < cpl)
    721         raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
    722     /* check valid bit */
    723     if (!(e2 & DESC_P_MASK))
    724         raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
    725     selector = e1 >> 16;
    726     offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
    727     if ((selector & 0xfffc) == 0)
    728         raise_exception_err(EXCP0D_GPF, 0);
    729 
    730     if (load_segment(&e1, &e2, selector) != 0)
    731         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    732     if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
    733         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    734     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
    735     if (dpl > cpl)
    736         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    737     if (!(e2 & DESC_P_MASK))
    738         raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
    739     if (!(e2 & DESC_C_MASK) && dpl < cpl) {
    740         /* to inner privilege */
    741         get_ss_esp_from_tss(&ss, &esp, dpl);
    742         if ((ss & 0xfffc) == 0)
    743             raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
    744         if ((ss & 3) != dpl)
    745             raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
    746         if (load_segment(&ss_e1, &ss_e2, ss) != 0)
    747             raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
    748         ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
    749         if (ss_dpl != dpl)
    750             raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
    751         if (!(ss_e2 & DESC_S_MASK) ||
    752             (ss_e2 & DESC_CS_MASK) ||
    753             !(ss_e2 & DESC_W_MASK))
    754             raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
    755         if (!(ss_e2 & DESC_P_MASK))
    756             raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
    757         new_stack = 1;
    758         sp_mask = get_sp_mask(ss_e2);
    759         ssp = get_seg_base(ss_e1, ss_e2);
    760     } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
    761         /* to same privilege */
    762         if (env->eflags & VM_MASK)
    763             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    764         new_stack = 0;
    765         sp_mask = get_sp_mask(env->segs[R_SS].flags);
    766         ssp = env->segs[R_SS].base;
    767         esp = ESP;
    768         dpl = cpl;
    769     } else {
    770         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    771         new_stack = 0; /* avoid warning */
    772         sp_mask = 0; /* avoid warning */
    773         ssp = 0; /* avoid warning */
    774         esp = 0; /* avoid warning */
    775     }
    776 
    777     shift = type >> 3;
    778 
    779 #if 0
    780     /* XXX: check that enough room is available */
    781     push_size = 6 + (new_stack << 2) + (has_error_code << 1);
    782     if (env->eflags & VM_MASK)
    783         push_size += 8;
    784     push_size <<= shift;
    785 #endif
    786     if (shift == 1) {
    787         if (new_stack) {
    788             if (env->eflags & VM_MASK) {
    789                 PUSHL(ssp, esp, sp_mask, env->segs[R_GS].selector);
    790                 PUSHL(ssp, esp, sp_mask, env->segs[R_FS].selector);
    791                 PUSHL(ssp, esp, sp_mask, env->segs[R_DS].selector);
    792                 PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector);
    793             }
    794             PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector);
    795             PUSHL(ssp, esp, sp_mask, ESP);
    796         }
    797         PUSHL(ssp, esp, sp_mask, compute_eflags());
    798         PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector);
    799         PUSHL(ssp, esp, sp_mask, old_eip);
    800         if (has_error_code) {
    801             PUSHL(ssp, esp, sp_mask, error_code);
    802         }
    803     } else {
    804         if (new_stack) {
    805             if (env->eflags & VM_MASK) {
    806                 PUSHW(ssp, esp, sp_mask, env->segs[R_GS].selector);
    807                 PUSHW(ssp, esp, sp_mask, env->segs[R_FS].selector);
    808                 PUSHW(ssp, esp, sp_mask, env->segs[R_DS].selector);
    809                 PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector);
    810             }
    811             PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector);
    812             PUSHW(ssp, esp, sp_mask, ESP);
    813         }
    814         PUSHW(ssp, esp, sp_mask, compute_eflags());
    815         PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);
    816         PUSHW(ssp, esp, sp_mask, old_eip);
    817         if (has_error_code) {
    818             PUSHW(ssp, esp, sp_mask, error_code);
    819         }
    820     }
    821 
    822     if (new_stack) {
    823         if (env->eflags & VM_MASK) {
    824             cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);
    825             cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0, 0);
    826             cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0, 0);
    827             cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0);
    828         }
    829         ss = (ss & ~3) | dpl;
    830         cpu_x86_load_seg_cache(env, R_SS, ss,
    831                                ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);
    832     }
    833     SET_ESP(esp, sp_mask);
    834 
    835     selector = (selector & ~3) | dpl;
    836     cpu_x86_load_seg_cache(env, R_CS, selector,
    837                    get_seg_base(e1, e2),
    838                    get_seg_limit(e1, e2),
    839                    e2);
    840     cpu_x86_set_cpl(env, dpl);
    841     env->eip = offset;
    842 
    843     /* interrupt gate clear IF mask */
    844     if ((type & 1) == 0) {
    845         env->eflags &= ~IF_MASK;
    846     }
    847     env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
    848 }
    849 
    850 #ifdef TARGET_X86_64
    851 
    852 #define PUSHQ(sp, val)\
    853 {\
    854     sp -= 8;\
    855     stq_kernel(sp, (val));\
    856 }
    857 
    858 #define POPQ(sp, val)\
    859 {\
    860     val = ldq_kernel(sp);\
    861     sp += 8;\
    862 }
    863 
    864 static inline target_ulong get_rsp_from_tss(int level)
    865 {
    866     int index;
    867 
    868 #if 0
    869     printf("TR: base=" TARGET_FMT_lx " limit=%x\n",
    870            env->tr.base, env->tr.limit);
    871 #endif
    872 
    873     if (!(env->tr.flags & DESC_P_MASK))
    874         cpu_abort(env, "invalid tss");
    875     index = 8 * level + 4;
    876     if ((index + 7) > env->tr.limit)
    877         raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
    878     return ldq_kernel(env->tr.base + index);
    879 }
    880 
    881 /* 64 bit interrupt */
    882 static void do_interrupt64(int intno, int is_int, int error_code,
    883                            target_ulong next_eip, int is_hw)
    884 {
    885     SegmentCache *dt;
    886     target_ulong ptr;
    887     int type, dpl, selector, cpl, ist;
    888     int has_error_code, new_stack;
    889     uint32_t e1, e2, e3, ss;
    890     target_ulong old_eip, esp, offset;
    891 
    892     has_error_code = 0;
    893     if (!is_int && !is_hw)
    894         has_error_code = exeption_has_error_code(intno);
    895     if (is_int)
    896         old_eip = next_eip;
    897     else
    898         old_eip = env->eip;
    899 
    900     dt = &env->idt;
    901     if (intno * 16 + 15 > dt->limit)
    902         raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
    903     ptr = dt->base + intno * 16;
    904     e1 = ldl_kernel(ptr);
    905     e2 = ldl_kernel(ptr + 4);
    906     e3 = ldl_kernel(ptr + 8);
    907     /* check gate type */
    908     type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
    909     switch(type) {
    910     case 14: /* 386 interrupt gate */
    911     case 15: /* 386 trap gate */
    912         break;
    913     default:
    914         raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
    915         break;
    916     }
    917     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
    918     cpl = env->hflags & HF_CPL_MASK;
    919     /* check privilege if software int */
    920     if (is_int && dpl < cpl)
    921         raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
    922     /* check valid bit */
    923     if (!(e2 & DESC_P_MASK))
    924         raise_exception_err(EXCP0B_NOSEG, intno * 16 + 2);
    925     selector = e1 >> 16;
    926     offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);
    927     ist = e2 & 7;
    928     if ((selector & 0xfffc) == 0)
    929         raise_exception_err(EXCP0D_GPF, 0);
    930 
    931     if (load_segment(&e1, &e2, selector) != 0)
    932         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    933     if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
    934         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    935     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
    936     if (dpl > cpl)
    937         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    938     if (!(e2 & DESC_P_MASK))
    939         raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
    940     if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK))
    941         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    942     if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
    943         /* to inner privilege */
    944         if (ist != 0)
    945             esp = get_rsp_from_tss(ist + 3);
    946         else
    947             esp = get_rsp_from_tss(dpl);
    948         esp &= ~0xfLL; /* align stack */
    949         ss = 0;
    950         new_stack = 1;
    951     } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
    952         /* to same privilege */
    953         if (env->eflags & VM_MASK)
    954             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    955         new_stack = 0;
    956         if (ist != 0)
    957             esp = get_rsp_from_tss(ist + 3);
    958         else
    959             esp = ESP;
    960         esp &= ~0xfLL; /* align stack */
    961         dpl = cpl;
    962     } else {
    963         raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    964         new_stack = 0; /* avoid warning */
    965         esp = 0; /* avoid warning */
    966     }
    967 
    968     PUSHQ(esp, env->segs[R_SS].selector);
    969     PUSHQ(esp, ESP);
    970     PUSHQ(esp, compute_eflags());
    971     PUSHQ(esp, env->segs[R_CS].selector);
    972     PUSHQ(esp, old_eip);
    973     if (has_error_code) {
    974         PUSHQ(esp, error_code);
    975     }
    976 
    977     if (new_stack) {
    978         ss = 0 | dpl;
    979         cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
    980     }
    981     ESP = esp;
    982 
    983     selector = (selector & ~3) | dpl;
    984     cpu_x86_load_seg_cache(env, R_CS, selector,
    985                    get_seg_base(e1, e2),
    986                    get_seg_limit(e1, e2),
    987                    e2);
    988     cpu_x86_set_cpl(env, dpl);
    989     env->eip = offset;
    990 
    991     /* interrupt gate clear IF mask */
    992     if ((type & 1) == 0) {
    993         env->eflags &= ~IF_MASK;
    994     }
    995     env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
    996 }
    997 #endif
    998 
    999 #ifdef TARGET_X86_64
   1000 #if defined(CONFIG_USER_ONLY)
   1001 void helper_syscall(int next_eip_addend)
   1002 {
   1003     env->exception_index = EXCP_SYSCALL;
   1004     env->exception_next_eip = env->eip + next_eip_addend;
   1005     cpu_loop_exit();
   1006 }
   1007 #else
   1008 void helper_syscall(int next_eip_addend)
   1009 {
   1010     int selector;
   1011 
   1012     if (!(env->efer & MSR_EFER_SCE)) {
   1013         raise_exception_err(EXCP06_ILLOP, 0);
   1014     }
   1015     selector = (env->star >> 32) & 0xffff;
   1016     if (env->hflags & HF_LMA_MASK) {
   1017         int code64;
   1018 
   1019         ECX = env->eip + next_eip_addend;
   1020         env->regs[11] = compute_eflags();
   1021 
   1022         code64 = env->hflags & HF_CS64_MASK;
   1023 
   1024         cpu_x86_set_cpl(env, 0);
   1025         cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
   1026                            0, 0xffffffff,
   1027                                DESC_G_MASK | DESC_P_MASK |
   1028                                DESC_S_MASK |
   1029                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
   1030         cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
   1031                                0, 0xffffffff,
   1032                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   1033                                DESC_S_MASK |
   1034                                DESC_W_MASK | DESC_A_MASK);
   1035         env->eflags &= ~env->fmask;
   1036         load_eflags(env->eflags, 0);
   1037         if (code64)
   1038             env->eip = env->lstar;
   1039         else
   1040             env->eip = env->cstar;
   1041     } else {
   1042         ECX = (uint32_t)(env->eip + next_eip_addend);
   1043 
   1044         cpu_x86_set_cpl(env, 0);
   1045         cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
   1046                            0, 0xffffffff,
   1047                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   1048                                DESC_S_MASK |
   1049                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
   1050         cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
   1051                                0, 0xffffffff,
   1052                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   1053                                DESC_S_MASK |
   1054                                DESC_W_MASK | DESC_A_MASK);
   1055         env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
   1056         env->eip = (uint32_t)env->star;
   1057     }
   1058 }
   1059 #endif
   1060 #endif
   1061 
   1062 #ifdef TARGET_X86_64
   1063 void helper_sysret(int dflag)
   1064 {
   1065     int cpl, selector;
   1066 
   1067     if (!(env->efer & MSR_EFER_SCE)) {
   1068         raise_exception_err(EXCP06_ILLOP, 0);
   1069     }
   1070     cpl = env->hflags & HF_CPL_MASK;
   1071     if (!(env->cr[0] & CR0_PE_MASK) || cpl != 0) {
   1072         raise_exception_err(EXCP0D_GPF, 0);
   1073     }
   1074     selector = (env->star >> 48) & 0xffff;
   1075     if (env->hflags & HF_LMA_MASK) {
   1076         if (dflag == 2) {
   1077             cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
   1078                                    0, 0xffffffff,
   1079                                    DESC_G_MASK | DESC_P_MASK |
   1080                                    DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   1081                                    DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
   1082                                    DESC_L_MASK);
   1083             env->eip = ECX;
   1084         } else {
   1085             cpu_x86_load_seg_cache(env, R_CS, selector | 3,
   1086                                    0, 0xffffffff,
   1087                                    DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   1088                                    DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   1089                                    DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
   1090             env->eip = (uint32_t)ECX;
   1091         }
   1092         cpu_x86_load_seg_cache(env, R_SS, selector + 8,
   1093                                0, 0xffffffff,
   1094                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   1095                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   1096                                DESC_W_MASK | DESC_A_MASK);
   1097         load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK |
   1098                     IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK);
   1099         cpu_x86_set_cpl(env, 3);
   1100     } else {
   1101         cpu_x86_load_seg_cache(env, R_CS, selector | 3,
   1102                                0, 0xffffffff,
   1103                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   1104                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   1105                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
   1106         env->eip = (uint32_t)ECX;
   1107         cpu_x86_load_seg_cache(env, R_SS, selector + 8,
   1108                                0, 0xffffffff,
   1109                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   1110                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   1111                                DESC_W_MASK | DESC_A_MASK);
   1112         env->eflags |= IF_MASK;
   1113         cpu_x86_set_cpl(env, 3);
   1114     }
   1115 #ifdef CONFIG_KQEMU
   1116     if (kqemu_is_ok(env)) {
   1117         if (env->hflags & HF_LMA_MASK)
   1118             CC_OP = CC_OP_EFLAGS;
   1119         env->exception_index = -1;
   1120         cpu_loop_exit();
   1121     }
   1122 #endif
   1123 }
   1124 #endif
   1125 
   1126 /* real mode interrupt */
   1127 static void do_interrupt_real(int intno, int is_int, int error_code,
   1128                               unsigned int next_eip)
   1129 {
   1130     SegmentCache *dt;
   1131     target_ulong ptr, ssp;
   1132     int selector;
   1133     uint32_t offset, esp;
   1134     uint32_t old_cs, old_eip;
   1135 
   1136     /* real mode (simpler !) */
   1137     dt = &env->idt;
   1138     if (intno * 4 + 3 > dt->limit)
   1139         raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
   1140     ptr = dt->base + intno * 4;
   1141     offset = lduw_kernel(ptr);
   1142     selector = lduw_kernel(ptr + 2);
   1143     esp = ESP;
   1144     ssp = env->segs[R_SS].base;
   1145     if (is_int)
   1146         old_eip = next_eip;
   1147     else
   1148         old_eip = env->eip;
   1149     old_cs = env->segs[R_CS].selector;
   1150     /* XXX: use SS segment size ? */
   1151     PUSHW(ssp, esp, 0xffff, compute_eflags());
   1152     PUSHW(ssp, esp, 0xffff, old_cs);
   1153     PUSHW(ssp, esp, 0xffff, old_eip);
   1154 
   1155     /* update processor state */
   1156     ESP = (ESP & ~0xffff) | (esp & 0xffff);
   1157     env->eip = offset;
   1158     env->segs[R_CS].selector = selector;
   1159     env->segs[R_CS].base = (selector << 4);
   1160     env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);
   1161 }
   1162 
   1163 /* fake user mode interrupt */
   1164 void do_interrupt_user(int intno, int is_int, int error_code,
   1165                        target_ulong next_eip)
   1166 {
   1167     SegmentCache *dt;
   1168     target_ulong ptr;
   1169     int dpl, cpl, shift;
   1170     uint32_t e2;
   1171 
   1172     dt = &env->idt;
   1173     if (env->hflags & HF_LMA_MASK) {
   1174         shift = 4;
   1175     } else {
   1176         shift = 3;
   1177     }
   1178     ptr = dt->base + (intno << shift);
   1179     e2 = ldl_kernel(ptr + 4);
   1180 
   1181     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   1182     cpl = env->hflags & HF_CPL_MASK;
   1183     /* check privilege if software int */
   1184     if (is_int && dpl < cpl)
   1185         raise_exception_err(EXCP0D_GPF, (intno << shift) + 2);
   1186 
   1187     /* Since we emulate only user space, we cannot do more than
   1188        exiting the emulation with the suitable exception and error
   1189        code */
   1190     if (is_int)
   1191         EIP = next_eip;
   1192 }
   1193 
   1194 #if !defined(CONFIG_USER_ONLY)
   1195 static void handle_even_inj(int intno, int is_int, int error_code,
   1196 		int is_hw, int rm)
   1197 {
   1198     uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
   1199     if (!(event_inj & SVM_EVTINJ_VALID)) {
   1200 	    int type;
   1201 	    if (is_int)
   1202 		    type = SVM_EVTINJ_TYPE_SOFT;
   1203 	    else
   1204 		    type = SVM_EVTINJ_TYPE_EXEPT;
   1205 	    event_inj = intno | type | SVM_EVTINJ_VALID;
   1206 	    if (!rm && exeption_has_error_code(intno)) {
   1207 		    event_inj |= SVM_EVTINJ_VALID_ERR;
   1208 		    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err), error_code);
   1209 	    }
   1210 	    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj);
   1211     }
   1212 }
   1213 #endif
   1214 
   1215 /*
   1216  * Begin execution of an interruption. is_int is TRUE if coming from
   1217  * the int instruction. next_eip is the EIP value AFTER the interrupt
   1218  * instruction. It is only relevant if is_int is TRUE.
   1219  */
   1220 void do_interrupt(int intno, int is_int, int error_code,
   1221                   target_ulong next_eip, int is_hw)
   1222 {
   1223     if (qemu_loglevel_mask(CPU_LOG_INT)) {
   1224         if ((env->cr[0] & CR0_PE_MASK)) {
   1225             static int count;
   1226             qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx,
   1227                     count, intno, error_code, is_int,
   1228                     env->hflags & HF_CPL_MASK,
   1229                     env->segs[R_CS].selector, EIP,
   1230                     (int)env->segs[R_CS].base + EIP,
   1231                     env->segs[R_SS].selector, ESP);
   1232             if (intno == 0x0e) {
   1233                 qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]);
   1234             } else {
   1235                 qemu_log(" EAX=" TARGET_FMT_lx, EAX);
   1236             }
   1237             qemu_log("\n");
   1238             log_cpu_state(env, X86_DUMP_CCOP);
   1239 #if 0
   1240             {
   1241                 int i;
   1242                 uint8_t *ptr;
   1243                 qemu_log("       code=");
   1244                 ptr = env->segs[R_CS].base + env->eip;
   1245                 for(i = 0; i < 16; i++) {
   1246                     qemu_log(" %02x", ldub(ptr + i));
   1247                 }
   1248                 qemu_log("\n");
   1249             }
   1250 #endif
   1251             count++;
   1252         }
   1253     }
   1254     if (env->cr[0] & CR0_PE_MASK) {
   1255 #if !defined(CONFIG_USER_ONLY)
   1256         if (env->hflags & HF_SVMI_MASK)
   1257             handle_even_inj(intno, is_int, error_code, is_hw, 0);
   1258 #endif
   1259 #ifdef TARGET_X86_64
   1260         if (env->hflags & HF_LMA_MASK) {
   1261             do_interrupt64(intno, is_int, error_code, next_eip, is_hw);
   1262         } else
   1263 #endif
   1264         {
   1265             do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
   1266         }
   1267     } else {
   1268 #if !defined(CONFIG_USER_ONLY)
   1269         if (env->hflags & HF_SVMI_MASK)
   1270             handle_even_inj(intno, is_int, error_code, is_hw, 1);
   1271 #endif
   1272         do_interrupt_real(intno, is_int, error_code, next_eip);
   1273     }
   1274 
   1275 #if !defined(CONFIG_USER_ONLY)
   1276     if (env->hflags & HF_SVMI_MASK) {
   1277 	    uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
   1278 	    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID);
   1279     }
   1280 #endif
   1281 }
   1282 
   1283 /* This should come from sysemu.h - if we could include it here... */
   1284 void qemu_system_reset_request(void);
   1285 
   1286 /*
   1287  * Check nested exceptions and change to double or triple fault if
   1288  * needed. It should only be called, if this is not an interrupt.
   1289  * Returns the new exception number.
   1290  */
   1291 static int check_exception(int intno, int *error_code)
   1292 {
   1293     int first_contributory = env->old_exception == 0 ||
   1294                               (env->old_exception >= 10 &&
   1295                                env->old_exception <= 13);
   1296     int second_contributory = intno == 0 ||
   1297                                (intno >= 10 && intno <= 13);
   1298 
   1299     qemu_log_mask(CPU_LOG_INT, "check_exception old: 0x%x new 0x%x\n",
   1300                 env->old_exception, intno);
   1301 
   1302 #if !defined(CONFIG_USER_ONLY)
   1303     if (env->old_exception == EXCP08_DBLE) {
   1304         if (env->hflags & HF_SVMI_MASK)
   1305             helper_vmexit(SVM_EXIT_SHUTDOWN, 0); /* does not return */
   1306 
   1307         qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
   1308 
   1309         qemu_system_reset_request();
   1310         return EXCP_HLT;
   1311     }
   1312 #endif
   1313 
   1314     if ((first_contributory && second_contributory)
   1315         || (env->old_exception == EXCP0E_PAGE &&
   1316             (second_contributory || (intno == EXCP0E_PAGE)))) {
   1317         intno = EXCP08_DBLE;
   1318         *error_code = 0;
   1319     }
   1320 
   1321     if (second_contributory || (intno == EXCP0E_PAGE) ||
   1322         (intno == EXCP08_DBLE))
   1323         env->old_exception = intno;
   1324 
   1325     return intno;
   1326 }
   1327 
   1328 /*
   1329  * Signal an interruption. It is executed in the main CPU loop.
   1330  * is_int is TRUE if coming from the int instruction. next_eip is the
   1331  * EIP value AFTER the interrupt instruction. It is only relevant if
   1332  * is_int is TRUE.
   1333  */
   1334 static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code,
   1335                                           int next_eip_addend)
   1336 {
   1337     if (!is_int) {
   1338         helper_svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code);
   1339         intno = check_exception(intno, &error_code);
   1340     } else {
   1341         helper_svm_check_intercept_param(SVM_EXIT_SWINT, 0);
   1342     }
   1343 
   1344     env->exception_index = intno;
   1345     env->error_code = error_code;
   1346     env->exception_is_int = is_int;
   1347     env->exception_next_eip = env->eip + next_eip_addend;
   1348     cpu_loop_exit();
   1349 }
   1350 
   1351 /* shortcuts to generate exceptions */
   1352 
   1353 void raise_exception_err(int exception_index, int error_code)
   1354 {
   1355     raise_interrupt(exception_index, 0, error_code, 0);
   1356 }
   1357 
   1358 void raise_exception(int exception_index)
   1359 {
   1360     raise_interrupt(exception_index, 0, 0, 0);
   1361 }
   1362 
   1363 /* SMM support */
   1364 
   1365 #if defined(CONFIG_USER_ONLY)
   1366 
   1367 void do_smm_enter(void)
   1368 {
   1369 }
   1370 
   1371 void helper_rsm(void)
   1372 {
   1373 }
   1374 
   1375 #else
   1376 
   1377 #ifdef TARGET_X86_64
   1378 #define SMM_REVISION_ID 0x00020064
   1379 #else
   1380 #define SMM_REVISION_ID 0x00020000
   1381 #endif
   1382 
   1383 void do_smm_enter(void)
   1384 {
   1385     target_ulong sm_state;
   1386     SegmentCache *dt;
   1387     int i, offset;
   1388 
   1389     qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
   1390     log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
   1391 
   1392     env->hflags |= HF_SMM_MASK;
   1393     cpu_smm_update(env);
   1394 
   1395     sm_state = env->smbase + 0x8000;
   1396 
   1397 #ifdef TARGET_X86_64
   1398     for(i = 0; i < 6; i++) {
   1399         dt = &env->segs[i];
   1400         offset = 0x7e00 + i * 16;
   1401         stw_phys(sm_state + offset, dt->selector);
   1402         stw_phys(sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
   1403         stl_phys(sm_state + offset + 4, dt->limit);
   1404         stq_phys(sm_state + offset + 8, dt->base);
   1405     }
   1406 
   1407     stq_phys(sm_state + 0x7e68, env->gdt.base);
   1408     stl_phys(sm_state + 0x7e64, env->gdt.limit);
   1409 
   1410     stw_phys(sm_state + 0x7e70, env->ldt.selector);
   1411     stq_phys(sm_state + 0x7e78, env->ldt.base);
   1412     stl_phys(sm_state + 0x7e74, env->ldt.limit);
   1413     stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
   1414 
   1415     stq_phys(sm_state + 0x7e88, env->idt.base);
   1416     stl_phys(sm_state + 0x7e84, env->idt.limit);
   1417 
   1418     stw_phys(sm_state + 0x7e90, env->tr.selector);
   1419     stq_phys(sm_state + 0x7e98, env->tr.base);
   1420     stl_phys(sm_state + 0x7e94, env->tr.limit);
   1421     stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
   1422 
   1423     stq_phys(sm_state + 0x7ed0, env->efer);
   1424 
   1425     stq_phys(sm_state + 0x7ff8, EAX);
   1426     stq_phys(sm_state + 0x7ff0, ECX);
   1427     stq_phys(sm_state + 0x7fe8, EDX);
   1428     stq_phys(sm_state + 0x7fe0, EBX);
   1429     stq_phys(sm_state + 0x7fd8, ESP);
   1430     stq_phys(sm_state + 0x7fd0, EBP);
   1431     stq_phys(sm_state + 0x7fc8, ESI);
   1432     stq_phys(sm_state + 0x7fc0, EDI);
   1433     for(i = 8; i < 16; i++)
   1434         stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]);
   1435     stq_phys(sm_state + 0x7f78, env->eip);
   1436     stl_phys(sm_state + 0x7f70, compute_eflags());
   1437     stl_phys(sm_state + 0x7f68, env->dr[6]);
   1438     stl_phys(sm_state + 0x7f60, env->dr[7]);
   1439 
   1440     stl_phys(sm_state + 0x7f48, env->cr[4]);
   1441     stl_phys(sm_state + 0x7f50, env->cr[3]);
   1442     stl_phys(sm_state + 0x7f58, env->cr[0]);
   1443 
   1444     stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
   1445     stl_phys(sm_state + 0x7f00, env->smbase);
   1446 #else
   1447     stl_phys(sm_state + 0x7ffc, env->cr[0]);
   1448     stl_phys(sm_state + 0x7ff8, env->cr[3]);
   1449     stl_phys(sm_state + 0x7ff4, compute_eflags());
   1450     stl_phys(sm_state + 0x7ff0, env->eip);
   1451     stl_phys(sm_state + 0x7fec, EDI);
   1452     stl_phys(sm_state + 0x7fe8, ESI);
   1453     stl_phys(sm_state + 0x7fe4, EBP);
   1454     stl_phys(sm_state + 0x7fe0, ESP);
   1455     stl_phys(sm_state + 0x7fdc, EBX);
   1456     stl_phys(sm_state + 0x7fd8, EDX);
   1457     stl_phys(sm_state + 0x7fd4, ECX);
   1458     stl_phys(sm_state + 0x7fd0, EAX);
   1459     stl_phys(sm_state + 0x7fcc, env->dr[6]);
   1460     stl_phys(sm_state + 0x7fc8, env->dr[7]);
   1461 
   1462     stl_phys(sm_state + 0x7fc4, env->tr.selector);
   1463     stl_phys(sm_state + 0x7f64, env->tr.base);
   1464     stl_phys(sm_state + 0x7f60, env->tr.limit);
   1465     stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
   1466 
   1467     stl_phys(sm_state + 0x7fc0, env->ldt.selector);
   1468     stl_phys(sm_state + 0x7f80, env->ldt.base);
   1469     stl_phys(sm_state + 0x7f7c, env->ldt.limit);
   1470     stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
   1471 
   1472     stl_phys(sm_state + 0x7f74, env->gdt.base);
   1473     stl_phys(sm_state + 0x7f70, env->gdt.limit);
   1474 
   1475     stl_phys(sm_state + 0x7f58, env->idt.base);
   1476     stl_phys(sm_state + 0x7f54, env->idt.limit);
   1477 
   1478     for(i = 0; i < 6; i++) {
   1479         dt = &env->segs[i];
   1480         if (i < 3)
   1481             offset = 0x7f84 + i * 12;
   1482         else
   1483             offset = 0x7f2c + (i - 3) * 12;
   1484         stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector);
   1485         stl_phys(sm_state + offset + 8, dt->base);
   1486         stl_phys(sm_state + offset + 4, dt->limit);
   1487         stl_phys(sm_state + offset, (dt->flags >> 8) & 0xf0ff);
   1488     }
   1489     stl_phys(sm_state + 0x7f14, env->cr[4]);
   1490 
   1491     stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
   1492     stl_phys(sm_state + 0x7ef8, env->smbase);
   1493 #endif
   1494     /* init SMM cpu state */
   1495 
   1496 #ifdef TARGET_X86_64
   1497     cpu_load_efer(env, 0);
   1498 #endif
   1499     load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
   1500     env->eip = 0x00008000;
   1501     cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
   1502                            0xffffffff, 0);
   1503     cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0);
   1504     cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0);
   1505     cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
   1506     cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
   1507     cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
   1508 
   1509     cpu_x86_update_cr0(env,
   1510                        env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
   1511     cpu_x86_update_cr4(env, 0);
   1512     env->dr[7] = 0x00000400;
   1513     CC_OP = CC_OP_EFLAGS;
   1514 }
   1515 
   1516 void helper_rsm(void)
   1517 {
   1518     target_ulong sm_state;
   1519     int i, offset;
   1520     uint32_t val;
   1521 
   1522     sm_state = env->smbase + 0x8000;
   1523 #ifdef TARGET_X86_64
   1524     cpu_load_efer(env, ldq_phys(sm_state + 0x7ed0));
   1525 
   1526     for(i = 0; i < 6; i++) {
   1527         offset = 0x7e00 + i * 16;
   1528         cpu_x86_load_seg_cache(env, i,
   1529                                lduw_phys(sm_state + offset),
   1530                                ldq_phys(sm_state + offset + 8),
   1531                                ldl_phys(sm_state + offset + 4),
   1532                                (lduw_phys(sm_state + offset + 2) & 0xf0ff) << 8);
   1533     }
   1534 
   1535     env->gdt.base = ldq_phys(sm_state + 0x7e68);
   1536     env->gdt.limit = ldl_phys(sm_state + 0x7e64);
   1537 
   1538     env->ldt.selector = lduw_phys(sm_state + 0x7e70);
   1539     env->ldt.base = ldq_phys(sm_state + 0x7e78);
   1540     env->ldt.limit = ldl_phys(sm_state + 0x7e74);
   1541     env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8;
   1542 
   1543     env->idt.base = ldq_phys(sm_state + 0x7e88);
   1544     env->idt.limit = ldl_phys(sm_state + 0x7e84);
   1545 
   1546     env->tr.selector = lduw_phys(sm_state + 0x7e90);
   1547     env->tr.base = ldq_phys(sm_state + 0x7e98);
   1548     env->tr.limit = ldl_phys(sm_state + 0x7e94);
   1549     env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
   1550 
   1551     EAX = ldq_phys(sm_state + 0x7ff8);
   1552     ECX = ldq_phys(sm_state + 0x7ff0);
   1553     EDX = ldq_phys(sm_state + 0x7fe8);
   1554     EBX = ldq_phys(sm_state + 0x7fe0);
   1555     ESP = ldq_phys(sm_state + 0x7fd8);
   1556     EBP = ldq_phys(sm_state + 0x7fd0);
   1557     ESI = ldq_phys(sm_state + 0x7fc8);
   1558     EDI = ldq_phys(sm_state + 0x7fc0);
   1559     for(i = 8; i < 16; i++)
   1560         env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8);
   1561     env->eip = ldq_phys(sm_state + 0x7f78);
   1562     load_eflags(ldl_phys(sm_state + 0x7f70),
   1563                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
   1564     env->dr[6] = ldl_phys(sm_state + 0x7f68);
   1565     env->dr[7] = ldl_phys(sm_state + 0x7f60);
   1566 
   1567     cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f48));
   1568     cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7f50));
   1569     cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7f58));
   1570 
   1571     val = ldl_phys(sm_state + 0x7efc); /* revision ID */
   1572     if (val & 0x20000) {
   1573         env->smbase = ldl_phys(sm_state + 0x7f00) & ~0x7fff;
   1574     }
   1575 #else
   1576     cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc));
   1577     cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8));
   1578     load_eflags(ldl_phys(sm_state + 0x7ff4),
   1579                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
   1580     env->eip = ldl_phys(sm_state + 0x7ff0);
   1581     EDI = ldl_phys(sm_state + 0x7fec);
   1582     ESI = ldl_phys(sm_state + 0x7fe8);
   1583     EBP = ldl_phys(sm_state + 0x7fe4);
   1584     ESP = ldl_phys(sm_state + 0x7fe0);
   1585     EBX = ldl_phys(sm_state + 0x7fdc);
   1586     EDX = ldl_phys(sm_state + 0x7fd8);
   1587     ECX = ldl_phys(sm_state + 0x7fd4);
   1588     EAX = ldl_phys(sm_state + 0x7fd0);
   1589     env->dr[6] = ldl_phys(sm_state + 0x7fcc);
   1590     env->dr[7] = ldl_phys(sm_state + 0x7fc8);
   1591 
   1592     env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff;
   1593     env->tr.base = ldl_phys(sm_state + 0x7f64);
   1594     env->tr.limit = ldl_phys(sm_state + 0x7f60);
   1595     env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8;
   1596 
   1597     env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff;
   1598     env->ldt.base = ldl_phys(sm_state + 0x7f80);
   1599     env->ldt.limit = ldl_phys(sm_state + 0x7f7c);
   1600     env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8;
   1601 
   1602     env->gdt.base = ldl_phys(sm_state + 0x7f74);
   1603     env->gdt.limit = ldl_phys(sm_state + 0x7f70);
   1604 
   1605     env->idt.base = ldl_phys(sm_state + 0x7f58);
   1606     env->idt.limit = ldl_phys(sm_state + 0x7f54);
   1607 
   1608     for(i = 0; i < 6; i++) {
   1609         if (i < 3)
   1610             offset = 0x7f84 + i * 12;
   1611         else
   1612             offset = 0x7f2c + (i - 3) * 12;
   1613         cpu_x86_load_seg_cache(env, i,
   1614                                ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff,
   1615                                ldl_phys(sm_state + offset + 8),
   1616                                ldl_phys(sm_state + offset + 4),
   1617                                (ldl_phys(sm_state + offset) & 0xf0ff) << 8);
   1618     }
   1619     cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f14));
   1620 
   1621     val = ldl_phys(sm_state + 0x7efc); /* revision ID */
   1622     if (val & 0x20000) {
   1623         env->smbase = ldl_phys(sm_state + 0x7ef8) & ~0x7fff;
   1624     }
   1625 #endif
   1626     CC_OP = CC_OP_EFLAGS;
   1627     env->hflags &= ~HF_SMM_MASK;
   1628     cpu_smm_update(env);
   1629 
   1630     qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
   1631     log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
   1632 }
   1633 
   1634 #endif /* !CONFIG_USER_ONLY */
   1635 
   1636 
   1637 /* division, flags are undefined */
   1638 
   1639 void helper_divb_AL(target_ulong t0)
   1640 {
   1641     unsigned int num, den, q, r;
   1642 
   1643     num = (EAX & 0xffff);
   1644     den = (t0 & 0xff);
   1645     if (den == 0) {
   1646         raise_exception(EXCP00_DIVZ);
   1647     }
   1648     q = (num / den);
   1649     if (q > 0xff)
   1650         raise_exception(EXCP00_DIVZ);
   1651     q &= 0xff;
   1652     r = (num % den) & 0xff;
   1653     EAX = (EAX & ~0xffff) | (r << 8) | q;
   1654 }
   1655 
   1656 void helper_idivb_AL(target_ulong t0)
   1657 {
   1658     int num, den, q, r;
   1659 
   1660     num = (int16_t)EAX;
   1661     den = (int8_t)t0;
   1662     if (den == 0) {
   1663         raise_exception(EXCP00_DIVZ);
   1664     }
   1665     q = (num / den);
   1666     if (q != (int8_t)q)
   1667         raise_exception(EXCP00_DIVZ);
   1668     q &= 0xff;
   1669     r = (num % den) & 0xff;
   1670     EAX = (EAX & ~0xffff) | (r << 8) | q;
   1671 }
   1672 
   1673 void helper_divw_AX(target_ulong t0)
   1674 {
   1675     unsigned int num, den, q, r;
   1676 
   1677     num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
   1678     den = (t0 & 0xffff);
   1679     if (den == 0) {
   1680         raise_exception(EXCP00_DIVZ);
   1681     }
   1682     q = (num / den);
   1683     if (q > 0xffff)
   1684         raise_exception(EXCP00_DIVZ);
   1685     q &= 0xffff;
   1686     r = (num % den) & 0xffff;
   1687     EAX = (EAX & ~0xffff) | q;
   1688     EDX = (EDX & ~0xffff) | r;
   1689 }
   1690 
   1691 void helper_idivw_AX(target_ulong t0)
   1692 {
   1693     int num, den, q, r;
   1694 
   1695     num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
   1696     den = (int16_t)t0;
   1697     if (den == 0) {
   1698         raise_exception(EXCP00_DIVZ);
   1699     }
   1700     q = (num / den);
   1701     if (q != (int16_t)q)
   1702         raise_exception(EXCP00_DIVZ);
   1703     q &= 0xffff;
   1704     r = (num % den) & 0xffff;
   1705     EAX = (EAX & ~0xffff) | q;
   1706     EDX = (EDX & ~0xffff) | r;
   1707 }
   1708 
   1709 void helper_divl_EAX(target_ulong t0)
   1710 {
   1711     unsigned int den, r;
   1712     uint64_t num, q;
   1713 
   1714     num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
   1715     den = t0;
   1716     if (den == 0) {
   1717         raise_exception(EXCP00_DIVZ);
   1718     }
   1719     q = (num / den);
   1720     r = (num % den);
   1721     if (q > 0xffffffff)
   1722         raise_exception(EXCP00_DIVZ);
   1723     EAX = (uint32_t)q;
   1724     EDX = (uint32_t)r;
   1725 }
   1726 
   1727 void helper_idivl_EAX(target_ulong t0)
   1728 {
   1729     int den, r;
   1730     int64_t num, q;
   1731 
   1732     num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
   1733     den = t0;
   1734     if (den == 0) {
   1735         raise_exception(EXCP00_DIVZ);
   1736     }
   1737     q = (num / den);
   1738     r = (num % den);
   1739     if (q != (int32_t)q)
   1740         raise_exception(EXCP00_DIVZ);
   1741     EAX = (uint32_t)q;
   1742     EDX = (uint32_t)r;
   1743 }
   1744 
   1745 /* bcd */
   1746 
   1747 /* XXX: exception */
   1748 void helper_aam(int base)
   1749 {
   1750     int al, ah;
   1751     al = EAX & 0xff;
   1752     ah = al / base;
   1753     al = al % base;
   1754     EAX = (EAX & ~0xffff) | al | (ah << 8);
   1755     CC_DST = al;
   1756 }
   1757 
   1758 void helper_aad(int base)
   1759 {
   1760     int al, ah;
   1761     al = EAX & 0xff;
   1762     ah = (EAX >> 8) & 0xff;
   1763     al = ((ah * base) + al) & 0xff;
   1764     EAX = (EAX & ~0xffff) | al;
   1765     CC_DST = al;
   1766 }
   1767 
   1768 void helper_aaa(void)
   1769 {
   1770     int icarry;
   1771     int al, ah, af;
   1772     int eflags;
   1773 
   1774     eflags = helper_cc_compute_all(CC_OP);
   1775     af = eflags & CC_A;
   1776     al = EAX & 0xff;
   1777     ah = (EAX >> 8) & 0xff;
   1778 
   1779     icarry = (al > 0xf9);
   1780     if (((al & 0x0f) > 9 ) || af) {
   1781         al = (al + 6) & 0x0f;
   1782         ah = (ah + 1 + icarry) & 0xff;
   1783         eflags |= CC_C | CC_A;
   1784     } else {
   1785         eflags &= ~(CC_C | CC_A);
   1786         al &= 0x0f;
   1787     }
   1788     EAX = (EAX & ~0xffff) | al | (ah << 8);
   1789     CC_SRC = eflags;
   1790 }
   1791 
   1792 void helper_aas(void)
   1793 {
   1794     int icarry;
   1795     int al, ah, af;
   1796     int eflags;
   1797 
   1798     eflags = helper_cc_compute_all(CC_OP);
   1799     af = eflags & CC_A;
   1800     al = EAX & 0xff;
   1801     ah = (EAX >> 8) & 0xff;
   1802 
   1803     icarry = (al < 6);
   1804     if (((al & 0x0f) > 9 ) || af) {
   1805         al = (al - 6) & 0x0f;
   1806         ah = (ah - 1 - icarry) & 0xff;
   1807         eflags |= CC_C | CC_A;
   1808     } else {
   1809         eflags &= ~(CC_C | CC_A);
   1810         al &= 0x0f;
   1811     }
   1812     EAX = (EAX & ~0xffff) | al | (ah << 8);
   1813     CC_SRC = eflags;
   1814 }
   1815 
   1816 void helper_daa(void)
   1817 {
   1818     int al, af, cf;
   1819     int eflags;
   1820 
   1821     eflags = helper_cc_compute_all(CC_OP);
   1822     cf = eflags & CC_C;
   1823     af = eflags & CC_A;
   1824     al = EAX & 0xff;
   1825 
   1826     eflags = 0;
   1827     if (((al & 0x0f) > 9 ) || af) {
   1828         al = (al + 6) & 0xff;
   1829         eflags |= CC_A;
   1830     }
   1831     if ((al > 0x9f) || cf) {
   1832         al = (al + 0x60) & 0xff;
   1833         eflags |= CC_C;
   1834     }
   1835     EAX = (EAX & ~0xff) | al;
   1836     /* well, speed is not an issue here, so we compute the flags by hand */
   1837     eflags |= (al == 0) << 6; /* zf */
   1838     eflags |= parity_table[al]; /* pf */
   1839     eflags |= (al & 0x80); /* sf */
   1840     CC_SRC = eflags;
   1841 }
   1842 
   1843 void helper_das(void)
   1844 {
   1845     int al, al1, af, cf;
   1846     int eflags;
   1847 
   1848     eflags = helper_cc_compute_all(CC_OP);
   1849     cf = eflags & CC_C;
   1850     af = eflags & CC_A;
   1851     al = EAX & 0xff;
   1852 
   1853     eflags = 0;
   1854     al1 = al;
   1855     if (((al & 0x0f) > 9 ) || af) {
   1856         eflags |= CC_A;
   1857         if (al < 6 || cf)
   1858             eflags |= CC_C;
   1859         al = (al - 6) & 0xff;
   1860     }
   1861     if ((al1 > 0x99) || cf) {
   1862         al = (al - 0x60) & 0xff;
   1863         eflags |= CC_C;
   1864     }
   1865     EAX = (EAX & ~0xff) | al;
   1866     /* well, speed is not an issue here, so we compute the flags by hand */
   1867     eflags |= (al == 0) << 6; /* zf */
   1868     eflags |= parity_table[al]; /* pf */
   1869     eflags |= (al & 0x80); /* sf */
   1870     CC_SRC = eflags;
   1871 }
   1872 
   1873 void helper_into(int next_eip_addend)
   1874 {
   1875     int eflags;
   1876     eflags = helper_cc_compute_all(CC_OP);
   1877     if (eflags & CC_O) {
   1878         raise_interrupt(EXCP04_INTO, 1, 0, next_eip_addend);
   1879     }
   1880 }
   1881 
   1882 void helper_cmpxchg8b(target_ulong a0)
   1883 {
   1884     uint64_t d;
   1885     int eflags;
   1886 
   1887     eflags = helper_cc_compute_all(CC_OP);
   1888     d = ldq(a0);
   1889     if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) {
   1890         stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX);
   1891         eflags |= CC_Z;
   1892     } else {
   1893         /* always do the store */
   1894         stq(a0, d);
   1895         EDX = (uint32_t)(d >> 32);
   1896         EAX = (uint32_t)d;
   1897         eflags &= ~CC_Z;
   1898     }
   1899     CC_SRC = eflags;
   1900 }
   1901 
   1902 #ifdef TARGET_X86_64
   1903 void helper_cmpxchg16b(target_ulong a0)
   1904 {
   1905     uint64_t d0, d1;
   1906     int eflags;
   1907 
   1908     if ((a0 & 0xf) != 0)
   1909         raise_exception(EXCP0D_GPF);
   1910     eflags = helper_cc_compute_all(CC_OP);
   1911     d0 = ldq(a0);
   1912     d1 = ldq(a0 + 8);
   1913     if (d0 == EAX && d1 == EDX) {
   1914         stq(a0, EBX);
   1915         stq(a0 + 8, ECX);
   1916         eflags |= CC_Z;
   1917     } else {
   1918         /* always do the store */
   1919         stq(a0, d0);
   1920         stq(a0 + 8, d1);
   1921         EDX = d1;
   1922         EAX = d0;
   1923         eflags &= ~CC_Z;
   1924     }
   1925     CC_SRC = eflags;
   1926 }
   1927 #endif
   1928 
   1929 void helper_single_step(void)
   1930 {
   1931 #ifndef CONFIG_USER_ONLY
   1932     check_hw_breakpoints(env, 1);
   1933     env->dr[6] |= DR6_BS;
   1934 #endif
   1935     raise_exception(EXCP01_DB);
   1936 }
   1937 
   1938 void helper_cpuid(void)
   1939 {
   1940     uint32_t eax, ebx, ecx, edx;
   1941 
   1942     helper_svm_check_intercept_param(SVM_EXIT_CPUID, 0);
   1943 
   1944     cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
   1945     EAX = eax;
   1946     EBX = ebx;
   1947     ECX = ecx;
   1948     EDX = edx;
   1949 }
   1950 
   1951 void helper_enter_level(int level, int data32, target_ulong t1)
   1952 {
   1953     target_ulong ssp;
   1954     uint32_t esp_mask, esp, ebp;
   1955 
   1956     esp_mask = get_sp_mask(env->segs[R_SS].flags);
   1957     ssp = env->segs[R_SS].base;
   1958     ebp = EBP;
   1959     esp = ESP;
   1960     if (data32) {
   1961         /* 32 bit */
   1962         esp -= 4;
   1963         while (--level) {
   1964             esp -= 4;
   1965             ebp -= 4;
   1966             stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
   1967         }
   1968         esp -= 4;
   1969         stl(ssp + (esp & esp_mask), t1);
   1970     } else {
   1971         /* 16 bit */
   1972         esp -= 2;
   1973         while (--level) {
   1974             esp -= 2;
   1975             ebp -= 2;
   1976             stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
   1977         }
   1978         esp -= 2;
   1979         stw(ssp + (esp & esp_mask), t1);
   1980     }
   1981 }
   1982 
   1983 #ifdef TARGET_X86_64
   1984 void helper_enter64_level(int level, int data64, target_ulong t1)
   1985 {
   1986     target_ulong esp, ebp;
   1987     ebp = EBP;
   1988     esp = ESP;
   1989 
   1990     if (data64) {
   1991         /* 64 bit */
   1992         esp -= 8;
   1993         while (--level) {
   1994             esp -= 8;
   1995             ebp -= 8;
   1996             stq(esp, ldq(ebp));
   1997         }
   1998         esp -= 8;
   1999         stq(esp, t1);
   2000     } else {
   2001         /* 16 bit */
   2002         esp -= 2;
   2003         while (--level) {
   2004             esp -= 2;
   2005             ebp -= 2;
   2006             stw(esp, lduw(ebp));
   2007         }
   2008         esp -= 2;
   2009         stw(esp, t1);
   2010     }
   2011 }
   2012 #endif
   2013 
   2014 void helper_lldt(int selector)
   2015 {
   2016     SegmentCache *dt;
   2017     uint32_t e1, e2;
   2018     int index, entry_limit;
   2019     target_ulong ptr;
   2020 
   2021     selector &= 0xffff;
   2022     if ((selector & 0xfffc) == 0) {
   2023         /* XXX: NULL selector case: invalid LDT */
   2024         env->ldt.base = 0;
   2025         env->ldt.limit = 0;
   2026     } else {
   2027         if (selector & 0x4)
   2028             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2029         dt = &env->gdt;
   2030         index = selector & ~7;
   2031 #ifdef TARGET_X86_64
   2032         if (env->hflags & HF_LMA_MASK)
   2033             entry_limit = 15;
   2034         else
   2035 #endif
   2036             entry_limit = 7;
   2037         if ((index + entry_limit) > dt->limit)
   2038             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2039         ptr = dt->base + index;
   2040         e1 = ldl_kernel(ptr);
   2041         e2 = ldl_kernel(ptr + 4);
   2042         if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2)
   2043             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2044         if (!(e2 & DESC_P_MASK))
   2045             raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
   2046 #ifdef TARGET_X86_64
   2047         if (env->hflags & HF_LMA_MASK) {
   2048             uint32_t e3;
   2049             e3 = ldl_kernel(ptr + 8);
   2050             load_seg_cache_raw_dt(&env->ldt, e1, e2);
   2051             env->ldt.base |= (target_ulong)e3 << 32;
   2052         } else
   2053 #endif
   2054         {
   2055             load_seg_cache_raw_dt(&env->ldt, e1, e2);
   2056         }
   2057     }
   2058     env->ldt.selector = selector;
   2059 }
   2060 
   2061 void helper_ltr(int selector)
   2062 {
   2063     SegmentCache *dt;
   2064     uint32_t e1, e2;
   2065     int index, type, entry_limit;
   2066     target_ulong ptr;
   2067 
   2068     selector &= 0xffff;
   2069     if ((selector & 0xfffc) == 0) {
   2070         /* NULL selector case: invalid TR */
   2071         env->tr.base = 0;
   2072         env->tr.limit = 0;
   2073         env->tr.flags = 0;
   2074     } else {
   2075         if (selector & 0x4)
   2076             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2077         dt = &env->gdt;
   2078         index = selector & ~7;
   2079 #ifdef TARGET_X86_64
   2080         if (env->hflags & HF_LMA_MASK)
   2081             entry_limit = 15;
   2082         else
   2083 #endif
   2084             entry_limit = 7;
   2085         if ((index + entry_limit) > dt->limit)
   2086             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2087         ptr = dt->base + index;
   2088         e1 = ldl_kernel(ptr);
   2089         e2 = ldl_kernel(ptr + 4);
   2090         type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
   2091         if ((e2 & DESC_S_MASK) ||
   2092             (type != 1 && type != 9))
   2093             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2094         if (!(e2 & DESC_P_MASK))
   2095             raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
   2096 #ifdef TARGET_X86_64
   2097         if (env->hflags & HF_LMA_MASK) {
   2098             uint32_t e3, e4;
   2099             e3 = ldl_kernel(ptr + 8);
   2100             e4 = ldl_kernel(ptr + 12);
   2101             if ((e4 >> DESC_TYPE_SHIFT) & 0xf)
   2102                 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2103             load_seg_cache_raw_dt(&env->tr, e1, e2);
   2104             env->tr.base |= (target_ulong)e3 << 32;
   2105         } else
   2106 #endif
   2107         {
   2108             load_seg_cache_raw_dt(&env->tr, e1, e2);
   2109         }
   2110         e2 |= DESC_TSS_BUSY_MASK;
   2111         stl_kernel(ptr + 4, e2);
   2112     }
   2113     env->tr.selector = selector;
   2114 }
   2115 
   2116 /* only works if protected mode and not VM86. seg_reg must be != R_CS */
   2117 void helper_load_seg(int seg_reg, int selector)
   2118 {
   2119     uint32_t e1, e2;
   2120     int cpl, dpl, rpl;
   2121     SegmentCache *dt;
   2122     int index;
   2123     target_ulong ptr;
   2124 
   2125     selector &= 0xffff;
   2126     cpl = env->hflags & HF_CPL_MASK;
   2127     if ((selector & 0xfffc) == 0) {
   2128         /* null selector case */
   2129         if (seg_reg == R_SS
   2130 #ifdef TARGET_X86_64
   2131             && (!(env->hflags & HF_CS64_MASK) || cpl == 3)
   2132 #endif
   2133             )
   2134             raise_exception_err(EXCP0D_GPF, 0);
   2135         cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
   2136     } else {
   2137 
   2138         if (selector & 0x4)
   2139             dt = &env->ldt;
   2140         else
   2141             dt = &env->gdt;
   2142         index = selector & ~7;
   2143         if ((index + 7) > dt->limit)
   2144             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2145         ptr = dt->base + index;
   2146         e1 = ldl_kernel(ptr);
   2147         e2 = ldl_kernel(ptr + 4);
   2148 
   2149         if (!(e2 & DESC_S_MASK))
   2150             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2151         rpl = selector & 3;
   2152         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2153         if (seg_reg == R_SS) {
   2154             /* must be writable segment */
   2155             if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK))
   2156                 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2157             if (rpl != cpl || dpl != cpl)
   2158                 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2159         } else {
   2160             /* must be readable segment */
   2161             if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK)
   2162                 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2163 
   2164             if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
   2165                 /* if not conforming code, test rights */
   2166                 if (dpl < cpl || dpl < rpl)
   2167                     raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2168             }
   2169         }
   2170 
   2171         if (!(e2 & DESC_P_MASK)) {
   2172             if (seg_reg == R_SS)
   2173                 raise_exception_err(EXCP0C_STACK, selector & 0xfffc);
   2174             else
   2175                 raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
   2176         }
   2177 
   2178         /* set the access bit if not already set */
   2179         if (!(e2 & DESC_A_MASK)) {
   2180             e2 |= DESC_A_MASK;
   2181             stl_kernel(ptr + 4, e2);
   2182         }
   2183 
   2184         cpu_x86_load_seg_cache(env, seg_reg, selector,
   2185                        get_seg_base(e1, e2),
   2186                        get_seg_limit(e1, e2),
   2187                        e2);
   2188 #if 0
   2189         qemu_log("load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n",
   2190                 selector, (unsigned long)sc->base, sc->limit, sc->flags);
   2191 #endif
   2192     }
   2193 }
   2194 
   2195 /* protected mode jump */
   2196 void helper_ljmp_protected(int new_cs, target_ulong new_eip,
   2197                            int next_eip_addend)
   2198 {
   2199     int gate_cs, type;
   2200     uint32_t e1, e2, cpl, dpl, rpl, limit;
   2201     target_ulong next_eip;
   2202 
   2203     if ((new_cs & 0xfffc) == 0)
   2204         raise_exception_err(EXCP0D_GPF, 0);
   2205     if (load_segment(&e1, &e2, new_cs) != 0)
   2206         raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2207     cpl = env->hflags & HF_CPL_MASK;
   2208     if (e2 & DESC_S_MASK) {
   2209         if (!(e2 & DESC_CS_MASK))
   2210             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2211         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2212         if (e2 & DESC_C_MASK) {
   2213             /* conforming code segment */
   2214             if (dpl > cpl)
   2215                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2216         } else {
   2217             /* non conforming code segment */
   2218             rpl = new_cs & 3;
   2219             if (rpl > cpl)
   2220                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2221             if (dpl != cpl)
   2222                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2223         }
   2224         if (!(e2 & DESC_P_MASK))
   2225             raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
   2226         limit = get_seg_limit(e1, e2);
   2227         if (new_eip > limit &&
   2228             !(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK))
   2229             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2230         cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
   2231                        get_seg_base(e1, e2), limit, e2);
   2232         EIP = new_eip;
   2233     } else {
   2234         /* jump to call or task gate */
   2235         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2236         rpl = new_cs & 3;
   2237         cpl = env->hflags & HF_CPL_MASK;
   2238         type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
   2239         switch(type) {
   2240         case 1: /* 286 TSS */
   2241         case 9: /* 386 TSS */
   2242         case 5: /* task gate */
   2243             if (dpl < cpl || dpl < rpl)
   2244                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2245             next_eip = env->eip + next_eip_addend;
   2246             switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
   2247             CC_OP = CC_OP_EFLAGS;
   2248             break;
   2249         case 4: /* 286 call gate */
   2250         case 12: /* 386 call gate */
   2251             if ((dpl < cpl) || (dpl < rpl))
   2252                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2253             if (!(e2 & DESC_P_MASK))
   2254                 raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
   2255             gate_cs = e1 >> 16;
   2256             new_eip = (e1 & 0xffff);
   2257             if (type == 12)
   2258                 new_eip |= (e2 & 0xffff0000);
   2259             if (load_segment(&e1, &e2, gate_cs) != 0)
   2260                 raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
   2261             dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2262             /* must be code segment */
   2263             if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) !=
   2264                  (DESC_S_MASK | DESC_CS_MASK)))
   2265                 raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
   2266             if (((e2 & DESC_C_MASK) && (dpl > cpl)) ||
   2267                 (!(e2 & DESC_C_MASK) && (dpl != cpl)))
   2268                 raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
   2269             if (!(e2 & DESC_P_MASK))
   2270                 raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
   2271             limit = get_seg_limit(e1, e2);
   2272             if (new_eip > limit)
   2273                 raise_exception_err(EXCP0D_GPF, 0);
   2274             cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl,
   2275                                    get_seg_base(e1, e2), limit, e2);
   2276             EIP = new_eip;
   2277             break;
   2278         default:
   2279             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2280             break;
   2281         }
   2282     }
   2283 }
   2284 
   2285 /* real mode call */
   2286 void helper_lcall_real(int new_cs, target_ulong new_eip1,
   2287                        int shift, int next_eip)
   2288 {
   2289     int new_eip;
   2290     uint32_t esp, esp_mask;
   2291     target_ulong ssp;
   2292 
   2293     new_eip = new_eip1;
   2294     esp = ESP;
   2295     esp_mask = get_sp_mask(env->segs[R_SS].flags);
   2296     ssp = env->segs[R_SS].base;
   2297     if (shift) {
   2298         PUSHL(ssp, esp, esp_mask, env->segs[R_CS].selector);
   2299         PUSHL(ssp, esp, esp_mask, next_eip);
   2300     } else {
   2301         PUSHW(ssp, esp, esp_mask, env->segs[R_CS].selector);
   2302         PUSHW(ssp, esp, esp_mask, next_eip);
   2303     }
   2304 
   2305     SET_ESP(esp, esp_mask);
   2306     env->eip = new_eip;
   2307     env->segs[R_CS].selector = new_cs;
   2308     env->segs[R_CS].base = (new_cs << 4);
   2309 }
   2310 
   2311 /* protected mode call */
   2312 void helper_lcall_protected(int new_cs, target_ulong new_eip,
   2313                             int shift, int next_eip_addend)
   2314 {
   2315     int new_stack, i;
   2316     uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;
   2317     uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, sp, type, ss_dpl, sp_mask;
   2318     uint32_t val, limit, old_sp_mask;
   2319     target_ulong ssp, old_ssp, next_eip;
   2320 
   2321     next_eip = env->eip + next_eip_addend;
   2322     LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift);
   2323     LOG_PCALL_STATE(env);
   2324     if ((new_cs & 0xfffc) == 0)
   2325         raise_exception_err(EXCP0D_GPF, 0);
   2326     if (load_segment(&e1, &e2, new_cs) != 0)
   2327         raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2328     cpl = env->hflags & HF_CPL_MASK;
   2329     LOG_PCALL("desc=%08x:%08x\n", e1, e2);
   2330     if (e2 & DESC_S_MASK) {
   2331         if (!(e2 & DESC_CS_MASK))
   2332             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2333         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2334         if (e2 & DESC_C_MASK) {
   2335             /* conforming code segment */
   2336             if (dpl > cpl)
   2337                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2338         } else {
   2339             /* non conforming code segment */
   2340             rpl = new_cs & 3;
   2341             if (rpl > cpl)
   2342                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2343             if (dpl != cpl)
   2344                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2345         }
   2346         if (!(e2 & DESC_P_MASK))
   2347             raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
   2348 
   2349 #ifdef TARGET_X86_64
   2350         /* XXX: check 16/32 bit cases in long mode */
   2351         if (shift == 2) {
   2352             target_ulong rsp;
   2353             /* 64 bit case */
   2354             rsp = ESP;
   2355             PUSHQ(rsp, env->segs[R_CS].selector);
   2356             PUSHQ(rsp, next_eip);
   2357             /* from this point, not restartable */
   2358             ESP = rsp;
   2359             cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
   2360                                    get_seg_base(e1, e2),
   2361                                    get_seg_limit(e1, e2), e2);
   2362             EIP = new_eip;
   2363         } else
   2364 #endif
   2365         {
   2366             sp = ESP;
   2367             sp_mask = get_sp_mask(env->segs[R_SS].flags);
   2368             ssp = env->segs[R_SS].base;
   2369             if (shift) {
   2370                 PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);
   2371                 PUSHL(ssp, sp, sp_mask, next_eip);
   2372             } else {
   2373                 PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);
   2374                 PUSHW(ssp, sp, sp_mask, next_eip);
   2375             }
   2376 
   2377             limit = get_seg_limit(e1, e2);
   2378             if (new_eip > limit)
   2379                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2380             /* from this point, not restartable */
   2381             SET_ESP(sp, sp_mask);
   2382             cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
   2383                                    get_seg_base(e1, e2), limit, e2);
   2384             EIP = new_eip;
   2385         }
   2386     } else {
   2387         /* check gate type */
   2388         type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
   2389         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2390         rpl = new_cs & 3;
   2391         switch(type) {
   2392         case 1: /* available 286 TSS */
   2393         case 9: /* available 386 TSS */
   2394         case 5: /* task gate */
   2395             if (dpl < cpl || dpl < rpl)
   2396                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2397             switch_tss(new_cs, e1, e2, SWITCH_TSS_CALL, next_eip);
   2398             CC_OP = CC_OP_EFLAGS;
   2399             return;
   2400         case 4: /* 286 call gate */
   2401         case 12: /* 386 call gate */
   2402             break;
   2403         default:
   2404             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2405             break;
   2406         }
   2407         shift = type >> 3;
   2408 
   2409         if (dpl < cpl || dpl < rpl)
   2410             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2411         /* check valid bit */
   2412         if (!(e2 & DESC_P_MASK))
   2413             raise_exception_err(EXCP0B_NOSEG,  new_cs & 0xfffc);
   2414         selector = e1 >> 16;
   2415         offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
   2416         param_count = e2 & 0x1f;
   2417         if ((selector & 0xfffc) == 0)
   2418             raise_exception_err(EXCP0D_GPF, 0);
   2419 
   2420         if (load_segment(&e1, &e2, selector) != 0)
   2421             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2422         if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
   2423             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2424         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2425         if (dpl > cpl)
   2426             raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
   2427         if (!(e2 & DESC_P_MASK))
   2428             raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
   2429 
   2430         if (!(e2 & DESC_C_MASK) && dpl < cpl) {
   2431             /* to inner privilege */
   2432             get_ss_esp_from_tss(&ss, &sp, dpl);
   2433             LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n",
   2434                         ss, sp, param_count, ESP);
   2435             if ((ss & 0xfffc) == 0)
   2436                 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
   2437             if ((ss & 3) != dpl)
   2438                 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
   2439             if (load_segment(&ss_e1, &ss_e2, ss) != 0)
   2440                 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
   2441             ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
   2442             if (ss_dpl != dpl)
   2443                 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
   2444             if (!(ss_e2 & DESC_S_MASK) ||
   2445                 (ss_e2 & DESC_CS_MASK) ||
   2446                 !(ss_e2 & DESC_W_MASK))
   2447                 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
   2448             if (!(ss_e2 & DESC_P_MASK))
   2449                 raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
   2450 
   2451             //            push_size = ((param_count * 2) + 8) << shift;
   2452 
   2453             old_sp_mask = get_sp_mask(env->segs[R_SS].flags);
   2454             old_ssp = env->segs[R_SS].base;
   2455 
   2456             sp_mask = get_sp_mask(ss_e2);
   2457             ssp = get_seg_base(ss_e1, ss_e2);
   2458             if (shift) {
   2459                 PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);
   2460                 PUSHL(ssp, sp, sp_mask, ESP);
   2461                 for(i = param_count - 1; i >= 0; i--) {
   2462                     val = ldl_kernel(old_ssp + ((ESP + i * 4) & old_sp_mask));
   2463                     PUSHL(ssp, sp, sp_mask, val);
   2464                 }
   2465             } else {
   2466                 PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);
   2467                 PUSHW(ssp, sp, sp_mask, ESP);
   2468                 for(i = param_count - 1; i >= 0; i--) {
   2469                     val = lduw_kernel(old_ssp + ((ESP + i * 2) & old_sp_mask));
   2470                     PUSHW(ssp, sp, sp_mask, val);
   2471                 }
   2472             }
   2473             new_stack = 1;
   2474         } else {
   2475             /* to same privilege */
   2476             sp = ESP;
   2477             sp_mask = get_sp_mask(env->segs[R_SS].flags);
   2478             ssp = env->segs[R_SS].base;
   2479             //            push_size = (4 << shift);
   2480             new_stack = 0;
   2481         }
   2482 
   2483         if (shift) {
   2484             PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);
   2485             PUSHL(ssp, sp, sp_mask, next_eip);
   2486         } else {
   2487             PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);
   2488             PUSHW(ssp, sp, sp_mask, next_eip);
   2489         }
   2490 
   2491         /* from this point, not restartable */
   2492 
   2493         if (new_stack) {
   2494             ss = (ss & ~3) | dpl;
   2495             cpu_x86_load_seg_cache(env, R_SS, ss,
   2496                                    ssp,
   2497                                    get_seg_limit(ss_e1, ss_e2),
   2498                                    ss_e2);
   2499         }
   2500 
   2501         selector = (selector & ~3) | dpl;
   2502         cpu_x86_load_seg_cache(env, R_CS, selector,
   2503                        get_seg_base(e1, e2),
   2504                        get_seg_limit(e1, e2),
   2505                        e2);
   2506         cpu_x86_set_cpl(env, dpl);
   2507         SET_ESP(sp, sp_mask);
   2508         EIP = offset;
   2509     }
   2510 #ifdef CONFIG_KQEMU
   2511     if (kqemu_is_ok(env)) {
   2512         env->exception_index = -1;
   2513         cpu_loop_exit();
   2514     }
   2515 #endif
   2516 }
   2517 
   2518 /* real and vm86 mode iret */
   2519 void helper_iret_real(int shift)
   2520 {
   2521     uint32_t sp, new_cs, new_eip, new_eflags, sp_mask;
   2522     target_ulong ssp;
   2523     int eflags_mask;
   2524 
   2525     sp_mask = 0xffff; /* XXXX: use SS segment size ? */
   2526     sp = ESP;
   2527     ssp = env->segs[R_SS].base;
   2528     if (shift == 1) {
   2529         /* 32 bits */
   2530         POPL(ssp, sp, sp_mask, new_eip);
   2531         POPL(ssp, sp, sp_mask, new_cs);
   2532         new_cs &= 0xffff;
   2533         POPL(ssp, sp, sp_mask, new_eflags);
   2534     } else {
   2535         /* 16 bits */
   2536         POPW(ssp, sp, sp_mask, new_eip);
   2537         POPW(ssp, sp, sp_mask, new_cs);
   2538         POPW(ssp, sp, sp_mask, new_eflags);
   2539     }
   2540     ESP = (ESP & ~sp_mask) | (sp & sp_mask);
   2541     env->segs[R_CS].selector = new_cs;
   2542     env->segs[R_CS].base = (new_cs << 4);
   2543     env->eip = new_eip;
   2544     if (env->eflags & VM_MASK)
   2545         eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | NT_MASK;
   2546     else
   2547         eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | RF_MASK | NT_MASK;
   2548     if (shift == 0)
   2549         eflags_mask &= 0xffff;
   2550     load_eflags(new_eflags, eflags_mask);
   2551     env->hflags2 &= ~HF2_NMI_MASK;
   2552 }
   2553 
   2554 static inline void validate_seg(int seg_reg, int cpl)
   2555 {
   2556     int dpl;
   2557     uint32_t e2;
   2558 
   2559     /* XXX: on x86_64, we do not want to nullify FS and GS because
   2560        they may still contain a valid base. I would be interested to
   2561        know how a real x86_64 CPU behaves */
   2562     if ((seg_reg == R_FS || seg_reg == R_GS) &&
   2563         (env->segs[seg_reg].selector & 0xfffc) == 0)
   2564         return;
   2565 
   2566     e2 = env->segs[seg_reg].flags;
   2567     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2568     if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
   2569         /* data or non conforming code segment */
   2570         if (dpl < cpl) {
   2571             cpu_x86_load_seg_cache(env, seg_reg, 0, 0, 0, 0);
   2572         }
   2573     }
   2574 }
   2575 
   2576 /* protected mode iret */
   2577 static inline void helper_ret_protected(int shift, int is_iret, int addend)
   2578 {
   2579     uint32_t new_cs, new_eflags, new_ss;
   2580     uint32_t new_es, new_ds, new_fs, new_gs;
   2581     uint32_t e1, e2, ss_e1, ss_e2;
   2582     int cpl, dpl, rpl, eflags_mask, iopl;
   2583     target_ulong ssp, sp, new_eip, new_esp, sp_mask;
   2584 
   2585 #ifdef TARGET_X86_64
   2586     if (shift == 2)
   2587         sp_mask = -1;
   2588     else
   2589 #endif
   2590         sp_mask = get_sp_mask(env->segs[R_SS].flags);
   2591     sp = ESP;
   2592     ssp = env->segs[R_SS].base;
   2593     new_eflags = 0; /* avoid warning */
   2594 #ifdef TARGET_X86_64
   2595     if (shift == 2) {
   2596         POPQ(sp, new_eip);
   2597         POPQ(sp, new_cs);
   2598         new_cs &= 0xffff;
   2599         if (is_iret) {
   2600             POPQ(sp, new_eflags);
   2601         }
   2602     } else
   2603 #endif
   2604     if (shift == 1) {
   2605         /* 32 bits */
   2606         POPL(ssp, sp, sp_mask, new_eip);
   2607         POPL(ssp, sp, sp_mask, new_cs);
   2608         new_cs &= 0xffff;
   2609         if (is_iret) {
   2610             POPL(ssp, sp, sp_mask, new_eflags);
   2611             if (new_eflags & VM_MASK)
   2612                 goto return_to_vm86;
   2613         }
   2614     } else {
   2615         /* 16 bits */
   2616         POPW(ssp, sp, sp_mask, new_eip);
   2617         POPW(ssp, sp, sp_mask, new_cs);
   2618         if (is_iret)
   2619             POPW(ssp, sp, sp_mask, new_eflags);
   2620     }
   2621     LOG_PCALL("lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n",
   2622               new_cs, new_eip, shift, addend);
   2623     LOG_PCALL_STATE(env);
   2624     if ((new_cs & 0xfffc) == 0)
   2625         raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2626     if (load_segment(&e1, &e2, new_cs) != 0)
   2627         raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2628     if (!(e2 & DESC_S_MASK) ||
   2629         !(e2 & DESC_CS_MASK))
   2630         raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2631     cpl = env->hflags & HF_CPL_MASK;
   2632     rpl = new_cs & 3;
   2633     if (rpl < cpl)
   2634         raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2635     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   2636     if (e2 & DESC_C_MASK) {
   2637         if (dpl > rpl)
   2638             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2639     } else {
   2640         if (dpl != rpl)
   2641             raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
   2642     }
   2643     if (!(e2 & DESC_P_MASK))
   2644         raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
   2645 
   2646     sp += addend;
   2647     if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) ||
   2648                        ((env->hflags & HF_CS64_MASK) && !is_iret))) {
   2649         /* return to same privilege level */
   2650         cpu_x86_load_seg_cache(env, R_CS, new_cs,
   2651                        get_seg_base(e1, e2),
   2652                        get_seg_limit(e1, e2),
   2653                        e2);
   2654     } else {
   2655         /* return to different privilege level */
   2656 #ifdef TARGET_X86_64
   2657         if (shift == 2) {
   2658             POPQ(sp, new_esp);
   2659             POPQ(sp, new_ss);
   2660             new_ss &= 0xffff;
   2661         } else
   2662 #endif
   2663         if (shift == 1) {
   2664             /* 32 bits */
   2665             POPL(ssp, sp, sp_mask, new_esp);
   2666             POPL(ssp, sp, sp_mask, new_ss);
   2667             new_ss &= 0xffff;
   2668         } else {
   2669             /* 16 bits */
   2670             POPW(ssp, sp, sp_mask, new_esp);
   2671             POPW(ssp, sp, sp_mask, new_ss);
   2672         }
   2673         LOG_PCALL("new ss:esp=%04x:" TARGET_FMT_lx "\n",
   2674                     new_ss, new_esp);
   2675         if ((new_ss & 0xfffc) == 0) {
   2676 #ifdef TARGET_X86_64
   2677             /* NULL ss is allowed in long mode if cpl != 3*/
   2678             /* XXX: test CS64 ? */
   2679             if ((env->hflags & HF_LMA_MASK) && rpl != 3) {
   2680                 cpu_x86_load_seg_cache(env, R_SS, new_ss,
   2681                                        0, 0xffffffff,
   2682                                        DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2683                                        DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
   2684                                        DESC_W_MASK | DESC_A_MASK);
   2685                 ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */
   2686             } else
   2687 #endif
   2688             {
   2689                 raise_exception_err(EXCP0D_GPF, 0);
   2690             }
   2691         } else {
   2692             if ((new_ss & 3) != rpl)
   2693                 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
   2694             if (load_segment(&ss_e1, &ss_e2, new_ss) != 0)
   2695                 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
   2696             if (!(ss_e2 & DESC_S_MASK) ||
   2697                 (ss_e2 & DESC_CS_MASK) ||
   2698                 !(ss_e2 & DESC_W_MASK))
   2699                 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
   2700             dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
   2701             if (dpl != rpl)
   2702                 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
   2703             if (!(ss_e2 & DESC_P_MASK))
   2704                 raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
   2705             cpu_x86_load_seg_cache(env, R_SS, new_ss,
   2706                                    get_seg_base(ss_e1, ss_e2),
   2707                                    get_seg_limit(ss_e1, ss_e2),
   2708                                    ss_e2);
   2709         }
   2710 
   2711         cpu_x86_load_seg_cache(env, R_CS, new_cs,
   2712                        get_seg_base(e1, e2),
   2713                        get_seg_limit(e1, e2),
   2714                        e2);
   2715         cpu_x86_set_cpl(env, rpl);
   2716         sp = new_esp;
   2717 #ifdef TARGET_X86_64
   2718         if (env->hflags & HF_CS64_MASK)
   2719             sp_mask = -1;
   2720         else
   2721 #endif
   2722             sp_mask = get_sp_mask(ss_e2);
   2723 
   2724         /* validate data segments */
   2725         validate_seg(R_ES, rpl);
   2726         validate_seg(R_DS, rpl);
   2727         validate_seg(R_FS, rpl);
   2728         validate_seg(R_GS, rpl);
   2729 
   2730         sp += addend;
   2731     }
   2732     SET_ESP(sp, sp_mask);
   2733     env->eip = new_eip;
   2734     if (is_iret) {
   2735         /* NOTE: 'cpl' is the _old_ CPL */
   2736         eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK;
   2737         if (cpl == 0)
   2738             eflags_mask |= IOPL_MASK;
   2739         iopl = (env->eflags >> IOPL_SHIFT) & 3;
   2740         if (cpl <= iopl)
   2741             eflags_mask |= IF_MASK;
   2742         if (shift == 0)
   2743             eflags_mask &= 0xffff;
   2744         load_eflags(new_eflags, eflags_mask);
   2745     }
   2746     return;
   2747 
   2748  return_to_vm86:
   2749     POPL(ssp, sp, sp_mask, new_esp);
   2750     POPL(ssp, sp, sp_mask, new_ss);
   2751     POPL(ssp, sp, sp_mask, new_es);
   2752     POPL(ssp, sp, sp_mask, new_ds);
   2753     POPL(ssp, sp, sp_mask, new_fs);
   2754     POPL(ssp, sp, sp_mask, new_gs);
   2755 
   2756     /* modify processor state */
   2757     load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK |
   2758                 IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK);
   2759     load_seg_vm(R_CS, new_cs & 0xffff);
   2760     cpu_x86_set_cpl(env, 3);
   2761     load_seg_vm(R_SS, new_ss & 0xffff);
   2762     load_seg_vm(R_ES, new_es & 0xffff);
   2763     load_seg_vm(R_DS, new_ds & 0xffff);
   2764     load_seg_vm(R_FS, new_fs & 0xffff);
   2765     load_seg_vm(R_GS, new_gs & 0xffff);
   2766 
   2767     env->eip = new_eip & 0xffff;
   2768     ESP = new_esp;
   2769 }
   2770 
   2771 void helper_iret_protected(int shift, int next_eip)
   2772 {
   2773     int tss_selector, type;
   2774     uint32_t e1, e2;
   2775 
   2776     /* specific case for TSS */
   2777     if (env->eflags & NT_MASK) {
   2778 #ifdef TARGET_X86_64
   2779         if (env->hflags & HF_LMA_MASK)
   2780             raise_exception_err(EXCP0D_GPF, 0);
   2781 #endif
   2782         tss_selector = lduw_kernel(env->tr.base + 0);
   2783         if (tss_selector & 4)
   2784             raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
   2785         if (load_segment(&e1, &e2, tss_selector) != 0)
   2786             raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
   2787         type = (e2 >> DESC_TYPE_SHIFT) & 0x17;
   2788         /* NOTE: we check both segment and busy TSS */
   2789         if (type != 3)
   2790             raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
   2791         switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
   2792     } else {
   2793         helper_ret_protected(shift, 1, 0);
   2794     }
   2795     env->hflags2 &= ~HF2_NMI_MASK;
   2796 #ifdef CONFIG_KQEMU
   2797     if (kqemu_is_ok(env)) {
   2798         CC_OP = CC_OP_EFLAGS;
   2799         env->exception_index = -1;
   2800         cpu_loop_exit();
   2801     }
   2802 #endif
   2803 }
   2804 
   2805 void helper_lret_protected(int shift, int addend)
   2806 {
   2807     helper_ret_protected(shift, 0, addend);
   2808 #ifdef CONFIG_KQEMU
   2809     if (kqemu_is_ok(env)) {
   2810         env->exception_index = -1;
   2811         cpu_loop_exit();
   2812     }
   2813 #endif
   2814 }
   2815 
   2816 void helper_sysenter(void)
   2817 {
   2818     if (env->sysenter_cs == 0) {
   2819         raise_exception_err(EXCP0D_GPF, 0);
   2820     }
   2821     env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK);
   2822     cpu_x86_set_cpl(env, 0);
   2823 
   2824 #ifdef TARGET_X86_64
   2825     if (env->hflags & HF_LMA_MASK) {
   2826         cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc,
   2827                                0, 0xffffffff,
   2828                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2829                                DESC_S_MASK |
   2830                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
   2831     } else
   2832 #endif
   2833     {
   2834         cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc,
   2835                                0, 0xffffffff,
   2836                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2837                                DESC_S_MASK |
   2838                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
   2839     }
   2840     cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc,
   2841                            0, 0xffffffff,
   2842                            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2843                            DESC_S_MASK |
   2844                            DESC_W_MASK | DESC_A_MASK);
   2845     ESP = env->sysenter_esp;
   2846     EIP = env->sysenter_eip;
   2847 }
   2848 
   2849 void helper_sysexit(int dflag)
   2850 {
   2851     int cpl;
   2852 
   2853     cpl = env->hflags & HF_CPL_MASK;
   2854     if (env->sysenter_cs == 0 || cpl != 0) {
   2855         raise_exception_err(EXCP0D_GPF, 0);
   2856     }
   2857     cpu_x86_set_cpl(env, 3);
   2858 #ifdef TARGET_X86_64
   2859     if (dflag == 2) {
   2860         cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 32) & 0xfffc) | 3,
   2861                                0, 0xffffffff,
   2862                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2863                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   2864                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
   2865         cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 40) & 0xfffc) | 3,
   2866                                0, 0xffffffff,
   2867                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2868                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   2869                                DESC_W_MASK | DESC_A_MASK);
   2870     } else
   2871 #endif
   2872     {
   2873         cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3,
   2874                                0, 0xffffffff,
   2875                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2876                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   2877                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
   2878         cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3,
   2879                                0, 0xffffffff,
   2880                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
   2881                                DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
   2882                                DESC_W_MASK | DESC_A_MASK);
   2883     }
   2884     ESP = ECX;
   2885     EIP = EDX;
   2886 #ifdef CONFIG_KQEMU
   2887     if (kqemu_is_ok(env)) {
   2888         env->exception_index = -1;
   2889         cpu_loop_exit();
   2890     }
   2891 #endif
   2892 }
   2893 
   2894 #if defined(CONFIG_USER_ONLY)
   2895 target_ulong helper_read_crN(int reg)
   2896 {
   2897     return 0;
   2898 }
   2899 
   2900 void helper_write_crN(int reg, target_ulong t0)
   2901 {
   2902 }
   2903 
   2904 void helper_movl_drN_T0(int reg, target_ulong t0)
   2905 {
   2906 }
   2907 #else
   2908 target_ulong helper_read_crN(int reg)
   2909 {
   2910     target_ulong val;
   2911 
   2912     helper_svm_check_intercept_param(SVM_EXIT_READ_CR0 + reg, 0);
   2913     switch(reg) {
   2914     default:
   2915         val = env->cr[reg];
   2916         break;
   2917     case 8:
   2918         if (!(env->hflags2 & HF2_VINTR_MASK)) {
   2919             val = cpu_get_apic_tpr(env);
   2920         } else {
   2921             val = env->v_tpr;
   2922         }
   2923         break;
   2924     }
   2925     return val;
   2926 }
   2927 
   2928 void helper_write_crN(int reg, target_ulong t0)
   2929 {
   2930     helper_svm_check_intercept_param(SVM_EXIT_WRITE_CR0 + reg, 0);
   2931     switch(reg) {
   2932     case 0:
   2933         cpu_x86_update_cr0(env, t0);
   2934         break;
   2935     case 3:
   2936         cpu_x86_update_cr3(env, t0);
   2937         break;
   2938     case 4:
   2939         cpu_x86_update_cr4(env, t0);
   2940         break;
   2941     case 8:
   2942         if (!(env->hflags2 & HF2_VINTR_MASK)) {
   2943             cpu_set_apic_tpr(env, t0);
   2944         }
   2945         env->v_tpr = t0 & 0x0f;
   2946         break;
   2947     default:
   2948         env->cr[reg] = t0;
   2949         break;
   2950     }
   2951 }
   2952 
   2953 void helper_movl_drN_T0(int reg, target_ulong t0)
   2954 {
   2955     int i;
   2956 
   2957     if (reg < 4) {
   2958         hw_breakpoint_remove(env, reg);
   2959         env->dr[reg] = t0;
   2960         hw_breakpoint_insert(env, reg);
   2961     } else if (reg == 7) {
   2962         for (i = 0; i < 4; i++)
   2963             hw_breakpoint_remove(env, i);
   2964         env->dr[7] = t0;
   2965         for (i = 0; i < 4; i++)
   2966             hw_breakpoint_insert(env, i);
   2967     } else
   2968         env->dr[reg] = t0;
   2969 }
   2970 #endif
   2971 
   2972 void helper_lmsw(target_ulong t0)
   2973 {
   2974     /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
   2975        if already set to one. */
   2976     t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
   2977     helper_write_crN(0, t0);
   2978 }
   2979 
   2980 void helper_clts(void)
   2981 {
   2982     env->cr[0] &= ~CR0_TS_MASK;
   2983     env->hflags &= ~HF_TS_MASK;
   2984 }
   2985 
   2986 void helper_invlpg(target_ulong addr)
   2987 {
   2988     helper_svm_check_intercept_param(SVM_EXIT_INVLPG, 0);
   2989     tlb_flush_page(env, addr);
   2990 }
   2991 
   2992 void helper_rdtsc(void)
   2993 {
   2994     uint64_t val;
   2995 
   2996     if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
   2997         raise_exception(EXCP0D_GPF);
   2998     }
   2999     helper_svm_check_intercept_param(SVM_EXIT_RDTSC, 0);
   3000 
   3001     val = cpu_get_tsc(env) + env->tsc_offset;
   3002     EAX = (uint32_t)(val);
   3003     EDX = (uint32_t)(val >> 32);
   3004 }
   3005 
   3006 void helper_rdpmc(void)
   3007 {
   3008     if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
   3009         raise_exception(EXCP0D_GPF);
   3010     }
   3011     helper_svm_check_intercept_param(SVM_EXIT_RDPMC, 0);
   3012 
   3013     /* currently unimplemented */
   3014     raise_exception_err(EXCP06_ILLOP, 0);
   3015 }
   3016 
   3017 #if defined(CONFIG_USER_ONLY)
   3018 void helper_wrmsr(void)
   3019 {
   3020 }
   3021 
   3022 void helper_rdmsr(void)
   3023 {
   3024 }
   3025 #else
   3026 void helper_wrmsr(void)
   3027 {
   3028     uint64_t val;
   3029 
   3030     helper_svm_check_intercept_param(SVM_EXIT_MSR, 1);
   3031 
   3032     val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
   3033 
   3034     switch((uint32_t)ECX) {
   3035     case MSR_IA32_SYSENTER_CS:
   3036         env->sysenter_cs = val & 0xffff;
   3037         break;
   3038     case MSR_IA32_SYSENTER_ESP:
   3039         env->sysenter_esp = val;
   3040         break;
   3041     case MSR_IA32_SYSENTER_EIP:
   3042         env->sysenter_eip = val;
   3043         break;
   3044     case MSR_IA32_APICBASE:
   3045         cpu_set_apic_base(env, val);
   3046         break;
   3047     case MSR_EFER:
   3048         {
   3049             uint64_t update_mask;
   3050             update_mask = 0;
   3051             if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL)
   3052                 update_mask |= MSR_EFER_SCE;
   3053             if (env->cpuid_ext2_features & CPUID_EXT2_LM)
   3054                 update_mask |= MSR_EFER_LME;
   3055             if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR)
   3056                 update_mask |= MSR_EFER_FFXSR;
   3057             if (env->cpuid_ext2_features & CPUID_EXT2_NX)
   3058                 update_mask |= MSR_EFER_NXE;
   3059             if (env->cpuid_ext3_features & CPUID_EXT3_SVM)
   3060                 update_mask |= MSR_EFER_SVME;
   3061             if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR)
   3062                 update_mask |= MSR_EFER_FFXSR;
   3063             cpu_load_efer(env, (env->efer & ~update_mask) |
   3064                           (val & update_mask));
   3065         }
   3066         break;
   3067     case MSR_STAR:
   3068         env->star = val;
   3069         break;
   3070     case MSR_PAT:
   3071         env->pat = val;
   3072         break;
   3073     case MSR_VM_HSAVE_PA:
   3074         env->vm_hsave = val;
   3075         break;
   3076 #ifdef TARGET_X86_64
   3077     case MSR_LSTAR:
   3078         env->lstar = val;
   3079         break;
   3080     case MSR_CSTAR:
   3081         env->cstar = val;
   3082         break;
   3083     case MSR_FMASK:
   3084         env->fmask = val;
   3085         break;
   3086     case MSR_FSBASE:
   3087         env->segs[R_FS].base = val;
   3088         break;
   3089     case MSR_GSBASE:
   3090         env->segs[R_GS].base = val;
   3091         break;
   3092     case MSR_KERNELGSBASE:
   3093         env->kernelgsbase = val;
   3094         break;
   3095 #endif
   3096     case MSR_MTRRphysBase(0):
   3097     case MSR_MTRRphysBase(1):
   3098     case MSR_MTRRphysBase(2):
   3099     case MSR_MTRRphysBase(3):
   3100     case MSR_MTRRphysBase(4):
   3101     case MSR_MTRRphysBase(5):
   3102     case MSR_MTRRphysBase(6):
   3103     case MSR_MTRRphysBase(7):
   3104         env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base = val;
   3105         break;
   3106     case MSR_MTRRphysMask(0):
   3107     case MSR_MTRRphysMask(1):
   3108     case MSR_MTRRphysMask(2):
   3109     case MSR_MTRRphysMask(3):
   3110     case MSR_MTRRphysMask(4):
   3111     case MSR_MTRRphysMask(5):
   3112     case MSR_MTRRphysMask(6):
   3113     case MSR_MTRRphysMask(7):
   3114         env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask = val;
   3115         break;
   3116     case MSR_MTRRfix64K_00000:
   3117         env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix64K_00000] = val;
   3118         break;
   3119     case MSR_MTRRfix16K_80000:
   3120     case MSR_MTRRfix16K_A0000:
   3121         env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1] = val;
   3122         break;
   3123     case MSR_MTRRfix4K_C0000:
   3124     case MSR_MTRRfix4K_C8000:
   3125     case MSR_MTRRfix4K_D0000:
   3126     case MSR_MTRRfix4K_D8000:
   3127     case MSR_MTRRfix4K_E0000:
   3128     case MSR_MTRRfix4K_E8000:
   3129     case MSR_MTRRfix4K_F0000:
   3130     case MSR_MTRRfix4K_F8000:
   3131         env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3] = val;
   3132         break;
   3133     case MSR_MTRRdefType:
   3134         env->mtrr_deftype = val;
   3135         break;
   3136     case MSR_MCG_STATUS:
   3137         env->mcg_status = val;
   3138         break;
   3139     case MSR_MCG_CTL:
   3140         if ((env->mcg_cap & MCG_CTL_P)
   3141             && (val == 0 || val == ~(uint64_t)0))
   3142             env->mcg_ctl = val;
   3143         break;
   3144     default:
   3145         if ((uint32_t)ECX >= MSR_MC0_CTL
   3146             && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
   3147             uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
   3148             if ((offset & 0x3) != 0
   3149                 || (val == 0 || val == ~(uint64_t)0))
   3150                 env->mce_banks[offset] = val;
   3151             break;
   3152         }
   3153         /* XXX: exception ? */
   3154         break;
   3155     }
   3156 }
   3157 
   3158 void helper_rdmsr(void)
   3159 {
   3160     uint64_t val;
   3161 
   3162     helper_svm_check_intercept_param(SVM_EXIT_MSR, 0);
   3163 
   3164     switch((uint32_t)ECX) {
   3165     case MSR_IA32_SYSENTER_CS:
   3166         val = env->sysenter_cs;
   3167         break;
   3168     case MSR_IA32_SYSENTER_ESP:
   3169         val = env->sysenter_esp;
   3170         break;
   3171     case MSR_IA32_SYSENTER_EIP:
   3172         val = env->sysenter_eip;
   3173         break;
   3174     case MSR_IA32_APICBASE:
   3175         val = cpu_get_apic_base(env);
   3176         break;
   3177     case MSR_EFER:
   3178         val = env->efer;
   3179         break;
   3180     case MSR_STAR:
   3181         val = env->star;
   3182         break;
   3183     case MSR_PAT:
   3184         val = env->pat;
   3185         break;
   3186     case MSR_VM_HSAVE_PA:
   3187         val = env->vm_hsave;
   3188         break;
   3189     case MSR_IA32_PERF_STATUS:
   3190         /* tsc_increment_by_tick */
   3191         val = 1000ULL;
   3192         /* CPU multiplier */
   3193         val |= (((uint64_t)4ULL) << 40);
   3194         break;
   3195 #ifdef TARGET_X86_64
   3196     case MSR_LSTAR:
   3197         val = env->lstar;
   3198         break;
   3199     case MSR_CSTAR:
   3200         val = env->cstar;
   3201         break;
   3202     case MSR_FMASK:
   3203         val = env->fmask;
   3204         break;
   3205     case MSR_FSBASE:
   3206         val = env->segs[R_FS].base;
   3207         break;
   3208     case MSR_GSBASE:
   3209         val = env->segs[R_GS].base;
   3210         break;
   3211     case MSR_KERNELGSBASE:
   3212         val = env->kernelgsbase;
   3213         break;
   3214 #endif
   3215 #ifdef CONFIG_KQEMU
   3216     case MSR_QPI_COMMBASE:
   3217         if (env->kqemu_enabled) {
   3218             val = kqemu_comm_base;
   3219         } else {
   3220             val = 0;
   3221         }
   3222         break;
   3223 #endif
   3224     case MSR_MTRRphysBase(0):
   3225     case MSR_MTRRphysBase(1):
   3226     case MSR_MTRRphysBase(2):
   3227     case MSR_MTRRphysBase(3):
   3228     case MSR_MTRRphysBase(4):
   3229     case MSR_MTRRphysBase(5):
   3230     case MSR_MTRRphysBase(6):
   3231     case MSR_MTRRphysBase(7):
   3232         val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base;
   3233         break;
   3234     case MSR_MTRRphysMask(0):
   3235     case MSR_MTRRphysMask(1):
   3236     case MSR_MTRRphysMask(2):
   3237     case MSR_MTRRphysMask(3):
   3238     case MSR_MTRRphysMask(4):
   3239     case MSR_MTRRphysMask(5):
   3240     case MSR_MTRRphysMask(6):
   3241     case MSR_MTRRphysMask(7):
   3242         val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask;
   3243         break;
   3244     case MSR_MTRRfix64K_00000:
   3245         val = env->mtrr_fixed[0];
   3246         break;
   3247     case MSR_MTRRfix16K_80000:
   3248     case MSR_MTRRfix16K_A0000:
   3249         val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1];
   3250         break;
   3251     case MSR_MTRRfix4K_C0000:
   3252     case MSR_MTRRfix4K_C8000:
   3253     case MSR_MTRRfix4K_D0000:
   3254     case MSR_MTRRfix4K_D8000:
   3255     case MSR_MTRRfix4K_E0000:
   3256     case MSR_MTRRfix4K_E8000:
   3257     case MSR_MTRRfix4K_F0000:
   3258     case MSR_MTRRfix4K_F8000:
   3259         val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3];
   3260         break;
   3261     case MSR_MTRRdefType:
   3262         val = env->mtrr_deftype;
   3263         break;
   3264     case MSR_MTRRcap:
   3265         if (env->cpuid_features & CPUID_MTRR)
   3266             val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | MSR_MTRRcap_WC_SUPPORTED;
   3267         else
   3268             /* XXX: exception ? */
   3269             val = 0;
   3270         break;
   3271     case MSR_MCG_CAP:
   3272         val = env->mcg_cap;
   3273         break;
   3274     case MSR_MCG_CTL:
   3275         if (env->mcg_cap & MCG_CTL_P)
   3276             val = env->mcg_ctl;
   3277         else
   3278             val = 0;
   3279         break;
   3280     case MSR_MCG_STATUS:
   3281         val = env->mcg_status;
   3282         break;
   3283     default:
   3284         if ((uint32_t)ECX >= MSR_MC0_CTL
   3285             && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
   3286             uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
   3287             val = env->mce_banks[offset];
   3288             break;
   3289         }
   3290         /* XXX: exception ? */
   3291         val = 0;
   3292         break;
   3293     }
   3294     EAX = (uint32_t)(val);
   3295     EDX = (uint32_t)(val >> 32);
   3296 }
   3297 #endif
   3298 
   3299 target_ulong helper_lsl(target_ulong selector1)
   3300 {
   3301     unsigned int limit;
   3302     uint32_t e1, e2, eflags, selector;
   3303     int rpl, dpl, cpl, type;
   3304 
   3305     selector = selector1 & 0xffff;
   3306     eflags = helper_cc_compute_all(CC_OP);
   3307     if ((selector & 0xfffc) == 0)
   3308         goto fail;
   3309     if (load_segment(&e1, &e2, selector) != 0)
   3310         goto fail;
   3311     rpl = selector & 3;
   3312     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   3313     cpl = env->hflags & HF_CPL_MASK;
   3314     if (e2 & DESC_S_MASK) {
   3315         if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
   3316             /* conforming */
   3317         } else {
   3318             if (dpl < cpl || dpl < rpl)
   3319                 goto fail;
   3320         }
   3321     } else {
   3322         type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
   3323         switch(type) {
   3324         case 1:
   3325         case 2:
   3326         case 3:
   3327         case 9:
   3328         case 11:
   3329             break;
   3330         default:
   3331             goto fail;
   3332         }
   3333         if (dpl < cpl || dpl < rpl) {
   3334         fail:
   3335             CC_SRC = eflags & ~CC_Z;
   3336             return 0;
   3337         }
   3338     }
   3339     limit = get_seg_limit(e1, e2);
   3340     CC_SRC = eflags | CC_Z;
   3341     return limit;
   3342 }
   3343 
   3344 target_ulong helper_lar(target_ulong selector1)
   3345 {
   3346     uint32_t e1, e2, eflags, selector;
   3347     int rpl, dpl, cpl, type;
   3348 
   3349     selector = selector1 & 0xffff;
   3350     eflags = helper_cc_compute_all(CC_OP);
   3351     if ((selector & 0xfffc) == 0)
   3352         goto fail;
   3353     if (load_segment(&e1, &e2, selector) != 0)
   3354         goto fail;
   3355     rpl = selector & 3;
   3356     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   3357     cpl = env->hflags & HF_CPL_MASK;
   3358     if (e2 & DESC_S_MASK) {
   3359         if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) {
   3360             /* conforming */
   3361         } else {
   3362             if (dpl < cpl || dpl < rpl)
   3363                 goto fail;
   3364         }
   3365     } else {
   3366         type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
   3367         switch(type) {
   3368         case 1:
   3369         case 2:
   3370         case 3:
   3371         case 4:
   3372         case 5:
   3373         case 9:
   3374         case 11:
   3375         case 12:
   3376             break;
   3377         default:
   3378             goto fail;
   3379         }
   3380         if (dpl < cpl || dpl < rpl) {
   3381         fail:
   3382             CC_SRC = eflags & ~CC_Z;
   3383             return 0;
   3384         }
   3385     }
   3386     CC_SRC = eflags | CC_Z;
   3387     return e2 & 0x00f0ff00;
   3388 }
   3389 
   3390 void helper_verr(target_ulong selector1)
   3391 {
   3392     uint32_t e1, e2, eflags, selector;
   3393     int rpl, dpl, cpl;
   3394 
   3395     selector = selector1 & 0xffff;
   3396     eflags = helper_cc_compute_all(CC_OP);
   3397     if ((selector & 0xfffc) == 0)
   3398         goto fail;
   3399     if (load_segment(&e1, &e2, selector) != 0)
   3400         goto fail;
   3401     if (!(e2 & DESC_S_MASK))
   3402         goto fail;
   3403     rpl = selector & 3;
   3404     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   3405     cpl = env->hflags & HF_CPL_MASK;
   3406     if (e2 & DESC_CS_MASK) {
   3407         if (!(e2 & DESC_R_MASK))
   3408             goto fail;
   3409         if (!(e2 & DESC_C_MASK)) {
   3410             if (dpl < cpl || dpl < rpl)
   3411                 goto fail;
   3412         }
   3413     } else {
   3414         if (dpl < cpl || dpl < rpl) {
   3415         fail:
   3416             CC_SRC = eflags & ~CC_Z;
   3417             return;
   3418         }
   3419     }
   3420     CC_SRC = eflags | CC_Z;
   3421 }
   3422 
   3423 void helper_verw(target_ulong selector1)
   3424 {
   3425     uint32_t e1, e2, eflags, selector;
   3426     int rpl, dpl, cpl;
   3427 
   3428     selector = selector1 & 0xffff;
   3429     eflags = helper_cc_compute_all(CC_OP);
   3430     if ((selector & 0xfffc) == 0)
   3431         goto fail;
   3432     if (load_segment(&e1, &e2, selector) != 0)
   3433         goto fail;
   3434     if (!(e2 & DESC_S_MASK))
   3435         goto fail;
   3436     rpl = selector & 3;
   3437     dpl = (e2 >> DESC_DPL_SHIFT) & 3;
   3438     cpl = env->hflags & HF_CPL_MASK;
   3439     if (e2 & DESC_CS_MASK) {
   3440         goto fail;
   3441     } else {
   3442         if (dpl < cpl || dpl < rpl)
   3443             goto fail;
   3444         if (!(e2 & DESC_W_MASK)) {
   3445         fail:
   3446             CC_SRC = eflags & ~CC_Z;
   3447             return;
   3448         }
   3449     }
   3450     CC_SRC = eflags | CC_Z;
   3451 }
   3452 
   3453 /* x87 FPU helpers */
   3454 
   3455 static void fpu_set_exception(int mask)
   3456 {
   3457     env->fpus |= mask;
   3458     if (env->fpus & (~env->fpuc & FPUC_EM))
   3459         env->fpus |= FPUS_SE | FPUS_B;
   3460 }
   3461 
   3462 static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
   3463 {
   3464     if (b == 0.0)
   3465         fpu_set_exception(FPUS_ZE);
   3466     return a / b;
   3467 }
   3468 
   3469 static void fpu_raise_exception(void)
   3470 {
   3471     if (env->cr[0] & CR0_NE_MASK) {
   3472         raise_exception(EXCP10_COPR);
   3473     }
   3474 #if !defined(CONFIG_USER_ONLY)
   3475     else {
   3476         cpu_set_ferr(env);
   3477     }
   3478 #endif
   3479 }
   3480 
   3481 void helper_flds_FT0(uint32_t val)
   3482 {
   3483     union {
   3484         float32 f;
   3485         uint32_t i;
   3486     } u;
   3487     u.i = val;
   3488     FT0 = float32_to_floatx(u.f, &env->fp_status);
   3489 }
   3490 
   3491 void helper_fldl_FT0(uint64_t val)
   3492 {
   3493     union {
   3494         float64 f;
   3495         uint64_t i;
   3496     } u;
   3497     u.i = val;
   3498     FT0 = float64_to_floatx(u.f, &env->fp_status);
   3499 }
   3500 
   3501 void helper_fildl_FT0(int32_t val)
   3502 {
   3503     FT0 = int32_to_floatx(val, &env->fp_status);
   3504 }
   3505 
   3506 void helper_flds_ST0(uint32_t val)
   3507 {
   3508     int new_fpstt;
   3509     union {
   3510         float32 f;
   3511         uint32_t i;
   3512     } u;
   3513     new_fpstt = (env->fpstt - 1) & 7;
   3514     u.i = val;
   3515     env->fpregs[new_fpstt].d = float32_to_floatx(u.f, &env->fp_status);
   3516     env->fpstt = new_fpstt;
   3517     env->fptags[new_fpstt] = 0; /* validate stack entry */
   3518 }
   3519 
   3520 void helper_fldl_ST0(uint64_t val)
   3521 {
   3522     int new_fpstt;
   3523     union {
   3524         float64 f;
   3525         uint64_t i;
   3526     } u;
   3527     new_fpstt = (env->fpstt - 1) & 7;
   3528     u.i = val;
   3529     env->fpregs[new_fpstt].d = float64_to_floatx(u.f, &env->fp_status);
   3530     env->fpstt = new_fpstt;
   3531     env->fptags[new_fpstt] = 0; /* validate stack entry */
   3532 }
   3533 
   3534 void helper_fildl_ST0(int32_t val)
   3535 {
   3536     int new_fpstt;
   3537     new_fpstt = (env->fpstt - 1) & 7;
   3538     env->fpregs[new_fpstt].d = int32_to_floatx(val, &env->fp_status);
   3539     env->fpstt = new_fpstt;
   3540     env->fptags[new_fpstt] = 0; /* validate stack entry */
   3541 }
   3542 
   3543 void helper_fildll_ST0(int64_t val)
   3544 {
   3545     int new_fpstt;
   3546     new_fpstt = (env->fpstt - 1) & 7;
   3547     env->fpregs[new_fpstt].d = int64_to_floatx(val, &env->fp_status);
   3548     env->fpstt = new_fpstt;
   3549     env->fptags[new_fpstt] = 0; /* validate stack entry */
   3550 }
   3551 
   3552 uint32_t helper_fsts_ST0(void)
   3553 {
   3554     union {
   3555         float32 f;
   3556         uint32_t i;
   3557     } u;
   3558     u.f = floatx_to_float32(ST0, &env->fp_status);
   3559     return u.i;
   3560 }
   3561 
   3562 uint64_t helper_fstl_ST0(void)
   3563 {
   3564     union {
   3565         float64 f;
   3566         uint64_t i;
   3567     } u;
   3568     u.f = floatx_to_float64(ST0, &env->fp_status);
   3569     return u.i;
   3570 }
   3571 
   3572 int32_t helper_fist_ST0(void)
   3573 {
   3574     int32_t val;
   3575     val = floatx_to_int32(ST0, &env->fp_status);
   3576     if (val != (int16_t)val)
   3577         val = -32768;
   3578     return val;
   3579 }
   3580 
   3581 int32_t helper_fistl_ST0(void)
   3582 {
   3583     int32_t val;
   3584     val = floatx_to_int32(ST0, &env->fp_status);
   3585     return val;
   3586 }
   3587 
   3588 int64_t helper_fistll_ST0(void)
   3589 {
   3590     int64_t val;
   3591     val = floatx_to_int64(ST0, &env->fp_status);
   3592     return val;
   3593 }
   3594 
   3595 int32_t helper_fistt_ST0(void)
   3596 {
   3597     int32_t val;
   3598     val = floatx_to_int32_round_to_zero(ST0, &env->fp_status);
   3599     if (val != (int16_t)val)
   3600         val = -32768;
   3601     return val;
   3602 }
   3603 
   3604 int32_t helper_fisttl_ST0(void)
   3605 {
   3606     int32_t val;
   3607     val = floatx_to_int32_round_to_zero(ST0, &env->fp_status);
   3608     return val;
   3609 }
   3610 
   3611 int64_t helper_fisttll_ST0(void)
   3612 {
   3613     int64_t val;
   3614     val = floatx_to_int64_round_to_zero(ST0, &env->fp_status);
   3615     return val;
   3616 }
   3617 
   3618 void helper_fldt_ST0(target_ulong ptr)
   3619 {
   3620     int new_fpstt;
   3621     new_fpstt = (env->fpstt - 1) & 7;
   3622     env->fpregs[new_fpstt].d = helper_fldt(ptr);
   3623     env->fpstt = new_fpstt;
   3624     env->fptags[new_fpstt] = 0; /* validate stack entry */
   3625 }
   3626 
   3627 void helper_fstt_ST0(target_ulong ptr)
   3628 {
   3629     helper_fstt(ST0, ptr);
   3630 }
   3631 
   3632 void helper_fpush(void)
   3633 {
   3634     fpush();
   3635 }
   3636 
   3637 void helper_fpop(void)
   3638 {
   3639     fpop();
   3640 }
   3641 
   3642 void helper_fdecstp(void)
   3643 {
   3644     env->fpstt = (env->fpstt - 1) & 7;
   3645     env->fpus &= (~0x4700);
   3646 }
   3647 
   3648 void helper_fincstp(void)
   3649 {
   3650     env->fpstt = (env->fpstt + 1) & 7;
   3651     env->fpus &= (~0x4700);
   3652 }
   3653 
   3654 /* FPU move */
   3655 
   3656 void helper_ffree_STN(int st_index)
   3657 {
   3658     env->fptags[(env->fpstt + st_index) & 7] = 1;
   3659 }
   3660 
   3661 void helper_fmov_ST0_FT0(void)
   3662 {
   3663     ST0 = FT0;
   3664 }
   3665 
   3666 void helper_fmov_FT0_STN(int st_index)
   3667 {
   3668     FT0 = ST(st_index);
   3669 }
   3670 
   3671 void helper_fmov_ST0_STN(int st_index)
   3672 {
   3673     ST0 = ST(st_index);
   3674 }
   3675 
   3676 void helper_fmov_STN_ST0(int st_index)
   3677 {
   3678     ST(st_index) = ST0;
   3679 }
   3680 
   3681 void helper_fxchg_ST0_STN(int st_index)
   3682 {
   3683     CPU86_LDouble tmp;
   3684     tmp = ST(st_index);
   3685     ST(st_index) = ST0;
   3686     ST0 = tmp;
   3687 }
   3688 
   3689 /* FPU operations */
   3690 
   3691 static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500};
   3692 
   3693 void helper_fcom_ST0_FT0(void)
   3694 {
   3695     int ret;
   3696 
   3697     ret = floatx_compare(ST0, FT0, &env->fp_status);
   3698     env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1];
   3699 }
   3700 
   3701 void helper_fucom_ST0_FT0(void)
   3702 {
   3703     int ret;
   3704 
   3705     ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
   3706     env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1];
   3707 }
   3708 
   3709 static const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
   3710 
   3711 void helper_fcomi_ST0_FT0(void)
   3712 {
   3713     int eflags;
   3714     int ret;
   3715 
   3716     ret = floatx_compare(ST0, FT0, &env->fp_status);
   3717     eflags = helper_cc_compute_all(CC_OP);
   3718     eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
   3719     CC_SRC = eflags;
   3720 }
   3721 
   3722 void helper_fucomi_ST0_FT0(void)
   3723 {
   3724     int eflags;
   3725     int ret;
   3726 
   3727     ret = floatx_compare_quiet(ST0, FT0, &env->fp_status);
   3728     eflags = helper_cc_compute_all(CC_OP);
   3729     eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1];
   3730     CC_SRC = eflags;
   3731 }
   3732 
   3733 void helper_fadd_ST0_FT0(void)
   3734 {
   3735     ST0 += FT0;
   3736 }
   3737 
   3738 void helper_fmul_ST0_FT0(void)
   3739 {
   3740     ST0 *= FT0;
   3741 }
   3742 
   3743 void helper_fsub_ST0_FT0(void)
   3744 {
   3745     ST0 -= FT0;
   3746 }
   3747 
   3748 void helper_fsubr_ST0_FT0(void)
   3749 {
   3750     ST0 = FT0 - ST0;
   3751 }
   3752 
   3753 void helper_fdiv_ST0_FT0(void)
   3754 {
   3755     ST0 = helper_fdiv(ST0, FT0);
   3756 }
   3757 
   3758 void helper_fdivr_ST0_FT0(void)
   3759 {
   3760     ST0 = helper_fdiv(FT0, ST0);
   3761 }
   3762 
   3763 /* fp operations between STN and ST0 */
   3764 
   3765 void helper_fadd_STN_ST0(int st_index)
   3766 {
   3767     ST(st_index) += ST0;
   3768 }
   3769 
   3770 void helper_fmul_STN_ST0(int st_index)
   3771 {
   3772     ST(st_index) *= ST0;
   3773 }
   3774 
   3775 void helper_fsub_STN_ST0(int st_index)
   3776 {
   3777     ST(st_index) -= ST0;
   3778 }
   3779 
   3780 void helper_fsubr_STN_ST0(int st_index)
   3781 {
   3782     CPU86_LDouble *p;
   3783     p = &ST(st_index);
   3784     *p = ST0 - *p;
   3785 }
   3786 
   3787 void helper_fdiv_STN_ST0(int st_index)
   3788 {
   3789     CPU86_LDouble *p;
   3790     p = &ST(st_index);
   3791     *p = helper_fdiv(*p, ST0);
   3792 }
   3793 
   3794 void helper_fdivr_STN_ST0(int st_index)
   3795 {
   3796     CPU86_LDouble *p;
   3797     p = &ST(st_index);
   3798     *p = helper_fdiv(ST0, *p);
   3799 }
   3800 
   3801 /* misc FPU operations */
   3802 void helper_fchs_ST0(void)
   3803 {
   3804     ST0 = floatx_chs(ST0);
   3805 }
   3806 
   3807 void helper_fabs_ST0(void)
   3808 {
   3809     ST0 = floatx_abs(ST0);
   3810 }
   3811 
   3812 void helper_fld1_ST0(void)
   3813 {
   3814     ST0 = f15rk[1];
   3815 }
   3816 
   3817 void helper_fldl2t_ST0(void)
   3818 {
   3819     ST0 = f15rk[6];
   3820 }
   3821 
   3822 void helper_fldl2e_ST0(void)
   3823 {
   3824     ST0 = f15rk[5];
   3825 }
   3826 
   3827 void helper_fldpi_ST0(void)
   3828 {
   3829     ST0 = f15rk[2];
   3830 }
   3831 
   3832 void helper_fldlg2_ST0(void)
   3833 {
   3834     ST0 = f15rk[3];
   3835 }
   3836 
   3837 void helper_fldln2_ST0(void)
   3838 {
   3839     ST0 = f15rk[4];
   3840 }
   3841 
   3842 void helper_fldz_ST0(void)
   3843 {
   3844     ST0 = f15rk[0];
   3845 }
   3846 
   3847 void helper_fldz_FT0(void)
   3848 {
   3849     FT0 = f15rk[0];
   3850 }
   3851 
   3852 uint32_t helper_fnstsw(void)
   3853 {
   3854     return (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
   3855 }
   3856 
   3857 uint32_t helper_fnstcw(void)
   3858 {
   3859     return env->fpuc;
   3860 }
   3861 
   3862 static void update_fp_status(void)
   3863 {
   3864     int rnd_type;
   3865 
   3866     /* set rounding mode */
   3867     switch(env->fpuc & RC_MASK) {
   3868     default:
   3869     case RC_NEAR:
   3870         rnd_type = float_round_nearest_even;
   3871         break;
   3872     case RC_DOWN:
   3873         rnd_type = float_round_down;
   3874         break;
   3875     case RC_UP:
   3876         rnd_type = float_round_up;
   3877         break;
   3878     case RC_CHOP:
   3879         rnd_type = float_round_to_zero;
   3880         break;
   3881     }
   3882     set_float_rounding_mode(rnd_type, &env->fp_status);
   3883 #ifdef FLOATX80
   3884     switch((env->fpuc >> 8) & 3) {
   3885     case 0:
   3886         rnd_type = 32;
   3887         break;
   3888     case 2:
   3889         rnd_type = 64;
   3890         break;
   3891     case 3:
   3892     default:
   3893         rnd_type = 80;
   3894         break;
   3895     }
   3896     set_floatx80_rounding_precision(rnd_type, &env->fp_status);
   3897 #endif
   3898 }
   3899 
   3900 void helper_fldcw(uint32_t val)
   3901 {
   3902     env->fpuc = val;
   3903     update_fp_status();
   3904 }
   3905 
   3906 void helper_fclex(void)
   3907 {
   3908     env->fpus &= 0x7f00;
   3909 }
   3910 
   3911 void helper_fwait(void)
   3912 {
   3913     if (env->fpus & FPUS_SE)
   3914         fpu_raise_exception();
   3915 }
   3916 
   3917 void helper_fninit(void)
   3918 {
   3919     env->fpus = 0;
   3920     env->fpstt = 0;
   3921     env->fpuc = 0x37f;
   3922     env->fptags[0] = 1;
   3923     env->fptags[1] = 1;
   3924     env->fptags[2] = 1;
   3925     env->fptags[3] = 1;
   3926     env->fptags[4] = 1;
   3927     env->fptags[5] = 1;
   3928     env->fptags[6] = 1;
   3929     env->fptags[7] = 1;
   3930 }
   3931 
   3932 /* BCD ops */
   3933 
   3934 void helper_fbld_ST0(target_ulong ptr)
   3935 {
   3936     CPU86_LDouble tmp;
   3937     uint64_t val;
   3938     unsigned int v;
   3939     int i;
   3940 
   3941     val = 0;
   3942     for(i = 8; i >= 0; i--) {
   3943         v = ldub(ptr + i);
   3944         val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
   3945     }
   3946     tmp = val;
   3947     if (ldub(ptr + 9) & 0x80)
   3948         tmp = -tmp;
   3949     fpush();
   3950     ST0 = tmp;
   3951 }
   3952 
   3953 void helper_fbst_ST0(target_ulong ptr)
   3954 {
   3955     int v;
   3956     target_ulong mem_ref, mem_end;
   3957     int64_t val;
   3958 
   3959     val = floatx_to_int64(ST0, &env->fp_status);
   3960     mem_ref = ptr;
   3961     mem_end = mem_ref + 9;
   3962     if (val < 0) {
   3963         stb(mem_end, 0x80);
   3964         val = -val;
   3965     } else {
   3966         stb(mem_end, 0x00);
   3967     }
   3968     while (mem_ref < mem_end) {
   3969         if (val == 0)
   3970             break;
   3971         v = val % 100;
   3972         val = val / 100;
   3973         v = ((v / 10) << 4) | (v % 10);
   3974         stb(mem_ref++, v);
   3975     }
   3976     while (mem_ref < mem_end) {
   3977         stb(mem_ref++, 0);
   3978     }
   3979 }
   3980 
   3981 void helper_f2xm1(void)
   3982 {
   3983     ST0 = pow(2.0,ST0) - 1.0;
   3984 }
   3985 
   3986 void helper_fyl2x(void)
   3987 {
   3988     CPU86_LDouble fptemp;
   3989 
   3990     fptemp = ST0;
   3991     if (fptemp>0.0){
   3992         fptemp = log(fptemp)/log(2.0);	 /* log2(ST) */
   3993         ST1 *= fptemp;
   3994         fpop();
   3995     } else {
   3996         env->fpus &= (~0x4700);
   3997         env->fpus |= 0x400;
   3998     }
   3999 }
   4000 
   4001 void helper_fptan(void)
   4002 {
   4003     CPU86_LDouble fptemp;
   4004 
   4005     fptemp = ST0;
   4006     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
   4007         env->fpus |= 0x400;
   4008     } else {
   4009         ST0 = tan(fptemp);
   4010         fpush();
   4011         ST0 = 1.0;
   4012         env->fpus &= (~0x400);  /* C2 <-- 0 */
   4013         /* the above code is for  |arg| < 2**52 only */
   4014     }
   4015 }
   4016 
   4017 void helper_fpatan(void)
   4018 {
   4019     CPU86_LDouble fptemp, fpsrcop;
   4020 
   4021     fpsrcop = ST1;
   4022     fptemp = ST0;
   4023     ST1 = atan2(fpsrcop,fptemp);
   4024     fpop();
   4025 }
   4026 
   4027 void helper_fxtract(void)
   4028 {
   4029     CPU86_LDoubleU temp;
   4030     unsigned int expdif;
   4031 
   4032     temp.d = ST0;
   4033     expdif = EXPD(temp) - EXPBIAS;
   4034     /*DP exponent bias*/
   4035     ST0 = expdif;
   4036     fpush();
   4037     BIASEXPONENT(temp);
   4038     ST0 = temp.d;
   4039 }
   4040 
   4041 void helper_fprem1(void)
   4042 {
   4043     CPU86_LDouble dblq, fpsrcop, fptemp;
   4044     CPU86_LDoubleU fpsrcop1, fptemp1;
   4045     int expdif;
   4046     signed long long int q;
   4047 
   4048     if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
   4049         ST0 = 0.0 / 0.0; /* NaN */
   4050         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
   4051         return;
   4052     }
   4053 
   4054     fpsrcop = ST0;
   4055     fptemp = ST1;
   4056     fpsrcop1.d = fpsrcop;
   4057     fptemp1.d = fptemp;
   4058     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
   4059 
   4060     if (expdif < 0) {
   4061         /* optimisation? taken from the AMD docs */
   4062         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
   4063         /* ST0 is unchanged */
   4064         return;
   4065     }
   4066 
   4067     if (expdif < 53) {
   4068         dblq = fpsrcop / fptemp;
   4069         /* round dblq towards nearest integer */
   4070         dblq = rint(dblq);
   4071         ST0 = fpsrcop - fptemp * dblq;
   4072 
   4073         /* convert dblq to q by truncating towards zero */
   4074         if (dblq < 0.0)
   4075            q = (signed long long int)(-dblq);
   4076         else
   4077            q = (signed long long int)dblq;
   4078 
   4079         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
   4080                                 /* (C0,C3,C1) <-- (q2,q1,q0) */
   4081         env->fpus |= (q & 0x4) << (8 - 2);  /* (C0) <-- q2 */
   4082         env->fpus |= (q & 0x2) << (14 - 1); /* (C3) <-- q1 */
   4083         env->fpus |= (q & 0x1) << (9 - 0);  /* (C1) <-- q0 */
   4084     } else {
   4085         env->fpus |= 0x400;  /* C2 <-- 1 */
   4086         fptemp = pow(2.0, expdif - 50);
   4087         fpsrcop = (ST0 / ST1) / fptemp;
   4088         /* fpsrcop = integer obtained by chopping */
   4089         fpsrcop = (fpsrcop < 0.0) ?
   4090                   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
   4091         ST0 -= (ST1 * fpsrcop * fptemp);
   4092     }
   4093 }
   4094 
   4095 void helper_fprem(void)
   4096 {
   4097     CPU86_LDouble dblq, fpsrcop, fptemp;
   4098     CPU86_LDoubleU fpsrcop1, fptemp1;
   4099     int expdif;
   4100     signed long long int q;
   4101 
   4102     if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
   4103        ST0 = 0.0 / 0.0; /* NaN */
   4104        env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
   4105        return;
   4106     }
   4107 
   4108     fpsrcop = (CPU86_LDouble)ST0;
   4109     fptemp = (CPU86_LDouble)ST1;
   4110     fpsrcop1.d = fpsrcop;
   4111     fptemp1.d = fptemp;
   4112     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
   4113 
   4114     if (expdif < 0) {
   4115         /* optimisation? taken from the AMD docs */
   4116         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
   4117         /* ST0 is unchanged */
   4118         return;
   4119     }
   4120 
   4121     if ( expdif < 53 ) {
   4122         dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/;
   4123         /* round dblq towards zero */
   4124         dblq = (dblq < 0.0) ? ceil(dblq) : floor(dblq);
   4125         ST0 = fpsrcop/*ST0*/ - fptemp * dblq;
   4126 
   4127         /* convert dblq to q by truncating towards zero */
   4128         if (dblq < 0.0)
   4129            q = (signed long long int)(-dblq);
   4130         else
   4131            q = (signed long long int)dblq;
   4132 
   4133         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
   4134                                 /* (C0,C3,C1) <-- (q2,q1,q0) */
   4135         env->fpus |= (q & 0x4) << (8 - 2);  /* (C0) <-- q2 */
   4136         env->fpus |= (q & 0x2) << (14 - 1); /* (C3) <-- q1 */
   4137         env->fpus |= (q & 0x1) << (9 - 0);  /* (C1) <-- q0 */
   4138     } else {
   4139         int N = 32 + (expdif % 32); /* as per AMD docs */
   4140         env->fpus |= 0x400;  /* C2 <-- 1 */
   4141         fptemp = pow(2.0, (double)(expdif - N));
   4142         fpsrcop = (ST0 / ST1) / fptemp;
   4143         /* fpsrcop = integer obtained by chopping */
   4144         fpsrcop = (fpsrcop < 0.0) ?
   4145                   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
   4146         ST0 -= (ST1 * fpsrcop * fptemp);
   4147     }
   4148 }
   4149 
   4150 void helper_fyl2xp1(void)
   4151 {
   4152     CPU86_LDouble fptemp;
   4153 
   4154     fptemp = ST0;
   4155     if ((fptemp+1.0)>0.0) {
   4156         fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
   4157         ST1 *= fptemp;
   4158         fpop();
   4159     } else {
   4160         env->fpus &= (~0x4700);
   4161         env->fpus |= 0x400;
   4162     }
   4163 }
   4164 
   4165 void helper_fsqrt(void)
   4166 {
   4167     CPU86_LDouble fptemp;
   4168 
   4169     fptemp = ST0;
   4170     if (fptemp<0.0) {
   4171         env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
   4172         env->fpus |= 0x400;
   4173     }
   4174     ST0 = sqrt(fptemp);
   4175 }
   4176 
   4177 void helper_fsincos(void)
   4178 {
   4179     CPU86_LDouble fptemp;
   4180 
   4181     fptemp = ST0;
   4182     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
   4183         env->fpus |= 0x400;
   4184     } else {
   4185         ST0 = sin(fptemp);
   4186         fpush();
   4187         ST0 = cos(fptemp);
   4188         env->fpus &= (~0x400);  /* C2 <-- 0 */
   4189         /* the above code is for  |arg| < 2**63 only */
   4190     }
   4191 }
   4192 
   4193 void helper_frndint(void)
   4194 {
   4195     ST0 = floatx_round_to_int(ST0, &env->fp_status);
   4196 }
   4197 
   4198 void helper_fscale(void)
   4199 {
   4200     ST0 = ldexp (ST0, (int)(ST1));
   4201 }
   4202 
   4203 void helper_fsin(void)
   4204 {
   4205     CPU86_LDouble fptemp;
   4206 
   4207     fptemp = ST0;
   4208     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
   4209         env->fpus |= 0x400;
   4210     } else {
   4211         ST0 = sin(fptemp);
   4212         env->fpus &= (~0x400);  /* C2 <-- 0 */
   4213         /* the above code is for  |arg| < 2**53 only */
   4214     }
   4215 }
   4216 
   4217 void helper_fcos(void)
   4218 {
   4219     CPU86_LDouble fptemp;
   4220 
   4221     fptemp = ST0;
   4222     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
   4223         env->fpus |= 0x400;
   4224     } else {
   4225         ST0 = cos(fptemp);
   4226         env->fpus &= (~0x400);  /* C2 <-- 0 */
   4227         /* the above code is for  |arg5 < 2**63 only */
   4228     }
   4229 }
   4230 
   4231 void helper_fxam_ST0(void)
   4232 {
   4233     CPU86_LDoubleU temp;
   4234     int expdif;
   4235 
   4236     temp.d = ST0;
   4237 
   4238     env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
   4239     if (SIGND(temp))
   4240         env->fpus |= 0x200; /* C1 <-- 1 */
   4241 
   4242     /* XXX: test fptags too */
   4243     expdif = EXPD(temp);
   4244     if (expdif == MAXEXPD) {
   4245 #ifdef USE_X86LDOUBLE
   4246         if (MANTD(temp) == 0x8000000000000000ULL)
   4247 #else
   4248         if (MANTD(temp) == 0)
   4249 #endif
   4250             env->fpus |=  0x500 /*Infinity*/;
   4251         else
   4252             env->fpus |=  0x100 /*NaN*/;
   4253     } else if (expdif == 0) {
   4254         if (MANTD(temp) == 0)
   4255             env->fpus |=  0x4000 /*Zero*/;
   4256         else
   4257             env->fpus |= 0x4400 /*Denormal*/;
   4258     } else {
   4259         env->fpus |= 0x400;
   4260     }
   4261 }
   4262 
   4263 void helper_fstenv(target_ulong ptr, int data32)
   4264 {
   4265     int fpus, fptag, exp, i;
   4266     uint64_t mant;
   4267     CPU86_LDoubleU tmp;
   4268 
   4269     fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
   4270     fptag = 0;
   4271     for (i=7; i>=0; i--) {
   4272 	fptag <<= 2;
   4273 	if (env->fptags[i]) {
   4274             fptag |= 3;
   4275 	} else {
   4276             tmp.d = env->fpregs[i].d;
   4277             exp = EXPD(tmp);
   4278             mant = MANTD(tmp);
   4279             if (exp == 0 && mant == 0) {
   4280                 /* zero */
   4281 	        fptag |= 1;
   4282 	    } else if (exp == 0 || exp == MAXEXPD
   4283 #ifdef USE_X86LDOUBLE
   4284                        || (mant & (1LL << 63)) == 0
   4285 #endif
   4286                        ) {
   4287                 /* NaNs, infinity, denormal */
   4288                 fptag |= 2;
   4289             }
   4290         }
   4291     }
   4292     if (data32) {
   4293         /* 32 bit */
   4294         stl(ptr, env->fpuc);
   4295         stl(ptr + 4, fpus);
   4296         stl(ptr + 8, fptag);
   4297         stl(ptr + 12, 0); /* fpip */
   4298         stl(ptr + 16, 0); /* fpcs */
   4299         stl(ptr + 20, 0); /* fpoo */
   4300         stl(ptr + 24, 0); /* fpos */
   4301     } else {
   4302         /* 16 bit */
   4303         stw(ptr, env->fpuc);
   4304         stw(ptr + 2, fpus);
   4305         stw(ptr + 4, fptag);
   4306         stw(ptr + 6, 0);
   4307         stw(ptr + 8, 0);
   4308         stw(ptr + 10, 0);
   4309         stw(ptr + 12, 0);
   4310     }
   4311 }
   4312 
   4313 void helper_fldenv(target_ulong ptr, int data32)
   4314 {
   4315     int i, fpus, fptag;
   4316 
   4317     if (data32) {
   4318 	env->fpuc = lduw(ptr);
   4319         fpus = lduw(ptr + 4);
   4320         fptag = lduw(ptr + 8);
   4321     }
   4322     else {
   4323 	env->fpuc = lduw(ptr);
   4324         fpus = lduw(ptr + 2);
   4325         fptag = lduw(ptr + 4);
   4326     }
   4327     env->fpstt = (fpus >> 11) & 7;
   4328     env->fpus = fpus & ~0x3800;
   4329     for(i = 0;i < 8; i++) {
   4330         env->fptags[i] = ((fptag & 3) == 3);
   4331         fptag >>= 2;
   4332     }
   4333 }
   4334 
   4335 void helper_fsave(target_ulong ptr, int data32)
   4336 {
   4337     CPU86_LDouble tmp;
   4338     int i;
   4339 
   4340     helper_fstenv(ptr, data32);
   4341 
   4342     ptr += (14 << data32);
   4343     for(i = 0;i < 8; i++) {
   4344         tmp = ST(i);
   4345         helper_fstt(tmp, ptr);
   4346         ptr += 10;
   4347     }
   4348 
   4349     /* fninit */
   4350     env->fpus = 0;
   4351     env->fpstt = 0;
   4352     env->fpuc = 0x37f;
   4353     env->fptags[0] = 1;
   4354     env->fptags[1] = 1;
   4355     env->fptags[2] = 1;
   4356     env->fptags[3] = 1;
   4357     env->fptags[4] = 1;
   4358     env->fptags[5] = 1;
   4359     env->fptags[6] = 1;
   4360     env->fptags[7] = 1;
   4361 }
   4362 
   4363 void helper_frstor(target_ulong ptr, int data32)
   4364 {
   4365     CPU86_LDouble tmp;
   4366     int i;
   4367 
   4368     helper_fldenv(ptr, data32);
   4369     ptr += (14 << data32);
   4370 
   4371     for(i = 0;i < 8; i++) {
   4372         tmp = helper_fldt(ptr);
   4373         ST(i) = tmp;
   4374         ptr += 10;
   4375     }
   4376 }
   4377 
   4378 void helper_fxsave(target_ulong ptr, int data64)
   4379 {
   4380     int fpus, fptag, i, nb_xmm_regs;
   4381     CPU86_LDouble tmp;
   4382     target_ulong addr;
   4383 
   4384     fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
   4385     fptag = 0;
   4386     for(i = 0; i < 8; i++) {
   4387         fptag |= (env->fptags[i] << i);
   4388     }
   4389     stw(ptr, env->fpuc);
   4390     stw(ptr + 2, fpus);
   4391     stw(ptr + 4, fptag ^ 0xff);
   4392 #ifdef TARGET_X86_64
   4393     if (data64) {
   4394         stq(ptr + 0x08, 0); /* rip */
   4395         stq(ptr + 0x10, 0); /* rdp */
   4396     } else
   4397 #endif
   4398     {
   4399         stl(ptr + 0x08, 0); /* eip */
   4400         stl(ptr + 0x0c, 0); /* sel  */
   4401         stl(ptr + 0x10, 0); /* dp */
   4402         stl(ptr + 0x14, 0); /* sel  */
   4403     }
   4404 
   4405     addr = ptr + 0x20;
   4406     for(i = 0;i < 8; i++) {
   4407         tmp = ST(i);
   4408         helper_fstt(tmp, addr);
   4409         addr += 16;
   4410     }
   4411 
   4412     if (env->cr[4] & CR4_OSFXSR_MASK) {
   4413         /* XXX: finish it */
   4414         stl(ptr + 0x18, env->mxcsr); /* mxcsr */
   4415         stl(ptr + 0x1c, 0x0000ffff); /* mxcsr_mask */
   4416         if (env->hflags & HF_CS64_MASK)
   4417             nb_xmm_regs = 16;
   4418         else
   4419             nb_xmm_regs = 8;
   4420         addr = ptr + 0xa0;
   4421         /* Fast FXSAVE leaves out the XMM registers */
   4422         if (!(env->efer & MSR_EFER_FFXSR)
   4423           || (env->hflags & HF_CPL_MASK)
   4424           || !(env->hflags & HF_LMA_MASK)) {
   4425             for(i = 0; i < nb_xmm_regs; i++) {
   4426                 stq(addr, env->xmm_regs[i].XMM_Q(0));
   4427                 stq(addr + 8, env->xmm_regs[i].XMM_Q(1));
   4428                 addr += 16;
   4429             }
   4430         }
   4431     }
   4432 }
   4433 
   4434 void helper_fxrstor(target_ulong ptr, int data64)
   4435 {
   4436     int i, fpus, fptag, nb_xmm_regs;
   4437     CPU86_LDouble tmp;
   4438     target_ulong addr;
   4439 
   4440     env->fpuc = lduw(ptr);
   4441     fpus = lduw(ptr + 2);
   4442     fptag = lduw(ptr + 4);
   4443     env->fpstt = (fpus >> 11) & 7;
   4444     env->fpus = fpus & ~0x3800;
   4445     fptag ^= 0xff;
   4446     for(i = 0;i < 8; i++) {
   4447         env->fptags[i] = ((fptag >> i) & 1);
   4448     }
   4449 
   4450     addr = ptr + 0x20;
   4451     for(i = 0;i < 8; i++) {
   4452         tmp = helper_fldt(addr);
   4453         ST(i) = tmp;
   4454         addr += 16;
   4455     }
   4456 
   4457     if (env->cr[4] & CR4_OSFXSR_MASK) {
   4458         /* XXX: finish it */
   4459         env->mxcsr = ldl(ptr + 0x18);
   4460         //ldl(ptr + 0x1c);
   4461         if (env->hflags & HF_CS64_MASK)
   4462             nb_xmm_regs = 16;
   4463         else
   4464             nb_xmm_regs = 8;
   4465         addr = ptr + 0xa0;
   4466         /* Fast FXRESTORE leaves out the XMM registers */
   4467         if (!(env->efer & MSR_EFER_FFXSR)
   4468           || (env->hflags & HF_CPL_MASK)
   4469           || !(env->hflags & HF_LMA_MASK)) {
   4470             for(i = 0; i < nb_xmm_regs; i++) {
   4471                 env->xmm_regs[i].XMM_Q(0) = ldq(addr);
   4472                 env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
   4473                 addr += 16;
   4474             }
   4475         }
   4476     }
   4477 }
   4478 
   4479 #ifndef USE_X86LDOUBLE
   4480 
   4481 void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f)
   4482 {
   4483     CPU86_LDoubleU temp;
   4484     int e;
   4485 
   4486     temp.d = f;
   4487     /* mantissa */
   4488     *pmant = (MANTD(temp) << 11) | (1LL << 63);
   4489     /* exponent + sign */
   4490     e = EXPD(temp) - EXPBIAS + 16383;
   4491     e |= SIGND(temp) >> 16;
   4492     *pexp = e;
   4493 }
   4494 
   4495 CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper)
   4496 {
   4497     CPU86_LDoubleU temp;
   4498     int e;
   4499     uint64_t ll;
   4500 
   4501     /* XXX: handle overflow ? */
   4502     e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
   4503     e |= (upper >> 4) & 0x800; /* sign */
   4504     ll = (mant >> 11) & ((1LL << 52) - 1);
   4505 #ifdef __arm__
   4506     temp.l.upper = (e << 20) | (ll >> 32);
   4507     temp.l.lower = ll;
   4508 #else
   4509     temp.ll = ll | ((uint64_t)e << 52);
   4510 #endif
   4511     return temp.d;
   4512 }
   4513 
   4514 #else
   4515 
   4516 void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f)
   4517 {
   4518     CPU86_LDoubleU temp;
   4519 
   4520     temp.d = f;
   4521     *pmant = temp.l.lower;
   4522     *pexp = temp.l.upper;
   4523 }
   4524 
   4525 CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper)
   4526 {
   4527     CPU86_LDoubleU temp;
   4528 
   4529     temp.l.upper = upper;
   4530     temp.l.lower = mant;
   4531     return temp.d;
   4532 }
   4533 #endif
   4534 
   4535 #ifdef TARGET_X86_64
   4536 
   4537 //#define DEBUG_MULDIV
   4538 
   4539 static void add128(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
   4540 {
   4541     *plow += a;
   4542     /* carry test */
   4543     if (*plow < a)
   4544         (*phigh)++;
   4545     *phigh += b;
   4546 }
   4547 
   4548 static void neg128(uint64_t *plow, uint64_t *phigh)
   4549 {
   4550     *plow = ~ *plow;
   4551     *phigh = ~ *phigh;
   4552     add128(plow, phigh, 1, 0);
   4553 }
   4554 
   4555 /* return TRUE if overflow */
   4556 static int div64(uint64_t *plow, uint64_t *phigh, uint64_t b)
   4557 {
   4558     uint64_t q, r, a1, a0;
   4559     int i, qb, ab;
   4560 
   4561     a0 = *plow;
   4562     a1 = *phigh;
   4563     if (a1 == 0) {
   4564         q = a0 / b;
   4565         r = a0 % b;
   4566         *plow = q;
   4567         *phigh = r;
   4568     } else {
   4569         if (a1 >= b)
   4570             return 1;
   4571         /* XXX: use a better algorithm */
   4572         for(i = 0; i < 64; i++) {
   4573             ab = a1 >> 63;
   4574             a1 = (a1 << 1) | (a0 >> 63);
   4575             if (ab || a1 >= b) {
   4576                 a1 -= b;
   4577                 qb = 1;
   4578             } else {
   4579                 qb = 0;
   4580             }
   4581             a0 = (a0 << 1) | qb;
   4582         }
   4583 #if defined(DEBUG_MULDIV)
   4584         printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n",
   4585                *phigh, *plow, b, a0, a1);
   4586 #endif
   4587         *plow = a0;
   4588         *phigh = a1;
   4589     }
   4590     return 0;
   4591 }
   4592 
   4593 /* return TRUE if overflow */
   4594 static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
   4595 {
   4596     int sa, sb;
   4597     sa = ((int64_t)*phigh < 0);
   4598     if (sa)
   4599         neg128(plow, phigh);
   4600     sb = (b < 0);
   4601     if (sb)
   4602         b = -b;
   4603     if (div64(plow, phigh, b) != 0)
   4604         return 1;
   4605     if (sa ^ sb) {
   4606         if (*plow > (1ULL << 63))
   4607             return 1;
   4608         *plow = - *plow;
   4609     } else {
   4610         if (*plow >= (1ULL << 63))
   4611             return 1;
   4612     }
   4613     if (sa)
   4614         *phigh = - *phigh;
   4615     return 0;
   4616 }
   4617 
   4618 void helper_mulq_EAX_T0(target_ulong t0)
   4619 {
   4620     uint64_t r0, r1;
   4621 
   4622     mulu64(&r0, &r1, EAX, t0);
   4623     EAX = r0;
   4624     EDX = r1;
   4625     CC_DST = r0;
   4626     CC_SRC = r1;
   4627 }
   4628 
   4629 void helper_imulq_EAX_T0(target_ulong t0)
   4630 {
   4631     uint64_t r0, r1;
   4632 
   4633     muls64(&r0, &r1, EAX, t0);
   4634     EAX = r0;
   4635     EDX = r1;
   4636     CC_DST = r0;
   4637     CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
   4638 }
   4639 
   4640 target_ulong helper_imulq_T0_T1(target_ulong t0, target_ulong t1)
   4641 {
   4642     uint64_t r0, r1;
   4643 
   4644     muls64(&r0, &r1, t0, t1);
   4645     CC_DST = r0;
   4646     CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63));
   4647     return r0;
   4648 }
   4649 
   4650 void helper_divq_EAX(target_ulong t0)
   4651 {
   4652     uint64_t r0, r1;
   4653     if (t0 == 0) {
   4654         raise_exception(EXCP00_DIVZ);
   4655     }
   4656     r0 = EAX;
   4657     r1 = EDX;
   4658     if (div64(&r0, &r1, t0))
   4659         raise_exception(EXCP00_DIVZ);
   4660     EAX = r0;
   4661     EDX = r1;
   4662 }
   4663 
   4664 void helper_idivq_EAX(target_ulong t0)
   4665 {
   4666     uint64_t r0, r1;
   4667     if (t0 == 0) {
   4668         raise_exception(EXCP00_DIVZ);
   4669     }
   4670     r0 = EAX;
   4671     r1 = EDX;
   4672     if (idiv64(&r0, &r1, t0))
   4673         raise_exception(EXCP00_DIVZ);
   4674     EAX = r0;
   4675     EDX = r1;
   4676 }
   4677 #endif
   4678 
   4679 static void do_hlt(void)
   4680 {
   4681     env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
   4682     env->halted = 1;
   4683     env->exception_index = EXCP_HLT;
   4684     cpu_loop_exit();
   4685 }
   4686 
   4687 void helper_hlt(int next_eip_addend)
   4688 {
   4689     helper_svm_check_intercept_param(SVM_EXIT_HLT, 0);
   4690     EIP += next_eip_addend;
   4691 
   4692     do_hlt();
   4693 }
   4694 
   4695 void helper_monitor(target_ulong ptr)
   4696 {
   4697     if ((uint32_t)ECX != 0)
   4698         raise_exception(EXCP0D_GPF);
   4699     /* XXX: store address ? */
   4700     helper_svm_check_intercept_param(SVM_EXIT_MONITOR, 0);
   4701 }
   4702 
   4703 void helper_mwait(int next_eip_addend)
   4704 {
   4705     if ((uint32_t)ECX != 0)
   4706         raise_exception(EXCP0D_GPF);
   4707     helper_svm_check_intercept_param(SVM_EXIT_MWAIT, 0);
   4708     EIP += next_eip_addend;
   4709 
   4710     /* XXX: not complete but not completely erroneous */
   4711     if (env->cpu_index != 0 || env->next_cpu != NULL) {
   4712         /* more than one CPU: do not sleep because another CPU may
   4713            wake this one */
   4714     } else {
   4715         do_hlt();
   4716     }
   4717 }
   4718 
   4719 void helper_debug(void)
   4720 {
   4721     env->exception_index = EXCP_DEBUG;
   4722     cpu_loop_exit();
   4723 }
   4724 
   4725 void helper_reset_rf(void)
   4726 {
   4727     env->eflags &= ~RF_MASK;
   4728 }
   4729 
   4730 void helper_raise_interrupt(int intno, int next_eip_addend)
   4731 {
   4732     raise_interrupt(intno, 1, 0, next_eip_addend);
   4733 }
   4734 
   4735 void helper_raise_exception(int exception_index)
   4736 {
   4737     raise_exception(exception_index);
   4738 }
   4739 
   4740 void helper_cli(void)
   4741 {
   4742     env->eflags &= ~IF_MASK;
   4743 }
   4744 
   4745 void helper_sti(void)
   4746 {
   4747     env->eflags |= IF_MASK;
   4748 }
   4749 
   4750 #if 0
   4751 /* vm86plus instructions */
   4752 void helper_cli_vm(void)
   4753 {
   4754     env->eflags &= ~VIF_MASK;
   4755 }
   4756 
   4757 void helper_sti_vm(void)
   4758 {
   4759     env->eflags |= VIF_MASK;
   4760     if (env->eflags & VIP_MASK) {
   4761         raise_exception(EXCP0D_GPF);
   4762     }
   4763 }
   4764 #endif
   4765 
   4766 void helper_set_inhibit_irq(void)
   4767 {
   4768     env->hflags |= HF_INHIBIT_IRQ_MASK;
   4769 }
   4770 
   4771 void helper_reset_inhibit_irq(void)
   4772 {
   4773     env->hflags &= ~HF_INHIBIT_IRQ_MASK;
   4774 }
   4775 
   4776 void helper_boundw(target_ulong a0, int v)
   4777 {
   4778     int low, high;
   4779     low = ldsw(a0);
   4780     high = ldsw(a0 + 2);
   4781     v = (int16_t)v;
   4782     if (v < low || v > high) {
   4783         raise_exception(EXCP05_BOUND);
   4784     }
   4785 }
   4786 
   4787 void helper_boundl(target_ulong a0, int v)
   4788 {
   4789     int low, high;
   4790     low = ldl(a0);
   4791     high = ldl(a0 + 4);
   4792     if (v < low || v > high) {
   4793         raise_exception(EXCP05_BOUND);
   4794     }
   4795 }
   4796 
   4797 static float approx_rsqrt(float a)
   4798 {
   4799     return 1.0 / sqrt(a);
   4800 }
   4801 
   4802 static float approx_rcp(float a)
   4803 {
   4804     return 1.0 / a;
   4805 }
   4806 
   4807 #if !defined(CONFIG_USER_ONLY)
   4808 
   4809 #define MMUSUFFIX _mmu
   4810 
   4811 #define SHIFT 0
   4812 #include "softmmu_template.h"
   4813 
   4814 #define SHIFT 1
   4815 #include "softmmu_template.h"
   4816 
   4817 #define SHIFT 2
   4818 #include "softmmu_template.h"
   4819 
   4820 #define SHIFT 3
   4821 #include "softmmu_template.h"
   4822 
   4823 #endif
   4824 
   4825 #if !defined(CONFIG_USER_ONLY)
   4826 /* try to fill the TLB and return an exception if error. If retaddr is
   4827    NULL, it means that the function was called in C code (i.e. not
   4828    from generated code or from helper.c) */
   4829 /* XXX: fix it to restore all registers */
   4830 void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
   4831 {
   4832     TranslationBlock *tb;
   4833     int ret;
   4834     unsigned long pc;
   4835     CPUX86State *saved_env;
   4836 
   4837     /* XXX: hack to restore env in all cases, even if not called from
   4838        generated code */
   4839     saved_env = env;
   4840     env = cpu_single_env;
   4841 
   4842     ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
   4843     if (ret) {
   4844         if (retaddr) {
   4845             /* now we have a real cpu fault */
   4846             pc = (unsigned long)retaddr;
   4847             tb = tb_find_pc(pc);
   4848             if (tb) {
   4849                 /* the PC is inside the translated code. It means that we have
   4850                    a virtual CPU fault */
   4851                 cpu_restore_state(tb, env, pc);
   4852             }
   4853         }
   4854         raise_exception_err(env->exception_index, env->error_code);
   4855     }
   4856     env = saved_env;
   4857 }
   4858 #endif
   4859 
   4860 /* Secure Virtual Machine helpers */
   4861 
   4862 #if defined(CONFIG_USER_ONLY)
   4863 
   4864 void helper_vmrun(int aflag, int next_eip_addend)
   4865 {
   4866 }
   4867 void helper_vmmcall(void)
   4868 {
   4869 }
   4870 void helper_vmload(int aflag)
   4871 {
   4872 }
   4873 void helper_vmsave(int aflag)
   4874 {
   4875 }
   4876 void helper_stgi(void)
   4877 {
   4878 }
   4879 void helper_clgi(void)
   4880 {
   4881 }
   4882 void helper_skinit(void)
   4883 {
   4884 }
   4885 void helper_invlpga(int aflag)
   4886 {
   4887 }
   4888 void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
   4889 {
   4890 }
   4891 void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
   4892 {
   4893 }
   4894 
   4895 void helper_svm_check_io(uint32_t port, uint32_t param,
   4896                          uint32_t next_eip_addend)
   4897 {
   4898 }
   4899 #else
   4900 
   4901 static inline void svm_save_seg(target_phys_addr_t addr,
   4902                                 const SegmentCache *sc)
   4903 {
   4904     stw_phys(addr + offsetof(struct vmcb_seg, selector),
   4905              sc->selector);
   4906     stq_phys(addr + offsetof(struct vmcb_seg, base),
   4907              sc->base);
   4908     stl_phys(addr + offsetof(struct vmcb_seg, limit),
   4909              sc->limit);
   4910     stw_phys(addr + offsetof(struct vmcb_seg, attrib),
   4911              ((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00));
   4912 }
   4913 
   4914 static inline void svm_load_seg(target_phys_addr_t addr, SegmentCache *sc)
   4915 {
   4916     unsigned int flags;
   4917 
   4918     sc->selector = lduw_phys(addr + offsetof(struct vmcb_seg, selector));
   4919     sc->base = ldq_phys(addr + offsetof(struct vmcb_seg, base));
   4920     sc->limit = ldl_phys(addr + offsetof(struct vmcb_seg, limit));
   4921     flags = lduw_phys(addr + offsetof(struct vmcb_seg, attrib));
   4922     sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
   4923 }
   4924 
   4925 static inline void svm_load_seg_cache(target_phys_addr_t addr,
   4926                                       CPUState *env, int seg_reg)
   4927 {
   4928     SegmentCache sc1, *sc = &sc1;
   4929     svm_load_seg(addr, sc);
   4930     cpu_x86_load_seg_cache(env, seg_reg, sc->selector,
   4931                            sc->base, sc->limit, sc->flags);
   4932 }
   4933 
   4934 void helper_vmrun(int aflag, int next_eip_addend)
   4935 {
   4936     target_ulong addr;
   4937     uint32_t event_inj;
   4938     uint32_t int_ctl;
   4939 
   4940     helper_svm_check_intercept_param(SVM_EXIT_VMRUN, 0);
   4941 
   4942     if (aflag == 2)
   4943         addr = EAX;
   4944     else
   4945         addr = (uint32_t)EAX;
   4946 
   4947     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr);
   4948 
   4949     env->vm_vmcb = addr;
   4950 
   4951     /* save the current CPU state in the hsave page */
   4952     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base);
   4953     stl_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit), env->gdt.limit);
   4954 
   4955     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.base), env->idt.base);
   4956     stl_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.limit), env->idt.limit);
   4957 
   4958     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0), env->cr[0]);
   4959     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]);
   4960     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]);
   4961     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]);
   4962     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]);
   4963     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]);
   4964 
   4965     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer), env->efer);
   4966     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags), compute_eflags());
   4967 
   4968     svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.es),
   4969                   &env->segs[R_ES]);
   4970     svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.cs),
   4971                  &env->segs[R_CS]);
   4972     svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ss),
   4973                  &env->segs[R_SS]);
   4974     svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ds),
   4975                  &env->segs[R_DS]);
   4976 
   4977     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip),
   4978              EIP + next_eip_addend);
   4979     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP);
   4980     stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX);
   4981 
   4982     /* load the interception bitmaps so we do not need to access the
   4983        vmcb in svm mode */
   4984     env->intercept            = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept));
   4985     env->intercept_cr_read    = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_cr_read));
   4986     env->intercept_cr_write   = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_cr_write));
   4987     env->intercept_dr_read    = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_dr_read));
   4988     env->intercept_dr_write   = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_dr_write));
   4989     env->intercept_exceptions = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_exceptions));
   4990 
   4991     /* enable intercepts */
   4992     env->hflags |= HF_SVMI_MASK;
   4993 
   4994     env->tsc_offset = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.tsc_offset));
   4995 
   4996     env->gdt.base  = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base));
   4997     env->gdt.limit = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit));
   4998 
   4999     env->idt.base  = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.base));
   5000     env->idt.limit = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit));
   5001 
   5002     /* clear exit_info_2 so we behave like the real hardware */
   5003     stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
   5004 
   5005     cpu_x86_update_cr0(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr0)));
   5006     cpu_x86_update_cr4(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4)));
   5007     cpu_x86_update_cr3(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3)));
   5008     env->cr[2] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2));
   5009     int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
   5010     env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
   5011     if (int_ctl & V_INTR_MASKING_MASK) {
   5012         env->v_tpr = int_ctl & V_TPR_MASK;
   5013         env->hflags2 |= HF2_VINTR_MASK;
   5014         if (env->eflags & IF_MASK)
   5015             env->hflags2 |= HF2_HIF_MASK;
   5016     }
   5017 
   5018     cpu_load_efer(env,
   5019                   ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer)));
   5020     env->eflags = 0;
   5021     load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)),
   5022                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
   5023     CC_OP = CC_OP_EFLAGS;
   5024 
   5025     svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.es),
   5026                        env, R_ES);
   5027     svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.cs),
   5028                        env, R_CS);
   5029     svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.ss),
   5030                        env, R_SS);
   5031     svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.ds),
   5032                        env, R_DS);
   5033 
   5034     EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
   5035     env->eip = EIP;
   5036     ESP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));
   5037     EAX = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));
   5038     env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7));
   5039     env->dr[6] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6));
   5040     cpu_x86_set_cpl(env, ldub_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl)));
   5041 
   5042     /* FIXME: guest state consistency checks */
   5043 
   5044     switch(ldub_phys(env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {
   5045         case TLB_CONTROL_DO_NOTHING:
   5046             break;
   5047         case TLB_CONTROL_FLUSH_ALL_ASID:
   5048             /* FIXME: this is not 100% correct but should work for now */
   5049             tlb_flush(env, 1);
   5050         break;
   5051     }
   5052 
   5053     env->hflags2 |= HF2_GIF_MASK;
   5054 
   5055     if (int_ctl & V_IRQ_MASK) {
   5056         env->interrupt_request |= CPU_INTERRUPT_VIRQ;
   5057     }
   5058 
   5059     /* maybe we need to inject an event */
   5060     event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
   5061     if (event_inj & SVM_EVTINJ_VALID) {
   5062         uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK;
   5063         uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR;
   5064         uint32_t event_inj_err = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err));
   5065 
   5066         qemu_log_mask(CPU_LOG_TB_IN_ASM, "Injecting(%#hx): ", valid_err);
   5067         /* FIXME: need to implement valid_err */
   5068         switch (event_inj & SVM_EVTINJ_TYPE_MASK) {
   5069         case SVM_EVTINJ_TYPE_INTR:
   5070                 env->exception_index = vector;
   5071                 env->error_code = event_inj_err;
   5072                 env->exception_is_int = 0;
   5073                 env->exception_next_eip = -1;
   5074                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
   5075                 /* XXX: is it always correct ? */
   5076                 do_interrupt(vector, 0, 0, 0, 1);
   5077                 break;
   5078         case SVM_EVTINJ_TYPE_NMI:
   5079                 env->exception_index = EXCP02_NMI;
   5080                 env->error_code = event_inj_err;
   5081                 env->exception_is_int = 0;
   5082                 env->exception_next_eip = EIP;
   5083                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
   5084                 cpu_loop_exit();
   5085                 break;
   5086         case SVM_EVTINJ_TYPE_EXEPT:
   5087                 env->exception_index = vector;
   5088                 env->error_code = event_inj_err;
   5089                 env->exception_is_int = 0;
   5090                 env->exception_next_eip = -1;
   5091                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT");
   5092                 cpu_loop_exit();
   5093                 break;
   5094         case SVM_EVTINJ_TYPE_SOFT:
   5095                 env->exception_index = vector;
   5096                 env->error_code = event_inj_err;
   5097                 env->exception_is_int = 1;
   5098                 env->exception_next_eip = EIP;
   5099                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
   5100                 cpu_loop_exit();
   5101                 break;
   5102         }
   5103         qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index, env->error_code);
   5104     }
   5105 }
   5106 
   5107 void helper_vmmcall(void)
   5108 {
   5109     helper_svm_check_intercept_param(SVM_EXIT_VMMCALL, 0);
   5110     raise_exception(EXCP06_ILLOP);
   5111 }
   5112 
   5113 void helper_vmload(int aflag)
   5114 {
   5115     target_ulong addr;
   5116     helper_svm_check_intercept_param(SVM_EXIT_VMLOAD, 0);
   5117 
   5118     if (aflag == 2)
   5119         addr = EAX;
   5120     else
   5121         addr = (uint32_t)EAX;
   5122 
   5123     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
   5124                 addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)),
   5125                 env->segs[R_FS].base);
   5126 
   5127     svm_load_seg_cache(addr + offsetof(struct vmcb, save.fs),
   5128                        env, R_FS);
   5129     svm_load_seg_cache(addr + offsetof(struct vmcb, save.gs),
   5130                        env, R_GS);
   5131     svm_load_seg(addr + offsetof(struct vmcb, save.tr),
   5132                  &env->tr);
   5133     svm_load_seg(addr + offsetof(struct vmcb, save.ldtr),
   5134                  &env->ldt);
   5135 
   5136 #ifdef TARGET_X86_64
   5137     env->kernelgsbase = ldq_phys(addr + offsetof(struct vmcb, save.kernel_gs_base));
   5138     env->lstar = ldq_phys(addr + offsetof(struct vmcb, save.lstar));
   5139     env->cstar = ldq_phys(addr + offsetof(struct vmcb, save.cstar));
   5140     env->fmask = ldq_phys(addr + offsetof(struct vmcb, save.sfmask));
   5141 #endif
   5142     env->star = ldq_phys(addr + offsetof(struct vmcb, save.star));
   5143     env->sysenter_cs = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_cs));
   5144     env->sysenter_esp = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_esp));
   5145     env->sysenter_eip = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_eip));
   5146 }
   5147 
   5148 void helper_vmsave(int aflag)
   5149 {
   5150     target_ulong addr;
   5151     helper_svm_check_intercept_param(SVM_EXIT_VMSAVE, 0);
   5152 
   5153     if (aflag == 2)
   5154         addr = EAX;
   5155     else
   5156         addr = (uint32_t)EAX;
   5157 
   5158     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
   5159                 addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)),
   5160                 env->segs[R_FS].base);
   5161 
   5162     svm_save_seg(addr + offsetof(struct vmcb, save.fs),
   5163                  &env->segs[R_FS]);
   5164     svm_save_seg(addr + offsetof(struct vmcb, save.gs),
   5165                  &env->segs[R_GS]);
   5166     svm_save_seg(addr + offsetof(struct vmcb, save.tr),
   5167                  &env->tr);
   5168     svm_save_seg(addr + offsetof(struct vmcb, save.ldtr),
   5169                  &env->ldt);
   5170 
   5171 #ifdef TARGET_X86_64
   5172     stq_phys(addr + offsetof(struct vmcb, save.kernel_gs_base), env->kernelgsbase);
   5173     stq_phys(addr + offsetof(struct vmcb, save.lstar), env->lstar);
   5174     stq_phys(addr + offsetof(struct vmcb, save.cstar), env->cstar);
   5175     stq_phys(addr + offsetof(struct vmcb, save.sfmask), env->fmask);
   5176 #endif
   5177     stq_phys(addr + offsetof(struct vmcb, save.star), env->star);
   5178     stq_phys(addr + offsetof(struct vmcb, save.sysenter_cs), env->sysenter_cs);
   5179     stq_phys(addr + offsetof(struct vmcb, save.sysenter_esp), env->sysenter_esp);
   5180     stq_phys(addr + offsetof(struct vmcb, save.sysenter_eip), env->sysenter_eip);
   5181 }
   5182 
   5183 void helper_stgi(void)
   5184 {
   5185     helper_svm_check_intercept_param(SVM_EXIT_STGI, 0);
   5186     env->hflags2 |= HF2_GIF_MASK;
   5187 }
   5188 
   5189 void helper_clgi(void)
   5190 {
   5191     helper_svm_check_intercept_param(SVM_EXIT_CLGI, 0);
   5192     env->hflags2 &= ~HF2_GIF_MASK;
   5193 }
   5194 
   5195 void helper_skinit(void)
   5196 {
   5197     helper_svm_check_intercept_param(SVM_EXIT_SKINIT, 0);
   5198     /* XXX: not implemented */
   5199     raise_exception(EXCP06_ILLOP);
   5200 }
   5201 
   5202 void helper_invlpga(int aflag)
   5203 {
   5204     target_ulong addr;
   5205     helper_svm_check_intercept_param(SVM_EXIT_INVLPGA, 0);
   5206 
   5207     if (aflag == 2)
   5208         addr = EAX;
   5209     else
   5210         addr = (uint32_t)EAX;
   5211 
   5212     /* XXX: could use the ASID to see if it is needed to do the
   5213        flush */
   5214     tlb_flush_page(env, addr);
   5215 }
   5216 
   5217 void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
   5218 {
   5219     if (likely(!(env->hflags & HF_SVMI_MASK)))
   5220         return;
   5221     switch(type) {
   5222     case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
   5223         if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
   5224             helper_vmexit(type, param);
   5225         }
   5226         break;
   5227     case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
   5228         if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
   5229             helper_vmexit(type, param);
   5230         }
   5231         break;
   5232     case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
   5233         if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
   5234             helper_vmexit(type, param);
   5235         }
   5236         break;
   5237     case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
   5238         if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
   5239             helper_vmexit(type, param);
   5240         }
   5241         break;
   5242     case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
   5243         if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
   5244             helper_vmexit(type, param);
   5245         }
   5246         break;
   5247     case SVM_EXIT_MSR:
   5248         if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) {
   5249             /* FIXME: this should be read in at vmrun (faster this way?) */
   5250             uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa));
   5251             uint32_t t0, t1;
   5252             switch((uint32_t)ECX) {
   5253             case 0 ... 0x1fff:
   5254                 t0 = (ECX * 2) % 8;
   5255                 t1 = ECX / 8;
   5256                 break;
   5257             case 0xc0000000 ... 0xc0001fff:
   5258                 t0 = (8192 + ECX - 0xc0000000) * 2;
   5259                 t1 = (t0 / 8);
   5260                 t0 %= 8;
   5261                 break;
   5262             case 0xc0010000 ... 0xc0011fff:
   5263                 t0 = (16384 + ECX - 0xc0010000) * 2;
   5264                 t1 = (t0 / 8);
   5265                 t0 %= 8;
   5266                 break;
   5267             default:
   5268                 helper_vmexit(type, param);
   5269                 t0 = 0;
   5270                 t1 = 0;
   5271                 break;
   5272             }
   5273             if (ldub_phys(addr + t1) & ((1 << param) << t0))
   5274                 helper_vmexit(type, param);
   5275         }
   5276         break;
   5277     default:
   5278         if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
   5279             helper_vmexit(type, param);
   5280         }
   5281         break;
   5282     }
   5283 }
   5284 
   5285 void helper_svm_check_io(uint32_t port, uint32_t param,
   5286                          uint32_t next_eip_addend)
   5287 {
   5288     if (env->intercept & (1ULL << (SVM_EXIT_IOIO - SVM_EXIT_INTR))) {
   5289         /* FIXME: this should be read in at vmrun (faster this way?) */
   5290         uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
   5291         uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
   5292         if(lduw_phys(addr + port / 8) & (mask << (port & 7))) {
   5293             /* next EIP */
   5294             stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
   5295                      env->eip + next_eip_addend);
   5296             helper_vmexit(SVM_EXIT_IOIO, param | (port << 16));
   5297         }
   5298     }
   5299 }
   5300 
   5301 /* Note: currently only 32 bits of exit_code are used */
   5302 void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
   5303 {
   5304     uint32_t int_ctl;
   5305 
   5306     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n",
   5307                 exit_code, exit_info_1,
   5308                 ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)),
   5309                 EIP);
   5310 
   5311     if(env->hflags & HF_INHIBIT_IRQ_MASK) {
   5312         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), SVM_INTERRUPT_SHADOW_MASK);
   5313         env->hflags &= ~HF_INHIBIT_IRQ_MASK;
   5314     } else {
   5315         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0);
   5316     }
   5317 
   5318     /* Save the VM state in the vmcb */
   5319     svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.es),
   5320                  &env->segs[R_ES]);
   5321     svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.cs),
   5322                  &env->segs[R_CS]);
   5323     svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.ss),
   5324                  &env->segs[R_SS]);
   5325     svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.ds),
   5326                  &env->segs[R_DS]);
   5327 
   5328     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base), env->gdt.base);
   5329     stl_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit), env->gdt.limit);
   5330 
   5331     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.base), env->idt.base);
   5332     stl_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit), env->idt.limit);
   5333 
   5334     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer), env->efer);
   5335     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr0), env->cr[0]);
   5336     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2), env->cr[2]);
   5337     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
   5338     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
   5339 
   5340     int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
   5341     int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
   5342     int_ctl |= env->v_tpr & V_TPR_MASK;
   5343     if (env->interrupt_request & CPU_INTERRUPT_VIRQ)
   5344         int_ctl |= V_IRQ_MASK;
   5345     stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);
   5346 
   5347     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags), compute_eflags());
   5348     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip), env->eip);
   5349     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), ESP);
   5350     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), EAX);
   5351     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]);
   5352     stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]);
   5353     stb_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl), env->hflags & HF_CPL_MASK);
   5354 
   5355     /* Reload the host state from vm_hsave */
   5356     env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
   5357     env->hflags &= ~HF_SVMI_MASK;
   5358     env->intercept = 0;
   5359     env->intercept_exceptions = 0;
   5360     env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
   5361     env->tsc_offset = 0;
   5362 
   5363     env->gdt.base  = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base));
   5364     env->gdt.limit = ldl_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit));
   5365 
   5366     env->idt.base  = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.base));
   5367     env->idt.limit = ldl_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.limit));
   5368 
   5369     cpu_x86_update_cr0(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0)) | CR0_PE_MASK);
   5370     cpu_x86_update_cr4(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4)));
   5371     cpu_x86_update_cr3(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3)));
   5372     /* we need to set the efer after the crs so the hidden flags get
   5373        set properly */
   5374     cpu_load_efer(env,
   5375                   ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer)));
   5376     env->eflags = 0;
   5377     load_eflags(ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags)),
   5378                 ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
   5379     CC_OP = CC_OP_EFLAGS;
   5380 
   5381     svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.es),
   5382                        env, R_ES);
   5383     svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.cs),
   5384                        env, R_CS);
   5385     svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.ss),
   5386                        env, R_SS);
   5387     svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.ds),
   5388                        env, R_DS);
   5389 
   5390     EIP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
   5391     ESP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp));
   5392     EAX = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax));
   5393 
   5394     env->dr[6] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6));
   5395     env->dr[7] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7));
   5396 
   5397     /* other setups */
   5398     cpu_x86_set_cpl(env, 0);
   5399     stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code);
   5400     stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1);
   5401 
   5402     stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info),
   5403              ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)));
   5404     stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err),
   5405              ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err)));
   5406 
   5407     env->hflags2 &= ~HF2_GIF_MASK;
   5408     /* FIXME: Resets the current ASID register to zero (host ASID). */
   5409 
   5410     /* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */
   5411 
   5412     /* Clears the TSC_OFFSET inside the processor. */
   5413 
   5414     /* If the host is in PAE mode, the processor reloads the host's PDPEs
   5415        from the page table indicated the host's CR3. If the PDPEs contain
   5416        illegal state, the processor causes a shutdown. */
   5417 
   5418     /* Forces CR0.PE = 1, RFLAGS.VM = 0. */
   5419     env->cr[0] |= CR0_PE_MASK;
   5420     env->eflags &= ~VM_MASK;
   5421 
   5422     /* Disables all breakpoints in the host DR7 register. */
   5423 
   5424     /* Checks the reloaded host state for consistency. */
   5425 
   5426     /* If the host's rIP reloaded by #VMEXIT is outside the limit of the
   5427        host's code segment or non-canonical (in the case of long mode), a
   5428        #GP fault is delivered inside the host.) */
   5429 
   5430     /* remove any pending exception */
   5431     env->exception_index = -1;
   5432     env->error_code = 0;
   5433     env->old_exception = -1;
   5434 
   5435     cpu_loop_exit();
   5436 }
   5437 
   5438 #endif
   5439 
   5440 /* MMX/SSE */
   5441 /* XXX: optimize by storing fptt and fptags in the static cpu state */
   5442 void helper_enter_mmx(void)
   5443 {
   5444     env->fpstt = 0;
   5445     *(uint32_t *)(env->fptags) = 0;
   5446     *(uint32_t *)(env->fptags + 4) = 0;
   5447 }
   5448 
   5449 void helper_emms(void)
   5450 {
   5451     /* set to empty state */
   5452     *(uint32_t *)(env->fptags) = 0x01010101;
   5453     *(uint32_t *)(env->fptags + 4) = 0x01010101;
   5454 }
   5455 
   5456 /* XXX: suppress */
   5457 void helper_movq(void *d, void *s)
   5458 {
   5459     *(uint64_t *)d = *(uint64_t *)s;
   5460 }
   5461 
   5462 #define SHIFT 0
   5463 #include "ops_sse.h"
   5464 
   5465 #define SHIFT 1
   5466 #include "ops_sse.h"
   5467 
   5468 #define SHIFT 0
   5469 #include "helper_template.h"
   5470 #undef SHIFT
   5471 
   5472 #define SHIFT 1
   5473 #include "helper_template.h"
   5474 #undef SHIFT
   5475 
   5476 #define SHIFT 2
   5477 #include "helper_template.h"
   5478 #undef SHIFT
   5479 
   5480 #ifdef TARGET_X86_64
   5481 
   5482 #define SHIFT 3
   5483 #include "helper_template.h"
   5484 #undef SHIFT
   5485 
   5486 #endif
   5487 
   5488 /* bit operations */
   5489 target_ulong helper_bsf(target_ulong t0)
   5490 {
   5491     int count;
   5492     target_ulong res;
   5493 
   5494     res = t0;
   5495     count = 0;
   5496     while ((res & 1) == 0) {
   5497         count++;
   5498         res >>= 1;
   5499     }
   5500     return count;
   5501 }
   5502 
   5503 target_ulong helper_bsr(target_ulong t0)
   5504 {
   5505     int count;
   5506     target_ulong res, mask;
   5507 
   5508     res = t0;
   5509     count = TARGET_LONG_BITS - 1;
   5510     mask = (target_ulong)1 << (TARGET_LONG_BITS - 1);
   5511     while ((res & mask) == 0) {
   5512         count--;
   5513         res <<= 1;
   5514     }
   5515     return count;
   5516 }
   5517 
   5518 
   5519 static int compute_all_eflags(void)
   5520 {
   5521     return CC_SRC;
   5522 }
   5523 
   5524 static int compute_c_eflags(void)
   5525 {
   5526     return CC_SRC & CC_C;
   5527 }
   5528 
   5529 uint32_t helper_cc_compute_all(int op)
   5530 {
   5531     switch (op) {
   5532     default: /* should never happen */ return 0;
   5533 
   5534     case CC_OP_EFLAGS: return compute_all_eflags();
   5535 
   5536     case CC_OP_MULB: return compute_all_mulb();
   5537     case CC_OP_MULW: return compute_all_mulw();
   5538     case CC_OP_MULL: return compute_all_mull();
   5539 
   5540     case CC_OP_ADDB: return compute_all_addb();
   5541     case CC_OP_ADDW: return compute_all_addw();
   5542     case CC_OP_ADDL: return compute_all_addl();
   5543 
   5544     case CC_OP_ADCB: return compute_all_adcb();
   5545     case CC_OP_ADCW: return compute_all_adcw();
   5546     case CC_OP_ADCL: return compute_all_adcl();
   5547 
   5548     case CC_OP_SUBB: return compute_all_subb();
   5549     case CC_OP_SUBW: return compute_all_subw();
   5550     case CC_OP_SUBL: return compute_all_subl();
   5551 
   5552     case CC_OP_SBBB: return compute_all_sbbb();
   5553     case CC_OP_SBBW: return compute_all_sbbw();
   5554     case CC_OP_SBBL: return compute_all_sbbl();
   5555 
   5556     case CC_OP_LOGICB: return compute_all_logicb();
   5557     case CC_OP_LOGICW: return compute_all_logicw();
   5558     case CC_OP_LOGICL: return compute_all_logicl();
   5559 
   5560     case CC_OP_INCB: return compute_all_incb();
   5561     case CC_OP_INCW: return compute_all_incw();
   5562     case CC_OP_INCL: return compute_all_incl();
   5563 
   5564     case CC_OP_DECB: return compute_all_decb();
   5565     case CC_OP_DECW: return compute_all_decw();
   5566     case CC_OP_DECL: return compute_all_decl();
   5567 
   5568     case CC_OP_SHLB: return compute_all_shlb();
   5569     case CC_OP_SHLW: return compute_all_shlw();
   5570     case CC_OP_SHLL: return compute_all_shll();
   5571 
   5572     case CC_OP_SARB: return compute_all_sarb();
   5573     case CC_OP_SARW: return compute_all_sarw();
   5574     case CC_OP_SARL: return compute_all_sarl();
   5575 
   5576 #ifdef TARGET_X86_64
   5577     case CC_OP_MULQ: return compute_all_mulq();
   5578 
   5579     case CC_OP_ADDQ: return compute_all_addq();
   5580 
   5581     case CC_OP_ADCQ: return compute_all_adcq();
   5582 
   5583     case CC_OP_SUBQ: return compute_all_subq();
   5584 
   5585     case CC_OP_SBBQ: return compute_all_sbbq();
   5586 
   5587     case CC_OP_LOGICQ: return compute_all_logicq();
   5588 
   5589     case CC_OP_INCQ: return compute_all_incq();
   5590 
   5591     case CC_OP_DECQ: return compute_all_decq();
   5592 
   5593     case CC_OP_SHLQ: return compute_all_shlq();
   5594 
   5595     case CC_OP_SARQ: return compute_all_sarq();
   5596 #endif
   5597     }
   5598 }
   5599 
   5600 uint32_t helper_cc_compute_c(int op)
   5601 {
   5602     switch (op) {
   5603     default: /* should never happen */ return 0;
   5604 
   5605     case CC_OP_EFLAGS: return compute_c_eflags();
   5606 
   5607     case CC_OP_MULB: return compute_c_mull();
   5608     case CC_OP_MULW: return compute_c_mull();
   5609     case CC_OP_MULL: return compute_c_mull();
   5610 
   5611     case CC_OP_ADDB: return compute_c_addb();
   5612     case CC_OP_ADDW: return compute_c_addw();
   5613     case CC_OP_ADDL: return compute_c_addl();
   5614 
   5615     case CC_OP_ADCB: return compute_c_adcb();
   5616     case CC_OP_ADCW: return compute_c_adcw();
   5617     case CC_OP_ADCL: return compute_c_adcl();
   5618 
   5619     case CC_OP_SUBB: return compute_c_subb();
   5620     case CC_OP_SUBW: return compute_c_subw();
   5621     case CC_OP_SUBL: return compute_c_subl();
   5622 
   5623     case CC_OP_SBBB: return compute_c_sbbb();
   5624     case CC_OP_SBBW: return compute_c_sbbw();
   5625     case CC_OP_SBBL: return compute_c_sbbl();
   5626 
   5627     case CC_OP_LOGICB: return compute_c_logicb();
   5628     case CC_OP_LOGICW: return compute_c_logicw();
   5629     case CC_OP_LOGICL: return compute_c_logicl();
   5630 
   5631     case CC_OP_INCB: return compute_c_incl();
   5632     case CC_OP_INCW: return compute_c_incl();
   5633     case CC_OP_INCL: return compute_c_incl();
   5634 
   5635     case CC_OP_DECB: return compute_c_incl();
   5636     case CC_OP_DECW: return compute_c_incl();
   5637     case CC_OP_DECL: return compute_c_incl();
   5638 
   5639     case CC_OP_SHLB: return compute_c_shlb();
   5640     case CC_OP_SHLW: return compute_c_shlw();
   5641     case CC_OP_SHLL: return compute_c_shll();
   5642 
   5643     case CC_OP_SARB: return compute_c_sarl();
   5644     case CC_OP_SARW: return compute_c_sarl();
   5645     case CC_OP_SARL: return compute_c_sarl();
   5646 
   5647 #ifdef TARGET_X86_64
   5648     case CC_OP_MULQ: return compute_c_mull();
   5649 
   5650     case CC_OP_ADDQ: return compute_c_addq();
   5651 
   5652     case CC_OP_ADCQ: return compute_c_adcq();
   5653 
   5654     case CC_OP_SUBQ: return compute_c_subq();
   5655 
   5656     case CC_OP_SBBQ: return compute_c_sbbq();
   5657 
   5658     case CC_OP_LOGICQ: return compute_c_logicq();
   5659 
   5660     case CC_OP_INCQ: return compute_c_incl();
   5661 
   5662     case CC_OP_DECQ: return compute_c_incl();
   5663 
   5664     case CC_OP_SHLQ: return compute_c_shlq();
   5665 
   5666     case CC_OP_SARQ: return compute_c_sarl();
   5667 #endif
   5668     }
   5669 }
   5670