qemu

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

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 
     27 uint64_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 
     43 uint64_t helper_zap(uint64_t val, uint64_t mask)
     44 {
     45     return helper_zapnot(val, ~mask);
     46 }
     47 
     48 uint64_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 
     62 uint64_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 
     91 uint64_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 
    106 uint64_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 
    122 uint64_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 
    137 uint64_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 
    153 uint64_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 
    168 uint64_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 
    184 uint64_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 
    199 uint64_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 
    215 uint64_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 
    234 uint64_t helper_pklb(uint64_t op1)
    235 {
    236     return (op1 & 0xff) | ((op1 >> 24) & 0xff00);
    237 }
    238 
    239 uint64_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 
    247 uint64_t helper_unpkbl(uint64_t op1)
    248 {
    249     return (op1 & 0xff) | ((op1 & 0xff00) << 24);
    250 }
    251 
    252 uint64_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 
    260 void 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 }