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 44 target_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 73 target_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