/*
* i386 micro operations (included several times to generate
* different operand sizes)
- *
+ *
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
*/
#ifdef MEM_WRITE
+#if MEM_WRITE == 0
+
+#if DATA_BITS == 8
+#define MEM_SUFFIX b_raw
+#elif DATA_BITS == 16
+#define MEM_SUFFIX w_raw
+#elif DATA_BITS == 32
+#define MEM_SUFFIX l_raw
+#elif DATA_BITS == 64
+#define MEM_SUFFIX q_raw
+#endif
+
+#elif MEM_WRITE == 1
+
+#if DATA_BITS == 8
+#define MEM_SUFFIX b_kernel
+#elif DATA_BITS == 16
+#define MEM_SUFFIX w_kernel
+#elif DATA_BITS == 32
+#define MEM_SUFFIX l_kernel
+#elif DATA_BITS == 64
+#define MEM_SUFFIX q_kernel
+#endif
+
+#elif MEM_WRITE == 2
+
#if DATA_BITS == 8
-#define MEM_SUFFIX b_mem
+#define MEM_SUFFIX b_user
#elif DATA_BITS == 16
-#define MEM_SUFFIX w_mem
+#define MEM_SUFFIX w_user
#elif DATA_BITS == 32
-#define MEM_SUFFIX l_mem
+#define MEM_SUFFIX l_user
+#elif DATA_BITS == 64
+#define MEM_SUFFIX q_user
+#endif
+
+#else
+
+#error invalid MEM_WRITE
+
#endif
#else
void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
{
- int count, src;
- count = T1 & SHIFT_MASK;
- if (count) {
+ int count;
+ target_long src;
+
+ if (T1 & SHIFT1_MASK) {
+ count = T1 & SHIFT_MASK;
src = T0;
T0 &= DATA_MASK;
T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#else
/* gcc 3.2 workaround. This is really a bug in gcc. */
asm volatile("" : : "r" (T0));
#endif
- CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
(T0 & CC_C);
CC_OP = CC_OP_EFLAGS;
}
void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
{
- int count, src;
- count = T1 & SHIFT_MASK;
- if (count) {
+ int count;
+ target_long src;
+
+ if (T1 & SHIFT1_MASK) {
+ count = T1 & SHIFT_MASK;
src = T0;
T0 &= DATA_MASK;
T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#else
/* gcc 3.2 workaround. This is really a bug in gcc. */
asm volatile("" : : "r" (T0));
#endif
CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
((T0 >> (DATA_BITS - 1)) & CC_C);
CC_OP = CC_OP_EFLAGS;
}
T0 &= DATA_MASK;
T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
}
FORCE_RET();
T0 &= DATA_MASK;
T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
}
FORCE_RET();
void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
{
- int count, res, eflags;
- unsigned int src;
+ int count, eflags;
+ target_ulong src;
+ target_long res;
- count = T1 & 0x1f;
+ count = T1 & SHIFT1_MASK;
#if DATA_BITS == 16
count = rclw_table[count];
#elif DATA_BITS == 8
eflags = cc_table[CC_OP].compute_all();
T0 &= DATA_MASK;
src = T0;
- res = (T0 << count) | ((eflags & CC_C) << (count - 1));
+ res = (T0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
if (count > 1)
res |= T0 >> (DATA_BITS + 1 - count);
T0 = res;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
((src >> (DATA_BITS - count)) & CC_C);
CC_OP = CC_OP_EFLAGS;
}
void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
{
- int count, res, eflags;
- unsigned int src;
+ int count, eflags;
+ target_ulong src;
+ target_long res;
- count = T1 & 0x1f;
+ count = T1 & SHIFT1_MASK;
#if DATA_BITS == 16
count = rclw_table[count];
#elif DATA_BITS == 8
eflags = cc_table[CC_OP].compute_all();
T0 &= DATA_MASK;
src = T0;
- res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
+ res = (T0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count));
if (count > 1)
res |= T0 << (DATA_BITS + 1 - count);
T0 = res;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
((src >> (count - 1)) & CC_C);
CC_OP = CC_OP_EFLAGS;
}
void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
{
- int count, src;
- count = T1 & 0x1f;
+ int count;
+ target_long src;
+
+ count = T1 & SHIFT1_MASK;
if (count) {
src = (DATA_TYPE)T0 << (count - 1);
T0 = T0 << count;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = src;
CC_DST = T0;
void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
{
- int count, src;
- count = T1 & 0x1f;
+ int count;
+ target_long src;
+
+ count = T1 & SHIFT1_MASK;
if (count) {
T0 &= DATA_MASK;
src = T0 >> (count - 1);
T0 = T0 >> count;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = src;
CC_DST = T0;
void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
{
- int count, src;
- count = T1 & 0x1f;
+ int count;
+ target_long src;
+
+ count = T1 & SHIFT1_MASK;
if (count) {
src = (DATA_STYPE)T0;
T0 = src >> count;
src = src >> (count - 1);
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = src;
CC_DST = T0;
res |= T1 << (count - 16);
T0 = res >> 16;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
res |= T1 << (count - 16);
T0 = res >> 16;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
res |= T1 << (32 - count);
T0 = res;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
res |= T1 << (32 - count);
T0 = res;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
}
#endif
-#if DATA_BITS == 32
+#if DATA_BITS >= 32
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
{
- int count, tmp;
+ int count;
+ target_long tmp;
+
count = PARAM1;
T0 &= DATA_MASK;
T1 &= DATA_MASK;
tmp = T0 << (count - 1);
T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
{
- int count, tmp;
- count = ECX & 0x1f;
+ int count;
+ target_long tmp;
+
+ count = ECX & SHIFT1_MASK;
if (count) {
T0 &= DATA_MASK;
T1 &= DATA_MASK;
tmp = T0 << (count - 1);
T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
{
- int count, tmp;
+ int count;
+ target_long tmp;
+
count = PARAM1;
T0 &= DATA_MASK;
T1 &= DATA_MASK;
tmp = T0 >> (count - 1);
T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
{
- int count, tmp;
- count = ECX & 0x1f;
+ int count;
+ target_long tmp;
+
+ count = ECX & SHIFT1_MASK;
if (count) {
T0 &= DATA_MASK;
T1 &= DATA_MASK;
tmp = T0 >> (count - 1);
T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = tmp;
CC_DST = T0;
cf = cc_table[CC_OP].compute_c();
T0 = T0 + T1 + cf;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = T1;
CC_DST = T0;
- CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
+ CC_OP = CC_OP_ADDB + SHIFT + cf * 4;
}
void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
cf = cc_table[CC_OP].compute_c();
T0 = T0 - T1 - cf;
#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
+ glue(st, MEM_SUFFIX)(A0, T0);
#endif
CC_SRC = T1;
CC_DST = T0;
- CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
+ CC_OP = CC_OP_SUBB + SHIFT + cf * 4;
}
void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
{
- unsigned int src, dst;
+ target_ulong src, dst;
src = T0;
dst = EAX - T0;
if ((DATA_TYPE)dst == 0) {
T0 = T1;
+#ifdef MEM_WRITE
+ glue(st, MEM_SUFFIX)(A0, T0);
+#endif
} else {
EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
}
-#ifdef MEM_WRITE
- glue(st, SUFFIX)((uint8_t *)A0, T0);
-#endif
CC_SRC = src;
CC_DST = dst;
FORCE_RET();