Home | History | Annotate | Download | only in target-i386
      1 /*
      2  *  x86 condition code 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 
     21 #include "cpu.h"
     22 #include "helper.h"
     23 
     24 const uint8_t parity_table[256] = {
     25     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     26     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     27     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     28     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     29     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     30     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     31     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     32     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     33     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     34     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     35     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     36     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     37     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     38     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     39     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     40     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     41     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     42     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     43     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     44     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     45     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     46     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     47     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     48     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     49     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     50     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     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     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     54     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     55     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     56     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     57 };
     58 
     59 #define SHIFT 0
     60 #include "cc_helper_template.h"
     61 #undef SHIFT
     62 
     63 #define SHIFT 1
     64 #include "cc_helper_template.h"
     65 #undef SHIFT
     66 
     67 #define SHIFT 2
     68 #include "cc_helper_template.h"
     69 #undef SHIFT
     70 
     71 #ifdef TARGET_X86_64
     72 #define SHIFT 3
     73 #include "cc_helper_template.h"
     74 #undef SHIFT
     75 #endif
     76 
     77 static int compute_all_eflags(CPUX86State *env)
     78 {
     79     return CC_SRC;
     80 }
     81 
     82 static int compute_c_eflags(CPUX86State *env)
     83 {
     84     return CC_SRC & CC_C;
     85 }
     86 
     87 uint32_t helper_cc_compute_all(CPUX86State *env, int op)
     88 {
     89     switch (op) {
     90     default: /* should never happen */ return 0;
     91 
     92     case CC_OP_EFLAGS: return compute_all_eflags(env);
     93 
     94     case CC_OP_MULB: return compute_all_mulb(env);
     95     case CC_OP_MULW: return compute_all_mulw(env);
     96     case CC_OP_MULL: return compute_all_mull(env);
     97 
     98     case CC_OP_ADDB: return compute_all_addb(env);
     99     case CC_OP_ADDW: return compute_all_addw(env);
    100     case CC_OP_ADDL: return compute_all_addl(env);
    101 
    102     case CC_OP_ADCB: return compute_all_adcb(env);
    103     case CC_OP_ADCW: return compute_all_adcw(env);
    104     case CC_OP_ADCL: return compute_all_adcl(env);
    105 
    106     case CC_OP_SUBB: return compute_all_subb(env);
    107     case CC_OP_SUBW: return compute_all_subw(env);
    108     case CC_OP_SUBL: return compute_all_subl(env);
    109 
    110     case CC_OP_SBBB: return compute_all_sbbb(env);
    111     case CC_OP_SBBW: return compute_all_sbbw(env);
    112     case CC_OP_SBBL: return compute_all_sbbl(env);
    113 
    114     case CC_OP_LOGICB: return compute_all_logicb(env);
    115     case CC_OP_LOGICW: return compute_all_logicw(env);
    116     case CC_OP_LOGICL: return compute_all_logicl(env);
    117 
    118     case CC_OP_INCB: return compute_all_incb(env);
    119     case CC_OP_INCW: return compute_all_incw(env);
    120     case CC_OP_INCL: return compute_all_incl(env);
    121 
    122     case CC_OP_DECB: return compute_all_decb(env);
    123     case CC_OP_DECW: return compute_all_decw(env);
    124     case CC_OP_DECL: return compute_all_decl(env);
    125 
    126     case CC_OP_SHLB: return compute_all_shlb(env);
    127     case CC_OP_SHLW: return compute_all_shlw(env);
    128     case CC_OP_SHLL: return compute_all_shll(env);
    129 
    130     case CC_OP_SARB: return compute_all_sarb(env);
    131     case CC_OP_SARW: return compute_all_sarw(env);
    132     case CC_OP_SARL: return compute_all_sarl(env);
    133 
    134 #ifdef TARGET_X86_64
    135     case CC_OP_MULQ: return compute_all_mulq(env);
    136 
    137     case CC_OP_ADDQ: return compute_all_addq(env);
    138 
    139     case CC_OP_ADCQ: return compute_all_adcq(env);
    140 
    141     case CC_OP_SUBQ: return compute_all_subq(env);
    142 
    143     case CC_OP_SBBQ: return compute_all_sbbq(env);
    144 
    145     case CC_OP_LOGICQ: return compute_all_logicq(env);
    146 
    147     case CC_OP_INCQ: return compute_all_incq(env);
    148 
    149     case CC_OP_DECQ: return compute_all_decq(env);
    150 
    151     case CC_OP_SHLQ: return compute_all_shlq(env);
    152 
    153     case CC_OP_SARQ: return compute_all_sarq(env);
    154 #endif
    155     }
    156 }
    157 
    158 uint32_t cpu_cc_compute_all(CPUArchState *env1, int op)
    159 {
    160     return helper_cc_compute_all(env1, op);
    161 }
    162 
    163 uint32_t helper_cc_compute_c(CPUX86State *env, int op)
    164 {
    165     switch (op) {
    166     default: /* should never happen */ return 0;
    167 
    168     case CC_OP_EFLAGS: return compute_c_eflags(env);
    169 
    170     case CC_OP_MULB: return compute_c_mull(env);
    171     case CC_OP_MULW: return compute_c_mull(env);
    172     case CC_OP_MULL: return compute_c_mull(env);
    173 
    174     case CC_OP_ADDB: return compute_c_addb(env);
    175     case CC_OP_ADDW: return compute_c_addw(env);
    176     case CC_OP_ADDL: return compute_c_addl(env);
    177 
    178     case CC_OP_ADCB: return compute_c_adcb(env);
    179     case CC_OP_ADCW: return compute_c_adcw(env);
    180     case CC_OP_ADCL: return compute_c_adcl(env);
    181 
    182     case CC_OP_SUBB: return compute_c_subb(env);
    183     case CC_OP_SUBW: return compute_c_subw(env);
    184     case CC_OP_SUBL: return compute_c_subl(env);
    185 
    186     case CC_OP_SBBB: return compute_c_sbbb(env);
    187     case CC_OP_SBBW: return compute_c_sbbw(env);
    188     case CC_OP_SBBL: return compute_c_sbbl(env);
    189 
    190     case CC_OP_LOGICB: return compute_c_logicb(env);
    191     case CC_OP_LOGICW: return compute_c_logicw(env);
    192     case CC_OP_LOGICL: return compute_c_logicl(env);
    193 
    194     case CC_OP_INCB: return compute_c_incl(env);
    195     case CC_OP_INCW: return compute_c_incl(env);
    196     case CC_OP_INCL: return compute_c_incl(env);
    197 
    198     case CC_OP_DECB: return compute_c_incl(env);
    199     case CC_OP_DECW: return compute_c_incl(env);
    200     case CC_OP_DECL: return compute_c_incl(env);
    201 
    202     case CC_OP_SHLB: return compute_c_shlb(env);
    203     case CC_OP_SHLW: return compute_c_shlw(env);
    204     case CC_OP_SHLL: return compute_c_shll(env);
    205 
    206     case CC_OP_SARB: return compute_c_sarl(env);
    207     case CC_OP_SARW: return compute_c_sarl(env);
    208     case CC_OP_SARL: return compute_c_sarl(env);
    209 
    210 #ifdef TARGET_X86_64
    211     case CC_OP_MULQ: return compute_c_mull(env);
    212 
    213     case CC_OP_ADDQ: return compute_c_addq(env);
    214 
    215     case CC_OP_ADCQ: return compute_c_adcq(env);
    216 
    217     case CC_OP_SUBQ: return compute_c_subq(env);
    218 
    219     case CC_OP_SBBQ: return compute_c_sbbq(env);
    220 
    221     case CC_OP_LOGICQ: return compute_c_logicq(env);
    222 
    223     case CC_OP_INCQ: return compute_c_incl(env);
    224 
    225     case CC_OP_DECQ: return compute_c_incl(env);
    226 
    227     case CC_OP_SHLQ: return compute_c_shlq(env);
    228 
    229     case CC_OP_SARQ: return compute_c_sarl(env);
    230 #endif
    231     }
    232 }
    233 
    234 void helper_write_eflags(CPUX86State *env,
    235                          target_ulong t0, uint32_t update_mask)
    236 {
    237     cpu_load_eflags(env, t0, update_mask);
    238 }
    239 
    240 target_ulong helper_read_eflags(CPUX86State *env)
    241 {
    242     uint32_t eflags;
    243     eflags = helper_cc_compute_all(env, CC_OP);
    244     eflags |= (DF & DF_MASK);
    245     eflags |= env->eflags & ~(VM_MASK | RF_MASK);
    246     return eflags;
    247 }
    248 
    249 void helper_clts(CPUX86State *env)
    250 {
    251     env->cr[0] &= ~CR0_TS_MASK;
    252     env->hflags &= ~HF_TS_MASK;
    253 }
    254 
    255 void helper_reset_rf(CPUX86State *env)
    256 {
    257     env->eflags &= ~RF_MASK;
    258 }
    259 
    260 void helper_cli(CPUX86State *env)
    261 {
    262     env->eflags &= ~IF_MASK;
    263 }
    264 
    265 void helper_sti(CPUX86State *env)
    266 {
    267     env->eflags |= IF_MASK;
    268 }
    269 
    270 void helper_set_inhibit_irq(CPUX86State *env)
    271 {
    272     env->hflags |= HF_INHIBIT_IRQ_MASK;
    273 }
    274 
    275 void helper_reset_inhibit_irq(CPUX86State *env)
    276 {
    277     env->hflags &= ~HF_INHIBIT_IRQ_MASK;
    278 }
    279