Annotation of qemu/target-i386/helper_template.h, revision 1.1.1.2

1.1       root        1: /*
                      2:  *  i386 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 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
1.1.1.2 ! root       17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: #define DATA_BITS (1 << (3 + SHIFT))
                     20: #define SHIFT_MASK (DATA_BITS - 1)
                     21: #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
                     22: #if DATA_BITS <= 32
                     23: #define SHIFT1_MASK 0x1f
                     24: #else
                     25: #define SHIFT1_MASK 0x3f
                     26: #endif
                     27: 
                     28: #if DATA_BITS == 8
                     29: #define SUFFIX b
                     30: #define DATA_TYPE uint8_t
                     31: #define DATA_STYPE int8_t
                     32: #define DATA_MASK 0xff
                     33: #elif DATA_BITS == 16
                     34: #define SUFFIX w
                     35: #define DATA_TYPE uint16_t
                     36: #define DATA_STYPE int16_t
                     37: #define DATA_MASK 0xffff
                     38: #elif DATA_BITS == 32
                     39: #define SUFFIX l
                     40: #define DATA_TYPE uint32_t
                     41: #define DATA_STYPE int32_t
                     42: #define DATA_MASK 0xffffffff
                     43: #elif DATA_BITS == 64
                     44: #define SUFFIX q
                     45: #define DATA_TYPE uint64_t
                     46: #define DATA_STYPE int64_t
                     47: #define DATA_MASK 0xffffffffffffffffULL
                     48: #else
                     49: #error unhandled operand size
                     50: #endif
                     51: 
                     52: /* dynamic flags computation */
                     53: 
                     54: static int glue(compute_all_add, SUFFIX)(void)
                     55: {
                     56:     int cf, pf, af, zf, sf, of;
                     57:     target_long src1, src2;
                     58:     src1 = CC_SRC;
                     59:     src2 = CC_DST - CC_SRC;
                     60:     cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
                     61:     pf = parity_table[(uint8_t)CC_DST];
                     62:     af = (CC_DST ^ src1 ^ src2) & 0x10;
                     63:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                     64:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                     65:     of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
                     66:     return cf | pf | af | zf | sf | of;
                     67: }
                     68: 
                     69: static int glue(compute_c_add, SUFFIX)(void)
                     70: {
                     71:     int cf;
                     72:     target_long src1;
                     73:     src1 = CC_SRC;
                     74:     cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
                     75:     return cf;
                     76: }
                     77: 
                     78: static int glue(compute_all_adc, SUFFIX)(void)
                     79: {
                     80:     int cf, pf, af, zf, sf, of;
                     81:     target_long src1, src2;
                     82:     src1 = CC_SRC;
                     83:     src2 = CC_DST - CC_SRC - 1;
                     84:     cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
                     85:     pf = parity_table[(uint8_t)CC_DST];
                     86:     af = (CC_DST ^ src1 ^ src2) & 0x10;
                     87:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                     88:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                     89:     of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
                     90:     return cf | pf | af | zf | sf | of;
                     91: }
                     92: 
                     93: static int glue(compute_c_adc, SUFFIX)(void)
                     94: {
                     95:     int cf;
                     96:     target_long src1;
                     97:     src1 = CC_SRC;
                     98:     cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
                     99:     return cf;
                    100: }
                    101: 
                    102: static int glue(compute_all_sub, SUFFIX)(void)
                    103: {
                    104:     int cf, pf, af, zf, sf, of;
                    105:     target_long src1, src2;
                    106:     src1 = CC_DST + CC_SRC;
                    107:     src2 = CC_SRC;
                    108:     cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
                    109:     pf = parity_table[(uint8_t)CC_DST];
                    110:     af = (CC_DST ^ src1 ^ src2) & 0x10;
                    111:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    112:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    113:     of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
                    114:     return cf | pf | af | zf | sf | of;
                    115: }
                    116: 
                    117: static int glue(compute_c_sub, SUFFIX)(void)
                    118: {
                    119:     int cf;
                    120:     target_long src1, src2;
                    121:     src1 = CC_DST + CC_SRC;
                    122:     src2 = CC_SRC;
                    123:     cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
                    124:     return cf;
                    125: }
                    126: 
                    127: static int glue(compute_all_sbb, SUFFIX)(void)
                    128: {
                    129:     int cf, pf, af, zf, sf, of;
                    130:     target_long src1, src2;
                    131:     src1 = CC_DST + CC_SRC + 1;
                    132:     src2 = CC_SRC;
                    133:     cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
                    134:     pf = parity_table[(uint8_t)CC_DST];
                    135:     af = (CC_DST ^ src1 ^ src2) & 0x10;
                    136:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    137:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    138:     of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
                    139:     return cf | pf | af | zf | sf | of;
                    140: }
                    141: 
                    142: static int glue(compute_c_sbb, SUFFIX)(void)
                    143: {
                    144:     int cf;
                    145:     target_long src1, src2;
                    146:     src1 = CC_DST + CC_SRC + 1;
                    147:     src2 = CC_SRC;
                    148:     cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
                    149:     return cf;
                    150: }
                    151: 
                    152: static int glue(compute_all_logic, SUFFIX)(void)
                    153: {
                    154:     int cf, pf, af, zf, sf, of;
                    155:     cf = 0;
                    156:     pf = parity_table[(uint8_t)CC_DST];
                    157:     af = 0;
                    158:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    159:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    160:     of = 0;
                    161:     return cf | pf | af | zf | sf | of;
                    162: }
                    163: 
                    164: static int glue(compute_c_logic, SUFFIX)(void)
                    165: {
                    166:     return 0;
                    167: }
                    168: 
                    169: static int glue(compute_all_inc, SUFFIX)(void)
                    170: {
                    171:     int cf, pf, af, zf, sf, of;
                    172:     target_long src1, src2;
                    173:     src1 = CC_DST - 1;
                    174:     src2 = 1;
                    175:     cf = CC_SRC;
                    176:     pf = parity_table[(uint8_t)CC_DST];
                    177:     af = (CC_DST ^ src1 ^ src2) & 0x10;
                    178:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    179:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    180:     of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
                    181:     return cf | pf | af | zf | sf | of;
                    182: }
                    183: 
                    184: #if DATA_BITS == 32
                    185: static int glue(compute_c_inc, SUFFIX)(void)
                    186: {
                    187:     return CC_SRC;
                    188: }
                    189: #endif
                    190: 
                    191: static int glue(compute_all_dec, SUFFIX)(void)
                    192: {
                    193:     int cf, pf, af, zf, sf, of;
                    194:     target_long src1, src2;
                    195:     src1 = CC_DST + 1;
                    196:     src2 = 1;
                    197:     cf = CC_SRC;
                    198:     pf = parity_table[(uint8_t)CC_DST];
                    199:     af = (CC_DST ^ src1 ^ src2) & 0x10;
                    200:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    201:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    202:     of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11;
                    203:     return cf | pf | af | zf | sf | of;
                    204: }
                    205: 
                    206: static int glue(compute_all_shl, SUFFIX)(void)
                    207: {
                    208:     int cf, pf, af, zf, sf, of;
                    209:     cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
                    210:     pf = parity_table[(uint8_t)CC_DST];
                    211:     af = 0; /* undefined */
                    212:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    213:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    214:     /* of is defined if shift count == 1 */
                    215:     of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
                    216:     return cf | pf | af | zf | sf | of;
                    217: }
                    218: 
                    219: static int glue(compute_c_shl, SUFFIX)(void)
                    220: {
                    221:     return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
                    222: }
                    223: 
                    224: #if DATA_BITS == 32
                    225: static int glue(compute_c_sar, SUFFIX)(void)
                    226: {
                    227:     return CC_SRC & 1;
                    228: }
                    229: #endif
                    230: 
                    231: static int glue(compute_all_sar, SUFFIX)(void)
                    232: {
                    233:     int cf, pf, af, zf, sf, of;
                    234:     cf = CC_SRC & 1;
                    235:     pf = parity_table[(uint8_t)CC_DST];
                    236:     af = 0; /* undefined */
                    237:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    238:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    239:     /* of is defined if shift count == 1 */
                    240:     of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
                    241:     return cf | pf | af | zf | sf | of;
                    242: }
                    243: 
                    244: #if DATA_BITS == 32
                    245: static int glue(compute_c_mul, SUFFIX)(void)
                    246: {
                    247:     int cf;
                    248:     cf = (CC_SRC != 0);
                    249:     return cf;
                    250: }
                    251: #endif
                    252: 
                    253: /* NOTE: we compute the flags like the P4. On olders CPUs, only OF and
                    254:    CF are modified and it is slower to do that. */
                    255: static int glue(compute_all_mul, SUFFIX)(void)
                    256: {
                    257:     int cf, pf, af, zf, sf, of;
                    258:     cf = (CC_SRC != 0);
                    259:     pf = parity_table[(uint8_t)CC_DST];
                    260:     af = 0; /* undefined */
                    261:     zf = ((DATA_TYPE)CC_DST == 0) << 6;
                    262:     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
                    263:     of = cf << 11;
                    264:     return cf | pf | af | zf | sf | of;
                    265: }
                    266: 
                    267: /* shifts */
                    268: 
                    269: target_ulong glue(helper_rcl, SUFFIX)(target_ulong t0, target_ulong t1)
                    270: {
                    271:     int count, eflags;
                    272:     target_ulong src;
                    273:     target_long res;
                    274: 
                    275:     count = t1 & SHIFT1_MASK;
                    276: #if DATA_BITS == 16
                    277:     count = rclw_table[count];
                    278: #elif DATA_BITS == 8
                    279:     count = rclb_table[count];
                    280: #endif
                    281:     if (count) {
                    282:         eflags = helper_cc_compute_all(CC_OP);
                    283:         t0 &= DATA_MASK;
                    284:         src = t0;
                    285:         res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
                    286:         if (count > 1)
                    287:             res |= t0 >> (DATA_BITS + 1 - count);
                    288:         t0 = res;
                    289:         env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
                    290:             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
                    291:             ((src >> (DATA_BITS - count)) & CC_C);
                    292:     } else {
                    293:         env->cc_tmp = -1;
                    294:     }
                    295:     return t0;
                    296: }
                    297: 
                    298: target_ulong glue(helper_rcr, SUFFIX)(target_ulong t0, target_ulong t1)
                    299: {
                    300:     int count, eflags;
                    301:     target_ulong src;
                    302:     target_long res;
                    303: 
                    304:     count = t1 & SHIFT1_MASK;
                    305: #if DATA_BITS == 16
                    306:     count = rclw_table[count];
                    307: #elif DATA_BITS == 8
                    308:     count = rclb_table[count];
                    309: #endif
                    310:     if (count) {
                    311:         eflags = helper_cc_compute_all(CC_OP);
                    312:         t0 &= DATA_MASK;
                    313:         src = t0;
                    314:         res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
                    315:         if (count > 1)
                    316:             res |= t0 << (DATA_BITS + 1 - count);
                    317:         t0 = res;
                    318:         env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
                    319:             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
                    320:             ((src >> (count - 1)) & CC_C);
                    321:     } else {
                    322:         env->cc_tmp = -1;
                    323:     }
                    324:     return t0;
                    325: }
                    326: 
                    327: #undef DATA_BITS
                    328: #undef SHIFT_MASK
                    329: #undef SHIFT1_MASK
                    330: #undef SIGN_MASK
                    331: #undef DATA_TYPE
                    332: #undef DATA_STYPE
                    333: #undef DATA_MASK
                    334: #undef SUFFIX

unix.superglobalmegacorp.com