mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
![Chetan Pant](/assets/img/avatar_default.png)
There is no "version 2" of the "Lesser" General Public License. It is either "GPL version 2.0" or "Lesser GPL version 2.1". This patch replaces all occurrences of "Lesser GPL version 2" with "Lesser GPL version 2.1" in comment section. Signed-off-by: Chetan Pant <chetan4windows@gmail.com> Message-Id: <20201023122801.19514-1-chetan4windows@gmail.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
109 lines
2.8 KiB
C
109 lines
2.8 KiB
C
/*
|
|
* x86 shift helpers
|
|
*
|
|
* Copyright (c) 2008 Fabrice Bellard
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define DATA_BITS (1 << (3 + SHIFT))
|
|
#define SHIFT_MASK (DATA_BITS - 1)
|
|
#if DATA_BITS <= 32
|
|
#define SHIFT1_MASK 0x1f
|
|
#else
|
|
#define SHIFT1_MASK 0x3f
|
|
#endif
|
|
|
|
#if DATA_BITS == 8
|
|
#define SUFFIX b
|
|
#define DATA_MASK 0xff
|
|
#elif DATA_BITS == 16
|
|
#define SUFFIX w
|
|
#define DATA_MASK 0xffff
|
|
#elif DATA_BITS == 32
|
|
#define SUFFIX l
|
|
#define DATA_MASK 0xffffffff
|
|
#elif DATA_BITS == 64
|
|
#define SUFFIX q
|
|
#define DATA_MASK 0xffffffffffffffffULL
|
|
#else
|
|
#error unhandled operand size
|
|
#endif
|
|
|
|
target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0,
|
|
target_ulong t1)
|
|
{
|
|
int count, eflags;
|
|
target_ulong src;
|
|
target_long res;
|
|
|
|
count = t1 & SHIFT1_MASK;
|
|
#if DATA_BITS == 16
|
|
count = rclw_table[count];
|
|
#elif DATA_BITS == 8
|
|
count = rclb_table[count];
|
|
#endif
|
|
if (count) {
|
|
eflags = env->cc_src;
|
|
t0 &= DATA_MASK;
|
|
src = t0;
|
|
res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
|
|
if (count > 1) {
|
|
res |= t0 >> (DATA_BITS + 1 - count);
|
|
}
|
|
t0 = res;
|
|
env->cc_src = (eflags & ~(CC_C | CC_O)) |
|
|
(lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
|
|
((src >> (DATA_BITS - count)) & CC_C);
|
|
}
|
|
return t0;
|
|
}
|
|
|
|
target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
|
|
target_ulong t1)
|
|
{
|
|
int count, eflags;
|
|
target_ulong src;
|
|
target_long res;
|
|
|
|
count = t1 & SHIFT1_MASK;
|
|
#if DATA_BITS == 16
|
|
count = rclw_table[count];
|
|
#elif DATA_BITS == 8
|
|
count = rclb_table[count];
|
|
#endif
|
|
if (count) {
|
|
eflags = env->cc_src;
|
|
t0 &= DATA_MASK;
|
|
src = t0;
|
|
res = (t0 >> count) |
|
|
((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
|
|
if (count > 1) {
|
|
res |= t0 << (DATA_BITS + 1 - count);
|
|
}
|
|
t0 = res;
|
|
env->cc_src = (eflags & ~(CC_C | CC_O)) |
|
|
(lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
|
|
((src >> (count - 1)) & CC_C);
|
|
}
|
|
return t0;
|
|
}
|
|
|
|
#undef DATA_BITS
|
|
#undef SHIFT_MASK
|
|
#undef SHIFT1_MASK
|
|
#undef DATA_TYPE
|
|
#undef DATA_MASK
|
|
#undef SUFFIX
|