cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

cc_helper.c (10280B)


      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
     25const 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
     80static 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
     86static 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
     92static 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
     98target_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
    223uint32_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
    228target_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
    328void helper_write_eflags(CPUX86State *env, target_ulong t0,
    329                         uint32_t update_mask)
    330{
    331    cpu_load_eflags(env, t0, update_mask);
    332}
    333
    334target_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
    344void helper_clts(CPUX86State *env)
    345{
    346    env->cr[0] &= ~CR0_TS_MASK;
    347    env->hflags &= ~HF_TS_MASK;
    348}
    349
    350void helper_reset_rf(CPUX86State *env)
    351{
    352    env->eflags &= ~RF_MASK;
    353}
    354
    355void helper_cli(CPUX86State *env)
    356{
    357    env->eflags &= ~IF_MASK;
    358}
    359
    360void helper_sti(CPUX86State *env)
    361{
    362    env->eflags |= IF_MASK;
    363}
    364
    365void helper_clac(CPUX86State *env)
    366{
    367    env->eflags &= ~AC_MASK;
    368}
    369
    370void helper_stac(CPUX86State *env)
    371{
    372    env->eflags |= AC_MASK;
    373}
    374
    375#if 0
    376/* vm86plus instructions */
    377void helper_cli_vm(CPUX86State *env)
    378{
    379    env->eflags &= ~VIF_MASK;
    380}
    381
    382void helper_sti_vm(CPUX86State *env)
    383{
    384    env->eflags |= VIF_MASK;
    385    if (env->eflags & VIP_MASK) {
    386        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    387    }
    388}
    389#endif