[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 046/111] m68k: improve asl/asr evaluate correclty th
From: |
Bryce Lanham |
Subject: |
[Qemu-devel] [PATCH 046/111] m68k: improve asl/asr evaluate correclty the missing V flag |
Date: |
Wed, 17 Aug 2011 15:46:51 -0500 |
From: Laurent Vivier <address@hidden>
Signed-off-by: Laurent Vivier <address@hidden>
---
target-m68k/helper.c | 49 ++++++++++++++++++++++++++++++++++++++++++----
target-m68k/helpers.h | 3 ++
target-m68k/translate.c | 36 ++++++++++++++++++++++++++++-----
3 files changed, 77 insertions(+), 11 deletions(-)
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 8bf4920..bdfe9aa 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -327,8 +327,7 @@ void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
#define SET_FLAGS_SHIFT(type) do { \
SET_NZ(dest, type); \
- if (src) \
- flags |= CCF_C; \
+ flags |= src; \
} while(0)
flags = 0;
@@ -751,7 +750,7 @@ uint32_t HELPER(glue(glue(shl, bits),_cc))(CPUState *env,
uint32_t val, uint32_t
result = 0; \
cf = 0; \
} \
- env->cc_src = cf; \
+ env->cc_src = cf ? CCF_C : 0; \
if (shift) env->cc_x = (cf != 0); \
env->cc_dest = result; \
return result; \
@@ -780,7 +779,7 @@ uint32_t HELPER(glue(glue(shr, bits), _cc))(CPUState *env,
uint32_t val, uint32_
result = 0; \
cf = 0; \
} \
- env->cc_src = cf; \
+ env->cc_src = cf ? CCF_C : 0; \
if (shift) env->cc_x = (cf != 0); \
env->cc_dest = result; \
return result; \
@@ -790,6 +789,46 @@ HELPER_SHR(uint8_t, 8)
HELPER_SHR(uint16_t, 16)
HELPER_SHR(uint32_t, 32)
+#define HELPER_SAL(type, bits) \
+uint32_t HELPER(glue(glue(sal, bits),_cc))(CPUState *env, uint32_t val,
uint32_t shift) \
+{ \
+ type result; \
+ uint32_t cf; \
+ uint32_t vf; \
+ uint32_t m; \
+ shift &= 63; \
+ if (shift == 0) { \
+ vf = 0; \
+ } else if (shift < bits) { \
+ m = ((1llu << (shift + 1)) - 1) << (bits - shift - 1); \
+ vf = (val & m) != m && (val & m) != 0; \
+ } else {\
+ m = (1llu << bits) - 1; \
+ vf = (val & m) != 0; \
+ }\
+ if (shift == 0) { \
+ result = (type)val; \
+ cf = env->cc_src & CCF_C; \
+ } else if (shift < bits) { \
+ result = (type)val << shift; \
+ cf = ((type)val >> (bits - shift)) & 1; \
+ } else if (shift == bits) { \
+ result = 0; \
+ cf = val & 1; \
+ } else /* shift > bits */ { \
+ result = 0; \
+ cf = 0; \
+ } \
+ env->cc_src = (cf ? CCF_C : 0) | (vf ? CCF_V : 0); \
+ if (shift) env->cc_x = (cf != 0); \
+ env->cc_dest = result; \
+ return result; \
+}
+
+HELPER_SAL(int8_t, 8)
+HELPER_SAL(int16_t, 16)
+HELPER_SAL(int32_t, 32)
+
#define HELPER_SAR(type, bits) \
uint32_t HELPER(glue(glue(sar, bits), _cc))(CPUState *env, uint32_t val,
uint32_t shift) \
{ \
@@ -806,7 +845,7 @@ uint32_t HELPER(glue(glue(sar, bits), _cc))(CPUState *env,
uint32_t val, uint32_
result = (type)val >> (bits - 1); \
cf = (type)val >> (bits - 1); \
} \
- env->cc_src = cf; \
+ env->cc_src = cf ? CCF_C : 0; \
if (shift) env->cc_x = (cf != 0); \
env->cc_dest = result; \
return result; \
diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h
index 8f6d333..aa835eb 100644
--- a/target-m68k/helpers.h
+++ b/target-m68k/helpers.h
@@ -26,6 +26,9 @@ DEF_HELPER_3(shl32_cc, i32, env, i32, i32)
DEF_HELPER_3(shr8_cc, i32, env, i32, i32)
DEF_HELPER_3(shr16_cc, i32, env, i32, i32)
DEF_HELPER_3(shr32_cc, i32, env, i32, i32)
+DEF_HELPER_3(sal8_cc, i32, env, i32, i32)
+DEF_HELPER_3(sal16_cc, i32, env, i32, i32)
+DEF_HELPER_3(sal32_cc, i32, env, i32, i32)
DEF_HELPER_3(sar8_cc, i32, env, i32, i32)
DEF_HELPER_3(sar16_cc, i32, env, i32, i32)
DEF_HELPER_3(sar32_cc, i32, env, i32, i32)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index bc1cf04..37ee841 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2298,7 +2298,11 @@ DISAS_INSN(shift8_im)
dest = tcg_temp_new_i32();
/* No need to flush flags becuse we know we will set C flag. */
if (insn & 0x100) {
- gen_helper_shl8_cc(dest, cpu_env, reg, shift);
+ if (insn & 8) {
+ gen_helper_shl8_cc(dest, cpu_env, reg, shift);
+ } else {
+ gen_helper_sal8_cc(dest, cpu_env, reg, shift);
+ }
} else {
if (insn & 8) {
gen_helper_shr8_cc(dest, cpu_env, reg, shift);
@@ -2326,7 +2330,11 @@ DISAS_INSN(shift16_im)
dest = tcg_temp_new_i32();
/* No need to flush flags becuse we know we will set C flag. */
if (insn & 0x100) {
- gen_helper_shl16_cc(dest, cpu_env, reg, shift);
+ if (insn & 8) {
+ gen_helper_shl16_cc(dest, cpu_env, reg, shift);
+ } else {
+ gen_helper_sal16_cc(dest, cpu_env, reg, shift);
+ }
} else {
if (insn & 8) {
gen_helper_shr16_cc(dest, cpu_env, reg, shift);
@@ -2353,7 +2361,11 @@ DISAS_INSN(shift_im)
shift = tcg_const_i32(tmp);
/* No need to flush flags becuse we know we will set C flag. */
if (insn & 0x100) {
- gen_helper_shl32_cc(reg, cpu_env, reg, shift);
+ if (insn & 8) {
+ gen_helper_shl32_cc(reg, cpu_env, reg, shift);
+ } else {
+ gen_helper_sal32_cc(reg, cpu_env, reg, shift);
+ }
} else {
if (insn & 8) {
gen_helper_shr32_cc(reg, cpu_env, reg, shift);
@@ -2379,7 +2391,11 @@ DISAS_INSN(shift8_reg)
/* Shift by zero leaves C flag unmodified. */
gen_flush_flags(s);
if (insn & 0x100) {
- gen_helper_shl8_cc(dest, cpu_env, reg, tmp);
+ if (insn & 8) {
+ gen_helper_shl8_cc(dest, cpu_env, reg, tmp);
+ } else {
+ gen_helper_sal8_cc(dest, cpu_env, reg, tmp);
+ }
} else {
if (insn & 8) {
gen_helper_shr8_cc(dest, cpu_env, reg, tmp);
@@ -2406,7 +2422,11 @@ DISAS_INSN(shift16_reg)
/* Shift by zero leaves C flag unmodified. */
gen_flush_flags(s);
if (insn & 0x100) {
- gen_helper_shl16_cc(dest, cpu_env, reg, tmp);
+ if (insn & 8) {
+ gen_helper_shl16_cc(dest, cpu_env, reg, tmp);
+ } else {
+ gen_helper_sal16_cc(dest, cpu_env, reg, tmp);
+ }
} else {
if (insn & 8) {
gen_helper_shr16_cc(dest, cpu_env, reg, tmp);
@@ -2428,7 +2448,11 @@ DISAS_INSN(shift_reg)
/* Shift by zero leaves C flag unmodified. */
gen_flush_flags(s);
if (insn & 0x100) {
- gen_helper_shl32_cc(reg, cpu_env, reg, shift);
+ if (insn & 8) {
+ gen_helper_shl32_cc(reg, cpu_env, reg, shift);
+ } else {
+ gen_helper_sal32_cc(reg, cpu_env, reg, shift);
+ }
} else {
if (insn & 8) {
gen_helper_shr32_cc(reg, cpu_env, reg, shift);
--
1.7.2.3
- [Qemu-devel] [PATCH 086/111] m68k: correct bfins instruction, (continued)
- [Qemu-devel] [PATCH 086/111] m68k: correct bfins instruction, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 025/111] m68k: add cas, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 067/111] m68k: add fscale, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 033/111] m68k: Add fmovecr, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 058/111] m68k: correctly compute divul, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 069/111] m68k: add fetox and flogn, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 048/111] m68k: correct shift side effect for roxrl and roxll, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 065/111] m68k: correct compute gen_bitfield_cc(), Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 049/111] m68k: asl/asr, clear C flag if shift count is 0, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 044/111] m68k: improve addx instructions Add (byte, word) opsize Add memory access, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 046/111] m68k: improve asl/asr evaluate correclty the missing V flag,
Bryce Lanham <=
- [Qemu-devel] [PATCH 023/111] m68k: add variable offset/width to bitfield_reg/bitfield_mem, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 081/111] m68k: correct fpcr update, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 063/111] m68k: some FPU debugging macros, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 066/111] m68k: add fgetexp, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 051/111] m68k: correct divs.w and divu.w, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 071/111] m68k: correct cmpa comparison datatype, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 061/111] m68k: remove useless file m68k-qreg.h, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 059/111] m68k: add m68030 definition, Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 034/111] m68k: correct typo on f64_to_i32() return type., Bryce Lanham, 2011/08/17
- [Qemu-devel] [PATCH 052/111] m68k: correct flags with negl, Bryce Lanham, 2011/08/17