qemu

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

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 
     42 static 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 
     56 static int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
     57 {
     58     return dst < src1;
     59 }
     60 
     61 static 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 
     76 static 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 
     82 static 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 
     96 static 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 
    103 static 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 
    118 static 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 
    126 static 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 
    139 static 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 
    155 static 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 
    171 static 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 
    185 static int glue(compute_c_shl, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
    186 {
    187     return (src1 >> (DATA_BITS - 1)) & CC_C;
    188 }
    189 
    190 static 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.  */
    207 static 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 
    220 static 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 
    233 static 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