Home | History | Annotate | Download | only in target-i386
      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, write to the Free Software
     18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
     19  */
     20 #define DATA_BITS (1 << (3 + SHIFT))
     21 #define SHIFT_MASK (DATA_BITS - 1)
     22 #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1))
     23 #if DATA_BITS <= 32
     24 #define SHIFT1_MASK 0x1f
     25 #else
     26 #define SHIFT1_MASK 0x3f
     27 #endif
     28 
     29 #if DATA_BITS == 8
     30 #define SUFFIX b
     31 #define DATA_TYPE uint8_t
     32 #define DATA_STYPE int8_t
     33 #define DATA_MASK 0xff
     34 #elif DATA_BITS == 16
     35 #define SUFFIX w
     36 #define DATA_TYPE uint16_t
     37 #define DATA_STYPE int16_t
     38 #define DATA_MASK 0xffff
     39 #elif DATA_BITS == 32
     40 #define SUFFIX l
     41 #define DATA_TYPE uint32_t
     42 #define DATA_STYPE int32_t
     43 #define DATA_MASK 0xffffffff
     44 #elif DATA_BITS == 64
     45 #define SUFFIX q
     46 #define DATA_TYPE uint64_t
     47 #define DATA_STYPE int64_t
     48 #define DATA_MASK 0xffffffffffffffffULL
     49 #else
     50 #error unhandled operand size
     51 #endif
     52 
     53 /* shifts */
     54 
     55 target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env,
     56                                       target_ulong t0, target_ulong t1)
     57 {
     58     int count, eflags;
     59     target_ulong src;
     60     target_long res;
     61 
     62     count = t1 & SHIFT1_MASK;
     63 #if DATA_BITS == 16
     64     count = rclw_table[count];
     65 #elif DATA_BITS == 8
     66     count = rclb_table[count];
     67 #endif
     68     if (count) {
     69         eflags = env->cc_src;
     70         t0 &= DATA_MASK;
     71         src = t0;
     72         res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
     73         if (count > 1)
     74             res |= t0 >> (DATA_BITS + 1 - count);
     75         t0 = res;
     76         env->cc_src = (eflags & ~(CC_C | CC_O)) |
     77             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
     78             ((src >> (DATA_BITS - count)) & CC_C);
     79     }
     80     return t0;
     81 }
     82 
     83 target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env,
     84                                       target_ulong t0, target_ulong t1)
     85 {
     86     int count, eflags;
     87     target_ulong src;
     88     target_long res;
     89 
     90     count = t1 & SHIFT1_MASK;
     91 #if DATA_BITS == 16
     92     count = rclw_table[count];
     93 #elif DATA_BITS == 8
     94     count = rclb_table[count];
     95 #endif
     96     if (count) {
     97         eflags = env->cc_src;
     98         t0 &= DATA_MASK;
     99         src = t0;
    100         res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
    101         if (count > 1)
    102             res |= t0 << (DATA_BITS + 1 - count);
    103         t0 = res;
    104         env->cc_src = (eflags & ~(CC_C | CC_O)) |
    105             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
    106             ((src >> (count - 1)) & CC_C);
    107     }
    108     return t0;
    109 }
    110 
    111 #undef DATA_BITS
    112 #undef SHIFT_MASK
    113 #undef SHIFT1_MASK
    114 #undef SIGN_MASK
    115 #undef DATA_TYPE
    116 #undef DATA_STYPE
    117 #undef DATA_MASK
    118 #undef SUFFIX
    119