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

int_helper.c (6626B)


      1/*
      2 *  Helpers for integer and multimedia instructions.
      3 *
      4 *  Copyright (c) 2007 Jocelyn Mayer
      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/exec-all.h"
     23#include "exec/helper-proto.h"
     24#include "qemu/host-utils.h"
     25
     26
     27uint64_t helper_zapnot(uint64_t val, uint64_t mskb)
     28{
     29    uint64_t mask;
     30
     31    mask  = -(mskb & 0x01) & 0x00000000000000ffull;
     32    mask |= -(mskb & 0x02) & 0x000000000000ff00ull;
     33    mask |= -(mskb & 0x04) & 0x0000000000ff0000ull;
     34    mask |= -(mskb & 0x08) & 0x00000000ff000000ull;
     35    mask |= -(mskb & 0x10) & 0x000000ff00000000ull;
     36    mask |= -(mskb & 0x20) & 0x0000ff0000000000ull;
     37    mask |= -(mskb & 0x40) & 0x00ff000000000000ull;
     38    mask |= -(mskb & 0x80) & 0xff00000000000000ull;
     39
     40    return val & mask;
     41}
     42
     43uint64_t helper_zap(uint64_t val, uint64_t mask)
     44{
     45    return helper_zapnot(val, ~mask);
     46}
     47
     48uint64_t helper_cmpbe0(uint64_t a)
     49{
     50    uint64_t m = 0x7f7f7f7f7f7f7f7fULL;
     51    uint64_t c = ~(((a & m) + m) | a | m);
     52    /* a.......b.......c.......d.......e.......f.......g.......h....... */
     53    c |= c << 7;
     54    /* ab......bc......cd......de......ef......fg......gh......h....... */
     55    c |= c << 14;
     56    /* abcd....bcde....cdef....defg....efgh....fgh.....gh......h....... */
     57    c |= c << 28;
     58    /* abcdefghbcdefgh.cdefgh..defgh...efgh....fgh.....gh......h....... */
     59    return c >> 56;
     60}
     61
     62uint64_t helper_cmpbge(uint64_t a, uint64_t b)
     63{
     64    uint64_t mask = 0x00ff00ff00ff00ffULL;
     65    uint64_t test = 0x0100010001000100ULL;
     66    uint64_t al, ah, bl, bh, cl, ch;
     67
     68    /* Separate the bytes to avoid false positives.  */
     69    al = a & mask;
     70    bl = b & mask;
     71    ah = (a >> 8) & mask;
     72    bh = (b >> 8) & mask;
     73
     74    /* "Compare".  If a byte in B is greater than a byte in A,
     75       it will clear the test bit.  */
     76    cl = ((al | test) - bl) & test;
     77    ch = ((ah | test) - bh) & test;
     78
     79    /* Fold all of the test bits into a contiguous set.  */
     80    /* ch=.......a...............c...............e...............g........ */
     81    /* cl=.......b...............d...............f...............h........ */
     82    cl += ch << 1;
     83    /* cl=......ab..............cd..............ef..............gh........ */
     84    cl |= cl << 14;
     85    /* cl=......abcd............cdef............efgh............gh........ */
     86    cl |= cl << 28;
     87    /* cl=......abcdefgh........cdefgh..........efgh............gh........ */
     88    return cl >> 50;
     89}
     90
     91uint64_t helper_minub8(uint64_t op1, uint64_t op2)
     92{
     93    uint64_t res = 0;
     94    uint8_t opa, opb, opr;
     95    int i;
     96
     97    for (i = 0; i < 8; ++i) {
     98        opa = op1 >> (i * 8);
     99        opb = op2 >> (i * 8);
    100        opr = opa < opb ? opa : opb;
    101        res |= (uint64_t)opr << (i * 8);
    102    }
    103    return res;
    104}
    105
    106uint64_t helper_minsb8(uint64_t op1, uint64_t op2)
    107{
    108    uint64_t res = 0;
    109    int8_t opa, opb;
    110    uint8_t opr;
    111    int i;
    112
    113    for (i = 0; i < 8; ++i) {
    114        opa = op1 >> (i * 8);
    115        opb = op2 >> (i * 8);
    116        opr = opa < opb ? opa : opb;
    117        res |= (uint64_t)opr << (i * 8);
    118    }
    119    return res;
    120}
    121
    122uint64_t helper_minuw4(uint64_t op1, uint64_t op2)
    123{
    124    uint64_t res = 0;
    125    uint16_t opa, opb, opr;
    126    int i;
    127
    128    for (i = 0; i < 4; ++i) {
    129        opa = op1 >> (i * 16);
    130        opb = op2 >> (i * 16);
    131        opr = opa < opb ? opa : opb;
    132        res |= (uint64_t)opr << (i * 16);
    133    }
    134    return res;
    135}
    136
    137uint64_t helper_minsw4(uint64_t op1, uint64_t op2)
    138{
    139    uint64_t res = 0;
    140    int16_t opa, opb;
    141    uint16_t opr;
    142    int i;
    143
    144    for (i = 0; i < 4; ++i) {
    145        opa = op1 >> (i * 16);
    146        opb = op2 >> (i * 16);
    147        opr = opa < opb ? opa : opb;
    148        res |= (uint64_t)opr << (i * 16);
    149    }
    150    return res;
    151}
    152
    153uint64_t helper_maxub8(uint64_t op1, uint64_t op2)
    154{
    155    uint64_t res = 0;
    156    uint8_t opa, opb, opr;
    157    int i;
    158
    159    for (i = 0; i < 8; ++i) {
    160        opa = op1 >> (i * 8);
    161        opb = op2 >> (i * 8);
    162        opr = opa > opb ? opa : opb;
    163        res |= (uint64_t)opr << (i * 8);
    164    }
    165    return res;
    166}
    167
    168uint64_t helper_maxsb8(uint64_t op1, uint64_t op2)
    169{
    170    uint64_t res = 0;
    171    int8_t opa, opb;
    172    uint8_t opr;
    173    int i;
    174
    175    for (i = 0; i < 8; ++i) {
    176        opa = op1 >> (i * 8);
    177        opb = op2 >> (i * 8);
    178        opr = opa > opb ? opa : opb;
    179        res |= (uint64_t)opr << (i * 8);
    180    }
    181    return res;
    182}
    183
    184uint64_t helper_maxuw4(uint64_t op1, uint64_t op2)
    185{
    186    uint64_t res = 0;
    187    uint16_t opa, opb, opr;
    188    int i;
    189
    190    for (i = 0; i < 4; ++i) {
    191        opa = op1 >> (i * 16);
    192        opb = op2 >> (i * 16);
    193        opr = opa > opb ? opa : opb;
    194        res |= (uint64_t)opr << (i * 16);
    195    }
    196    return res;
    197}
    198
    199uint64_t helper_maxsw4(uint64_t op1, uint64_t op2)
    200{
    201    uint64_t res = 0;
    202    int16_t opa, opb;
    203    uint16_t opr;
    204    int i;
    205
    206    for (i = 0; i < 4; ++i) {
    207        opa = op1 >> (i * 16);
    208        opb = op2 >> (i * 16);
    209        opr = opa > opb ? opa : opb;
    210        res |= (uint64_t)opr << (i * 16);
    211    }
    212    return res;
    213}
    214
    215uint64_t helper_perr(uint64_t op1, uint64_t op2)
    216{
    217    uint64_t res = 0;
    218    uint8_t opa, opb, opr;
    219    int i;
    220
    221    for (i = 0; i < 8; ++i) {
    222        opa = op1 >> (i * 8);
    223        opb = op2 >> (i * 8);
    224        if (opa >= opb) {
    225            opr = opa - opb;
    226        } else {
    227            opr = opb - opa;
    228        }
    229        res += opr;
    230    }
    231    return res;
    232}
    233
    234uint64_t helper_pklb(uint64_t op1)
    235{
    236    return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
    237}
    238
    239uint64_t helper_pkwb(uint64_t op1)
    240{
    241    return ((op1 & 0xff)
    242            | ((op1 >> 8) & 0xff00)
    243            | ((op1 >> 16) & 0xff0000)
    244            | ((op1 >> 24) & 0xff000000));
    245}
    246
    247uint64_t helper_unpkbl(uint64_t op1)
    248{
    249    return (op1 & 0xff) | ((op1 & 0xff00) << 24);
    250}
    251
    252uint64_t helper_unpkbw(uint64_t op1)
    253{
    254    return ((op1 & 0xff)
    255            | ((op1 & 0xff00) << 8)
    256            | ((op1 & 0xff0000) << 16)
    257            | ((op1 & 0xff000000) << 24));
    258}
    259
    260void helper_check_overflow(CPUAlphaState *env, uint64_t op1, uint64_t op2)
    261{
    262    if (unlikely(op1 != op2)) {
    263        arith_excp(env, GETPC(), EXC_M_IOV, 0);
    264    }
    265}