shift_helper_template.h (2917B)
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