[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 07/20] target/sparc: Remove CC_OP_TADDTV, CC_OP_TSUBTV
From: |
Richard Henderson |
Subject: |
[PATCH 07/20] target/sparc: Remove CC_OP_TADDTV, CC_OP_TSUBTV |
Date: |
Mon, 16 Oct 2023 23:40:56 -0700 |
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 2 -
target/sparc/cc_helper.c | 267 +--------------------------------------
target/sparc/helper.c | 40 ++++--
target/sparc/translate.c | 4 +-
4 files changed, 32 insertions(+), 281 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8498bd07db..27f7fed293 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -150,8 +150,6 @@ enum {
enum {
CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
CC_OP_FLAGS, /* all cc are back in cc_*_[NZCV] registers */
- CC_OP_TADDTV, /* modify all flags except V, CC_DST = res, CC_SRC = src1 */
- CC_OP_TSUBTV, /* modify all flags except V, CC_DST = res, CC_SRC = src1 */
CC_OP_NB,
};
diff --git a/target/sparc/cc_helper.c b/target/sparc/cc_helper.c
index d31aa24b5d..cebe03ff51 100644
--- a/target/sparc/cc_helper.c
+++ b/target/sparc/cc_helper.c
@@ -21,275 +21,12 @@
#include "cpu.h"
#include "exec/helper-proto.h"
-static inline uint32_t get_NZ_icc(int32_t dst)
-{
- uint32_t ret = 0;
-
- if (dst == 0) {
- ret = PSR_ZERO;
- } else if (dst < 0) {
- ret = PSR_NEG;
- }
- return ret;
-}
-
-#ifdef TARGET_SPARC64
-static inline uint32_t get_NZ_xcc(target_long dst)
-{
- uint32_t ret = 0;
-
- if (!dst) {
- ret = PSR_ZERO;
- } else if (dst < 0) {
- ret = PSR_NEG;
- }
- return ret;
-}
-#endif
-
-static inline uint32_t get_C_add_icc(uint32_t dst, uint32_t src1)
-{
- uint32_t ret = 0;
-
- if (dst < src1) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_C_addx_icc(uint32_t dst, uint32_t src1,
- uint32_t src2)
-{
- uint32_t ret = 0;
-
- if (((src1 & src2) | (~dst & (src1 | src2))) & (1U << 31)) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_V_add_icc(uint32_t dst, uint32_t src1,
- uint32_t src2)
-{
- uint32_t ret = 0;
-
- if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1U << 31)) {
- ret = PSR_OVF;
- }
- return ret;
-}
-
-#ifdef TARGET_SPARC64
-static inline uint32_t get_C_add_xcc(target_ulong dst, target_ulong src1)
-{
- uint32_t ret = 0;
-
- if (dst < src1) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_C_addx_xcc(target_ulong dst, target_ulong src1,
- target_ulong src2)
-{
- uint32_t ret = 0;
-
- if (((src1 & src2) | (~dst & (src1 | src2))) & (1ULL << 63)) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_V_add_xcc(target_ulong dst, target_ulong src1,
- target_ulong src2)
-{
- uint32_t ret = 0;
-
- if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 63)) {
- ret = PSR_OVF;
- }
- return ret;
-}
-
-static uint32_t compute_all_add_xcc(CPUSPARCState *env)
-{
- uint32_t ret;
-
- ret = get_NZ_xcc(CC_DST);
- ret |= get_C_add_xcc(CC_DST, CC_SRC);
- ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2);
- return ret;
-}
-
-static uint32_t compute_C_add_xcc(CPUSPARCState *env)
-{
- return get_C_add_xcc(CC_DST, CC_SRC);
-}
-#endif
-
-static uint32_t compute_C_add(CPUSPARCState *env)
-{
- return get_C_add_icc(CC_DST, CC_SRC);
-}
-
-static inline uint32_t get_V_tag_icc(target_ulong src1, target_ulong src2)
-{
- uint32_t ret = 0;
-
- if ((src1 | src2) & 0x3) {
- ret = PSR_OVF;
- }
- return ret;
-}
-
-static uint32_t compute_all_taddtv(CPUSPARCState *env)
-{
- uint32_t ret;
-
- ret = get_NZ_icc(CC_DST);
- ret |= get_C_add_icc(CC_DST, CC_SRC);
- return ret;
-}
-
-static inline uint32_t get_C_sub_icc(uint32_t src1, uint32_t src2)
-{
- uint32_t ret = 0;
-
- if (src1 < src2) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_C_subx_icc(uint32_t dst, uint32_t src1,
- uint32_t src2)
-{
- uint32_t ret = 0;
-
- if (((~src1 & src2) | (dst & (~src1 | src2))) & (1U << 31)) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_V_sub_icc(uint32_t dst, uint32_t src1,
- uint32_t src2)
-{
- uint32_t ret = 0;
-
- if (((src1 ^ src2) & (src1 ^ dst)) & (1U << 31)) {
- ret = PSR_OVF;
- }
- return ret;
-}
-
-
-#ifdef TARGET_SPARC64
-static inline uint32_t get_C_sub_xcc(target_ulong src1, target_ulong src2)
-{
- uint32_t ret = 0;
-
- if (src1 < src2) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_C_subx_xcc(target_ulong dst, target_ulong src1,
- target_ulong src2)
-{
- uint32_t ret = 0;
-
- if (((~src1 & src2) | (dst & (~src1 | src2))) & (1ULL << 63)) {
- ret = PSR_CARRY;
- }
- return ret;
-}
-
-static inline uint32_t get_V_sub_xcc(target_ulong dst, target_ulong src1,
- target_ulong src2)
-{
- uint32_t ret = 0;
-
- if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 63)) {
- ret = PSR_OVF;
- }
- return ret;
-}
-
-static uint32_t compute_all_sub_xcc(CPUSPARCState *env)
-{
- uint32_t ret;
-
- ret = get_NZ_xcc(CC_DST);
- ret |= get_C_sub_xcc(CC_SRC, CC_SRC2);
- ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2);
- return ret;
-}
-
-static uint32_t compute_C_sub_xcc(CPUSPARCState *env)
-{
- return get_C_sub_xcc(CC_SRC, CC_SRC2);
-}
-#endif
-
-static uint32_t compute_C_sub(CPUSPARCState *env)
-{
- return get_C_sub_icc(CC_SRC, CC_SRC2);
-}
-
-static uint32_t compute_all_tsubtv(CPUSPARCState *env)
-{
- uint32_t ret;
-
- ret = get_NZ_icc(CC_DST);
- ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
- return ret;
-}
-
-typedef struct CCTable {
- uint32_t (*compute_all)(CPUSPARCState *env); /* return all the flags */
- uint32_t (*compute_c)(CPUSPARCState *env); /* return the C flag */
-} CCTable;
-
-static const CCTable icc_table[CC_OP_NB] = {
- /* CC_OP_DYNAMIC should never happen */
- [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_add },
- [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_sub },
-};
-
-#ifdef TARGET_SPARC64
-static const CCTable xcc_table[CC_OP_NB] = {
- /* CC_OP_DYNAMIC should never happen */
- [CC_OP_TADDTV] = { compute_all_add_xcc, compute_C_add_xcc },
- [CC_OP_TSUBTV] = { compute_all_sub_xcc, compute_C_sub_xcc },
-};
-#endif
-
void helper_compute_psr(CPUSPARCState *env)
{
if (CC_OP == CC_OP_FLAGS) {
return;
}
-
- uint32_t icc = icc_table[CC_OP].compute_all(env);
-#ifdef TARGET_SPARC64
- uint32_t xcc = xcc_table[CC_OP].compute_all(env);
-
- env->cc_N = deposit64(-(icc & PSR_NEG), 32, 32, -(xcc & PSR_NEG));
- env->cc_V = deposit64(-(icc & PSR_OVF), 32, 32, -(xcc & PSR_OVF));
- env->cc_icc_C = (uint64_t)icc << (32 - PSR_CARRY_SHIFT);
- env->cc_xcc_C = (xcc >> PSR_CARRY_SHIFT) & 1;
- env->cc_xcc_Z = ~xcc & PSR_ZERO;
-#else
- env->cc_N = -(icc & PSR_NEG);
- env->cc_V = -(icc & PSR_OVF);
- env->cc_icc_C = (icc >> PSR_CARRY_SHIFT) & 1;
-#endif
- env->cc_icc_Z = ~icc & PSR_ZERO;
-
- CC_OP = CC_OP_FLAGS;
+ g_assert_not_reached();
}
uint32_t helper_compute_C_icc(CPUSPARCState *env)
@@ -301,5 +38,5 @@ uint32_t helper_compute_C_icc(CPUSPARCState *env)
return env->cc_icc_C;
#endif
}
- return icc_table[CC_OP].compute_c(env) >> PSR_CARRY_SHIFT;
+ g_assert_not_reached();
}
diff --git a/target/sparc/helper.c b/target/sparc/helper.c
index 87a4258792..4887f295a5 100644
--- a/target/sparc/helper.c
+++ b/target/sparc/helper.c
@@ -204,7 +204,7 @@ uint64_t helper_udivx(CPUSPARCState *env, uint64_t a,
uint64_t b)
target_ulong helper_taddcctv(CPUSPARCState *env, target_ulong src1,
target_ulong src2)
{
- target_ulong dst;
+ target_ulong dst, v;
/* Tag overflow occurs if either input has bits 0 or 1 set. */
if ((src1 | src2) & 3) {
@@ -214,15 +214,23 @@ target_ulong helper_taddcctv(CPUSPARCState *env,
target_ulong src1,
dst = src1 + src2;
/* Tag overflow occurs if the addition overflows. */
- if (~(src1 ^ src2) & (src1 ^ dst) & (1u << 31)) {
+ v = ~(src1 ^ src2) & (src1 ^ dst);
+ if (v & (1u << 31)) {
goto tag_overflow;
}
/* Only modify the CC after any exceptions have been generated. */
- env->cc_op = CC_OP_TADDTV;
- env->cc_src = src1;
- env->cc_src2 = src2;
- env->cc_dst = dst;
+ env->cc_V = v;
+ env->cc_N = dst;
+ env->cc_icc_Z = dst;
+#ifdef TARGET_SPARC64
+ env->cc_xcc_Z = dst;
+ env->cc_icc_C = dst ^ src1 ^ src2;
+ env->cc_xcc_C = dst < src1;
+#else
+ env->cc_icc_C = dst < src1;
+#endif
+
return dst;
tag_overflow:
@@ -232,7 +240,7 @@ target_ulong helper_taddcctv(CPUSPARCState *env,
target_ulong src1,
target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1,
target_ulong src2)
{
- target_ulong dst;
+ target_ulong dst, v;
/* Tag overflow occurs if either input has bits 0 or 1 set. */
if ((src1 | src2) & 3) {
@@ -242,15 +250,23 @@ target_ulong helper_tsubcctv(CPUSPARCState *env,
target_ulong src1,
dst = src1 - src2;
/* Tag overflow occurs if the subtraction overflows. */
- if ((src1 ^ src2) & (src1 ^ dst) & (1u << 31)) {
+ v = (src1 ^ src2) & (src1 ^ dst);
+ if (v & (1u << 31)) {
goto tag_overflow;
}
/* Only modify the CC after any exceptions have been generated. */
- env->cc_op = CC_OP_TSUBTV;
- env->cc_src = src1;
- env->cc_src2 = src2;
- env->cc_dst = dst;
+ env->cc_V = v;
+ env->cc_N = dst;
+ env->cc_icc_Z = dst;
+#ifdef TARGET_SPARC64
+ env->cc_xcc_Z = dst;
+ env->cc_icc_C = dst ^ src1 ^ src2;
+ env->cc_xcc_C = src1 < src2;
+#else
+ env->cc_icc_C = src1 < src2;
+#endif
+
return dst;
tag_overflow:
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ff523a4e7d..d8cb669592 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3700,8 +3700,8 @@ TRANS(UDIVcc, DIV, do_flags_arith, a, CC_OP_FLAGS,
gen_op_udivcc)
TRANS(SDIVcc, DIV, do_flags_arith, a, CC_OP_FLAGS, gen_op_sdivcc)
TRANS(TADDcc, ALL, do_flags_arith, a, CC_OP_FLAGS, gen_op_taddcc)
TRANS(TSUBcc, ALL, do_flags_arith, a, CC_OP_FLAGS, gen_op_tsubcc)
-TRANS(TADDccTV, ALL, do_flags_arith, a, CC_OP_TADDTV, gen_op_taddcctv)
-TRANS(TSUBccTV, ALL, do_flags_arith, a, CC_OP_TSUBTV, gen_op_tsubcctv)
+TRANS(TADDccTV, ALL, do_flags_arith, a, CC_OP_FLAGS, gen_op_taddcctv)
+TRANS(TSUBccTV, ALL, do_flags_arith, a, CC_OP_FLAGS, gen_op_tsubcctv)
static TCGv gen_rs2_or_imm(DisasContext *dc, bool imm, int rs2_or_imm)
{
--
2.34.1
- [PATCH 00/20] target/sparc: Cleanup condition codes etc, Richard Henderson, 2023/10/17
- [PATCH 01/20] target/sparc: Introduce cpu_put_psr_icc, Richard Henderson, 2023/10/17
- [PATCH 02/20] target/sparc: Split psr and xcc into components, Richard Henderson, 2023/10/17
- [PATCH 03/20] target/sparc: Remove CC_OP_DIV, Richard Henderson, 2023/10/17
- [PATCH 04/20] target/sparc: Remove CC_OP_LOGIC, Richard Henderson, 2023/10/17
- [PATCH 05/20] target/sparc: Remove CC_OP_ADD, CC_OP_ADDX, CC_OP_TADD, Richard Henderson, 2023/10/17
- [PATCH 07/20] target/sparc: Remove CC_OP_TADDTV, CC_OP_TSUBTV,
Richard Henderson <=
- [PATCH 09/20] target/sparc: Remove DisasCompare.is_bool, Richard Henderson, 2023/10/17
- [PATCH 08/20] target/sparc: Remove CC_OP leftovers, Richard Henderson, 2023/10/17
- [PATCH 12/20] target/sparc: Do flush_cond in advance_jump_cond, Richard Henderson, 2023/10/17
- [PATCH 18/20] target/sparc: Discard cpu_cond at the end of each insn, Richard Henderson, 2023/10/17
- [PATCH 16/20] target/sparc: Merge gen_op_next_insn into only caller, Richard Henderson, 2023/10/17
- [PATCH 19/20] target/sparc: Implement UDIVX and SDIVX inline, Richard Henderson, 2023/10/17
- [PATCH 20/20] target/sparc: Implement UDIV inline, Richard Henderson, 2023/10/17
- [PATCH 13/20] target/sparc: Merge gen_branch2 into advance_pc, Richard Henderson, 2023/10/17
- [PATCH 15/20] target/sparc: Use DISAS_EXIT in do_wrpsr, Richard Henderson, 2023/10/17
- [PATCH 17/20] target/sparc: Record entire jump condition in DisasContext, Richard Henderson, 2023/10/17