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_template.h (6750B)


      1/*
      2 *  x86 condition code helpers
      3 *
      4 *  Copyright (c) 2008 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#define DATA_BITS (1 << (3 + SHIFT))
     21
     22#if DATA_BITS == 8
     23#define SUFFIX b
     24#define DATA_TYPE uint8_t
     25#elif DATA_BITS == 16
     26#define SUFFIX w
     27#define DATA_TYPE uint16_t
     28#elif DATA_BITS == 32
     29#define SUFFIX l
     30#define DATA_TYPE uint32_t
     31#elif DATA_BITS == 64
     32#define SUFFIX q
     33#define DATA_TYPE uint64_t
     34#else
     35#error unhandled operand size
     36#endif
     37
     38#define SIGN_MASK (((DATA_TYPE)1) << (DATA_BITS - 1))
     39
     40/* dynamic flags computation */
     41
     42static int glue(compute_all_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
     43{
     44    int cf, pf, af, zf, sf, of;
     45    DATA_TYPE src2 = dst - src1;
     46
     47    cf = dst < src1;
     48    pf = parity_table[(uint8_t)dst];
     49    af = (dst ^ src1 ^ src2) & CC_A;
     50    zf = (dst == 0) * CC_Z;
     51    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
     52    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
     53    return cf | pf | af | zf | sf | of;
     54}
     55
     56static int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
     57{
     58    return dst < src1;
     59}
     60
     61static int glue(compute_all_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
     62                                         DATA_TYPE src3)
     63{
     64    int cf, pf, af, zf, sf, of;
     65    DATA_TYPE src2 = dst - src1 - src3;
     66
     67    cf = (src3 ? dst <= src1 : dst < src1);
     68    pf = parity_table[(uint8_t)dst];
     69    af = (dst ^ src1 ^ src2) & 0x10;
     70    zf = (dst == 0) << 6;
     71    sf = lshift(dst, 8 - DATA_BITS) & 0x80;
     72    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
     73    return cf | pf | af | zf | sf | of;
     74}
     75
     76static int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1,
     77                                       DATA_TYPE src3)
     78{
     79    return src3 ? dst <= src1 : dst < src1;
     80}
     81
     82static int glue(compute_all_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
     83{
     84    int cf, pf, af, zf, sf, of;
     85    DATA_TYPE src1 = dst + src2;
     86
     87    cf = src1 < src2;
     88    pf = parity_table[(uint8_t)dst];
     89    af = (dst ^ src1 ^ src2) & CC_A;
     90    zf = (dst == 0) * CC_Z;
     91    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
     92    of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
     93    return cf | pf | af | zf | sf | of;
     94}
     95
     96static int glue(compute_c_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2)
     97{
     98    DATA_TYPE src1 = dst + src2;
     99
    100    return src1 < src2;
    101}
    102
    103static int glue(compute_all_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
    104                                         DATA_TYPE src3)
    105{
    106    int cf, pf, af, zf, sf, of;
    107    DATA_TYPE src1 = dst + src2 + src3;
    108
    109    cf = (src3 ? src1 <= src2 : src1 < src2);
    110    pf = parity_table[(uint8_t)dst];
    111    af = (dst ^ src1 ^ src2) & 0x10;
    112    zf = (dst == 0) << 6;
    113    sf = lshift(dst, 8 - DATA_BITS) & 0x80;
    114    of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O;
    115    return cf | pf | af | zf | sf | of;
    116}
    117
    118static int glue(compute_c_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2,
    119                                       DATA_TYPE src3)
    120{
    121    DATA_TYPE src1 = dst + src2 + src3;
    122
    123    return (src3 ? src1 <= src2 : src1 < src2);
    124}
    125
    126static int glue(compute_all_logic, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    127{
    128    int cf, pf, af, zf, sf, of;
    129
    130    cf = 0;
    131    pf = parity_table[(uint8_t)dst];
    132    af = 0;
    133    zf = (dst == 0) * CC_Z;
    134    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
    135    of = 0;
    136    return cf | pf | af | zf | sf | of;
    137}
    138
    139static int glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    140{
    141    int cf, pf, af, zf, sf, of;
    142    DATA_TYPE src2;
    143
    144    cf = src1;
    145    src1 = dst - 1;
    146    src2 = 1;
    147    pf = parity_table[(uint8_t)dst];
    148    af = (dst ^ src1 ^ src2) & CC_A;
    149    zf = (dst == 0) * CC_Z;
    150    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
    151    of = (dst == SIGN_MASK) * CC_O;
    152    return cf | pf | af | zf | sf | of;
    153}
    154
    155static int glue(compute_all_dec, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    156{
    157    int cf, pf, af, zf, sf, of;
    158    DATA_TYPE src2;
    159
    160    cf = src1;
    161    src1 = dst + 1;
    162    src2 = 1;
    163    pf = parity_table[(uint8_t)dst];
    164    af = (dst ^ src1 ^ src2) & CC_A;
    165    zf = (dst == 0) * CC_Z;
    166    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
    167    of = (dst == SIGN_MASK - 1) * CC_O;
    168    return cf | pf | af | zf | sf | of;
    169}
    170
    171static int glue(compute_all_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    172{
    173    int cf, pf, af, zf, sf, of;
    174
    175    cf = (src1 >> (DATA_BITS - 1)) & CC_C;
    176    pf = parity_table[(uint8_t)dst];
    177    af = 0; /* undefined */
    178    zf = (dst == 0) * CC_Z;
    179    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
    180    /* of is defined iff shift count == 1 */
    181    of = lshift(src1 ^ dst, 12 - DATA_BITS) & CC_O;
    182    return cf | pf | af | zf | sf | of;
    183}
    184
    185static int glue(compute_c_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    186{
    187    return (src1 >> (DATA_BITS - 1)) & CC_C;
    188}
    189
    190static int glue(compute_all_sar, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    191{
    192    int cf, pf, af, zf, sf, of;
    193
    194    cf = src1 & 1;
    195    pf = parity_table[(uint8_t)dst];
    196    af = 0; /* undefined */
    197    zf = (dst == 0) * CC_Z;
    198    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
    199    /* of is defined iff shift count == 1 */
    200    of = lshift(src1 ^ dst, 12 - DATA_BITS) & CC_O;
    201    return cf | pf | af | zf | sf | of;
    202}
    203
    204/* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
    205   CF are modified and it is slower to do that.  Note as well that we
    206   don't truncate SRC1 for computing carry to DATA_TYPE.  */
    207static int glue(compute_all_mul, SUFFIX)(DATA_TYPE dst, target_long src1)
    208{
    209    int cf, pf, af, zf, sf, of;
    210
    211    cf = (src1 != 0);
    212    pf = parity_table[(uint8_t)dst];
    213    af = 0; /* undefined */
    214    zf = (dst == 0) * CC_Z;
    215    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
    216    of = cf * CC_O;
    217    return cf | pf | af | zf | sf | of;
    218}
    219
    220static int glue(compute_all_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    221{
    222    int cf, pf, af, zf, sf, of;
    223
    224    cf = (src1 == 0);
    225    pf = 0; /* undefined */
    226    af = 0; /* undefined */
    227    zf = (dst == 0) * CC_Z;
    228    sf = lshift(dst, 8 - DATA_BITS) & CC_S;
    229    of = 0;
    230    return cf | pf | af | zf | sf | of;
    231}
    232
    233static int glue(compute_c_bmilg, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    234{
    235    return src1 == 0;
    236}
    237
    238#undef DATA_BITS
    239#undef SIGN_MASK
    240#undef DATA_TYPE
    241#undef DATA_MASK
    242#undef SUFFIX