qemu/target/i386/shift_helper_template.h
<<
>>
Prefs
   1/*
   2 *  x86 shift 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#define SHIFT_MASK (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_MASK 0xff
  31#elif DATA_BITS == 16
  32#define SUFFIX w
  33#define DATA_MASK 0xffff
  34#elif DATA_BITS == 32
  35#define SUFFIX l
  36#define DATA_MASK 0xffffffff
  37#elif DATA_BITS == 64
  38#define SUFFIX q
  39#define DATA_MASK 0xffffffffffffffffULL
  40#else
  41#error unhandled operand size
  42#endif
  43
  44target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0,
  45                                      target_ulong t1)
  46{
  47    int count, eflags;
  48    target_ulong src;
  49    target_long res;
  50
  51    count = t1 & SHIFT1_MASK;
  52#if DATA_BITS == 16
  53    count = rclw_table[count];
  54#elif DATA_BITS == 8
  55    count = rclb_table[count];
  56#endif
  57    if (count) {
  58        eflags = env->cc_src;
  59        t0 &= DATA_MASK;
  60        src = t0;
  61        res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
  62        if (count > 1) {
  63            res |= t0 >> (DATA_BITS + 1 - count);
  64        }
  65        t0 = res;
  66        env->cc_src = (eflags & ~(CC_C | CC_O)) |
  67            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
  68            ((src >> (DATA_BITS - count)) & CC_C);
  69    }
  70    return t0;
  71}
  72
  73target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
  74                                      target_ulong t1)
  75{
  76    int count, eflags;
  77    target_ulong src;
  78    target_long res;
  79
  80    count = t1 & SHIFT1_MASK;
  81#if DATA_BITS == 16
  82    count = rclw_table[count];
  83#elif DATA_BITS == 8
  84    count = rclb_table[count];
  85#endif
  86    if (count) {
  87        eflags = env->cc_src;
  88        t0 &= DATA_MASK;
  89        src = t0;
  90        res = (t0 >> count) |
  91            ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
  92        if (count > 1) {
  93            res |= t0 << (DATA_BITS + 1 - count);
  94        }
  95        t0 = res;
  96        env->cc_src = (eflags & ~(CC_C | CC_O)) |
  97            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
  98            ((src >> (count - 1)) & CC_C);
  99    }
 100    return t0;
 101}
 102
 103#undef DATA_BITS
 104#undef SHIFT_MASK
 105#undef SHIFT1_MASK
 106#undef DATA_TYPE
 107#undef DATA_MASK
 108#undef SUFFIX
 109