qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

cc_helper.c (9657B)


      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.1 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Lesser General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Lesser General Public
     17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18  */
     19 
     20 #include "qemu/osdep.h"
     21 #include "cpu.h"
     22 #include "exec/helper-proto.h"
     23 #include "helper-tcg.h"
     24 
     25 const uint8_t parity_table[256] = {
     26     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     27     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     28     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     29     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     30     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     31     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     32     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     33     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     34     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     35     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     36     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     37     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     38     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     39     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     40     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     41     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     42     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     43     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     44     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     45     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     46     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     47     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     48     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     49     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     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     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     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     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     56     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
     57     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
     58 };
     59 
     60 #define SHIFT 0
     61 #include "cc_helper_template.h"
     62 #undef SHIFT
     63 
     64 #define SHIFT 1
     65 #include "cc_helper_template.h"
     66 #undef SHIFT
     67 
     68 #define SHIFT 2
     69 #include "cc_helper_template.h"
     70 #undef SHIFT
     71 
     72 #ifdef TARGET_X86_64
     73 
     74 #define SHIFT 3
     75 #include "cc_helper_template.h"
     76 #undef SHIFT
     77 
     78 #endif
     79 
     80 static target_ulong compute_all_adcx(target_ulong dst, target_ulong src1,
     81                                      target_ulong src2)
     82 {
     83     return (src1 & ~CC_C) | (dst * CC_C);
     84 }
     85 
     86 static target_ulong compute_all_adox(target_ulong dst, target_ulong src1,
     87                                      target_ulong src2)
     88 {
     89     return (src1 & ~CC_O) | (src2 * CC_O);
     90 }
     91 
     92 static target_ulong compute_all_adcox(target_ulong dst, target_ulong src1,
     93                                       target_ulong src2)
     94 {
     95     return (src1 & ~(CC_C | CC_O)) | (dst * CC_C) | (src2 * CC_O);
     96 }
     97 
     98 target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
     99                                    target_ulong src2, int op)
    100 {
    101     switch (op) {
    102     default: /* should never happen */
    103         return 0;
    104 
    105     case CC_OP_EFLAGS:
    106         return src1;
    107     case CC_OP_CLR:
    108         return CC_Z | CC_P;
    109     case CC_OP_POPCNT:
    110         return src1 ? 0 : CC_Z;
    111 
    112     case CC_OP_MULB:
    113         return compute_all_mulb(dst, src1);
    114     case CC_OP_MULW:
    115         return compute_all_mulw(dst, src1);
    116     case CC_OP_MULL:
    117         return compute_all_mull(dst, src1);
    118 
    119     case CC_OP_ADDB:
    120         return compute_all_addb(dst, src1);
    121     case CC_OP_ADDW:
    122         return compute_all_addw(dst, src1);
    123     case CC_OP_ADDL:
    124         return compute_all_addl(dst, src1);
    125 
    126     case CC_OP_ADCB:
    127         return compute_all_adcb(dst, src1, src2);
    128     case CC_OP_ADCW:
    129         return compute_all_adcw(dst, src1, src2);
    130     case CC_OP_ADCL:
    131         return compute_all_adcl(dst, src1, src2);
    132 
    133     case CC_OP_SUBB:
    134         return compute_all_subb(dst, src1);
    135     case CC_OP_SUBW:
    136         return compute_all_subw(dst, src1);
    137     case CC_OP_SUBL:
    138         return compute_all_subl(dst, src1);
    139 
    140     case CC_OP_SBBB:
    141         return compute_all_sbbb(dst, src1, src2);
    142     case CC_OP_SBBW:
    143         return compute_all_sbbw(dst, src1, src2);
    144     case CC_OP_SBBL:
    145         return compute_all_sbbl(dst, src1, src2);
    146 
    147     case CC_OP_LOGICB:
    148         return compute_all_logicb(dst, src1);
    149     case CC_OP_LOGICW:
    150         return compute_all_logicw(dst, src1);
    151     case CC_OP_LOGICL:
    152         return compute_all_logicl(dst, src1);
    153 
    154     case CC_OP_INCB:
    155         return compute_all_incb(dst, src1);
    156     case CC_OP_INCW:
    157         return compute_all_incw(dst, src1);
    158     case CC_OP_INCL:
    159         return compute_all_incl(dst, src1);
    160 
    161     case CC_OP_DECB:
    162         return compute_all_decb(dst, src1);
    163     case CC_OP_DECW:
    164         return compute_all_decw(dst, src1);
    165     case CC_OP_DECL:
    166         return compute_all_decl(dst, src1);
    167 
    168     case CC_OP_SHLB:
    169         return compute_all_shlb(dst, src1);
    170     case CC_OP_SHLW:
    171         return compute_all_shlw(dst, src1);
    172     case CC_OP_SHLL:
    173         return compute_all_shll(dst, src1);
    174 
    175     case CC_OP_SARB:
    176         return compute_all_sarb(dst, src1);
    177     case CC_OP_SARW:
    178         return compute_all_sarw(dst, src1);
    179     case CC_OP_SARL:
    180         return compute_all_sarl(dst, src1);
    181 
    182     case CC_OP_BMILGB:
    183         return compute_all_bmilgb(dst, src1);
    184     case CC_OP_BMILGW:
    185         return compute_all_bmilgw(dst, src1);
    186     case CC_OP_BMILGL:
    187         return compute_all_bmilgl(dst, src1);
    188 
    189     case CC_OP_ADCX:
    190         return compute_all_adcx(dst, src1, src2);
    191     case CC_OP_ADOX:
    192         return compute_all_adox(dst, src1, src2);
    193     case CC_OP_ADCOX:
    194         return compute_all_adcox(dst, src1, src2);
    195 
    196 #ifdef TARGET_X86_64
    197     case CC_OP_MULQ:
    198         return compute_all_mulq(dst, src1);
    199     case CC_OP_ADDQ:
    200         return compute_all_addq(dst, src1);
    201     case CC_OP_ADCQ:
    202         return compute_all_adcq(dst, src1, src2);
    203     case CC_OP_SUBQ:
    204         return compute_all_subq(dst, src1);
    205     case CC_OP_SBBQ:
    206         return compute_all_sbbq(dst, src1, src2);
    207     case CC_OP_LOGICQ:
    208         return compute_all_logicq(dst, src1);
    209     case CC_OP_INCQ:
    210         return compute_all_incq(dst, src1);
    211     case CC_OP_DECQ:
    212         return compute_all_decq(dst, src1);
    213     case CC_OP_SHLQ:
    214         return compute_all_shlq(dst, src1);
    215     case CC_OP_SARQ:
    216         return compute_all_sarq(dst, src1);
    217     case CC_OP_BMILGQ:
    218         return compute_all_bmilgq(dst, src1);
    219 #endif
    220     }
    221 }
    222 
    223 uint32_t cpu_cc_compute_all(CPUX86State *env, int op)
    224 {
    225     return helper_cc_compute_all(CC_DST, CC_SRC, CC_SRC2, op);
    226 }
    227 
    228 target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
    229                                  target_ulong src2, int op)
    230 {
    231     switch (op) {
    232     default: /* should never happen */
    233     case CC_OP_LOGICB:
    234     case CC_OP_LOGICW:
    235     case CC_OP_LOGICL:
    236     case CC_OP_LOGICQ:
    237     case CC_OP_CLR:
    238     case CC_OP_POPCNT:
    239         return 0;
    240 
    241     case CC_OP_EFLAGS:
    242     case CC_OP_SARB:
    243     case CC_OP_SARW:
    244     case CC_OP_SARL:
    245     case CC_OP_SARQ:
    246     case CC_OP_ADOX:
    247         return src1 & 1;
    248 
    249     case CC_OP_INCB:
    250     case CC_OP_INCW:
    251     case CC_OP_INCL:
    252     case CC_OP_INCQ:
    253     case CC_OP_DECB:
    254     case CC_OP_DECW:
    255     case CC_OP_DECL:
    256     case CC_OP_DECQ:
    257         return src1;
    258 
    259     case CC_OP_MULB:
    260     case CC_OP_MULW:
    261     case CC_OP_MULL:
    262     case CC_OP_MULQ:
    263         return src1 != 0;
    264 
    265     case CC_OP_ADCX:
    266     case CC_OP_ADCOX:
    267         return dst;
    268 
    269     case CC_OP_ADDB:
    270         return compute_c_addb(dst, src1);
    271     case CC_OP_ADDW:
    272         return compute_c_addw(dst, src1);
    273     case CC_OP_ADDL:
    274         return compute_c_addl(dst, src1);
    275 
    276     case CC_OP_ADCB:
    277         return compute_c_adcb(dst, src1, src2);
    278     case CC_OP_ADCW:
    279         return compute_c_adcw(dst, src1, src2);
    280     case CC_OP_ADCL:
    281         return compute_c_adcl(dst, src1, src2);
    282 
    283     case CC_OP_SUBB:
    284         return compute_c_subb(dst, src1);
    285     case CC_OP_SUBW:
    286         return compute_c_subw(dst, src1);
    287     case CC_OP_SUBL:
    288         return compute_c_subl(dst, src1);
    289 
    290     case CC_OP_SBBB:
    291         return compute_c_sbbb(dst, src1, src2);
    292     case CC_OP_SBBW:
    293         return compute_c_sbbw(dst, src1, src2);
    294     case CC_OP_SBBL:
    295         return compute_c_sbbl(dst, src1, src2);
    296 
    297     case CC_OP_SHLB:
    298         return compute_c_shlb(dst, src1);
    299     case CC_OP_SHLW:
    300         return compute_c_shlw(dst, src1);
    301     case CC_OP_SHLL:
    302         return compute_c_shll(dst, src1);
    303 
    304     case CC_OP_BMILGB:
    305         return compute_c_bmilgb(dst, src1);
    306     case CC_OP_BMILGW:
    307         return compute_c_bmilgw(dst, src1);
    308     case CC_OP_BMILGL:
    309         return compute_c_bmilgl(dst, src1);
    310 
    311 #ifdef TARGET_X86_64
    312     case CC_OP_ADDQ:
    313         return compute_c_addq(dst, src1);
    314     case CC_OP_ADCQ:
    315         return compute_c_adcq(dst, src1, src2);
    316     case CC_OP_SUBQ:
    317         return compute_c_subq(dst, src1);
    318     case CC_OP_SBBQ:
    319         return compute_c_sbbq(dst, src1, src2);
    320     case CC_OP_SHLQ:
    321         return compute_c_shlq(dst, src1);
    322     case CC_OP_BMILGQ:
    323         return compute_c_bmilgq(dst, src1);
    324 #endif
    325     }
    326 }
    327 
    328 void helper_write_eflags(CPUX86State *env, target_ulong t0,
    329                          uint32_t update_mask)
    330 {
    331     cpu_load_eflags(env, t0, update_mask);
    332 }
    333 
    334 target_ulong helper_read_eflags(CPUX86State *env)
    335 {
    336     uint32_t eflags;
    337 
    338     eflags = cpu_cc_compute_all(env, CC_OP);
    339     eflags |= (env->df & DF_MASK);
    340     eflags |= env->eflags & ~(VM_MASK | RF_MASK);
    341     return eflags;
    342 }
    343 
    344 void helper_clts(CPUX86State *env)
    345 {
    346     env->cr[0] &= ~CR0_TS_MASK;
    347     env->hflags &= ~HF_TS_MASK;
    348 }