File:  [Qemu by Fabrice Bellard] / qemu / target-i386 / helper_template.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:26:00 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, qemu1001, qemu1000, qemu0151, qemu0150, qemu0141, qemu0140, qemu0130, qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, qemu0111, qemu0110, HEAD
qemu 0.11.0

    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
   17:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
   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