[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: [PATCH 2/3] target-sparc: Simplify ICC generation; fix
From: |
Blue Swirl |
Subject: |
[Qemu-devel] Re: [PATCH 2/3] target-sparc: Simplify ICC generation; fix ADDX carry generation. |
Date: |
Tue, 11 May 2010 22:14:27 +0300 |
On 5/11/10, Richard Henderson <address@hidden> wrote:
> Use int32 types instead of target_ulong when computing ICC. This
> simplifies the generated code for 32-bit host and 64-bit guest.
> Use the same simplified expressions for ICC as were already used
> for XCC in carry flag generation.
>
> ADDX ICC carry generation was using the same routines as ADD ICC,
> which is incorrect if the input carry bit produces the output carry.
> Use the algorithms already in place for ADDX XCC carry generation.
> Similarly for SUBX.
>
> Signed-off-by: Richard Henderson <address@hidden>
> ---
> target-sparc/op_helper.c | 106
> ++++++++++++++++++++++++++++++----------------
> 1 files changed, 69 insertions(+), 37 deletions(-)
>
> diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
> index 09449c5..c36bc54 100644
> --- a/target-sparc/op_helper.c
> +++ b/target-sparc/op_helper.c
> @@ -896,13 +896,13 @@ static uint32_t compute_C_flags(void)
> return env->psr & PSR_CARRY;
> }
>
> -static inline uint32_t get_NZ_icc(target_ulong dst)
> +static inline uint32_t get_NZ_icc(int32_t dst)
> {
> uint32_t ret = 0;
>
> - if (!(dst & 0xffffffffULL))
> + if (dst == 0)
Could you add the braces to fix CODING_STYLE while at it?
> ret |= PSR_ZERO;
> - if ((int32_t) (dst & 0xffffffffULL) < 0)
> + if (dst < 0)
> ret |= PSR_NEG;
> return ret;
> }
> @@ -918,13 +918,13 @@ static uint32_t compute_C_flags_xcc(void)
> return env->xcc & PSR_CARRY;
> }
>
> -static inline uint32_t get_NZ_xcc(target_ulong dst)
> +static inline uint32_t get_NZ_xcc(target_long dst)
> {
> uint32_t ret = 0;
>
> if (!dst)
> ret |= PSR_ZERO;
> - if ((int64_t)dst < 0)
> + if (dst < 0)
> ret |= PSR_NEG;
> return ret;
> }
> @@ -953,25 +953,21 @@ static uint32_t compute_C_div(void)
> return 0;
> }
>
> -/* carry = (src1[31] & src2[31]) | ( ~dst[31] & (src1[31] | src2[31])) */
> -static inline uint32_t get_C_add_icc(target_ulong dst, target_ulong src1,
> - target_ulong src2)
> +static inline uint32_t get_C_add_icc(uint32_t dst, uint32_t src1)
> {
> uint32_t ret = 0;
>
> - if (((src1 & (1ULL << 31)) & (src2 & (1ULL << 31)))
> - | ((~(dst & (1ULL << 31)))
> - & ((src1 & (1ULL << 31)) | (src2 & (1ULL << 31)))))
> + if (dst < src1)
> ret |= PSR_CARRY;
> return ret;
> }
>
> -static inline uint32_t get_V_add_icc(target_ulong dst, target_ulong src1,
> - target_ulong src2)
> +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)) & (1ULL << 31))
> + if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1U << 31))
> ret |= PSR_OVF;
> return ret;
> }
> @@ -1017,14 +1013,14 @@ static uint32_t compute_all_add(void)
> uint32_t ret;
>
> ret = get_NZ_icc(CC_DST);
> - ret |= get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
> + ret |= get_C_add_icc(CC_DST, CC_SRC);
> ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
> return ret;
> }
>
> static uint32_t compute_C_add(void)
> {
> - return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
> + return get_C_add_icc(CC_DST, CC_SRC);
> }
>
> #ifdef TARGET_SPARC64
> @@ -1049,6 +1045,26 @@ static uint32_t compute_C_addx_xcc(void)
> }
> #endif
>
> +static uint32_t compute_all_addx(void)
> +{
> + uint32_t ret;
> +
> + ret = get_NZ_icc(CC_DST);
> + ret |= get_C_add_icc(CC_DST - CC_SRC2, CC_SRC);
> + ret |= get_C_add_icc(CC_DST, CC_SRC);
> + ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
> + return ret;
> +}
> +
> +static uint32_t compute_C_addx(void)
> +{
> + uint32_t ret;
> +
> + ret = get_C_add_icc(CC_DST - CC_SRC2, CC_SRC);
> + ret |= get_C_add_icc(CC_DST, CC_SRC);
> + return ret;
> +}
> +
> static inline uint32_t get_V_tag_icc(target_ulong src1, target_ulong src2)
> {
> uint32_t ret = 0;
> @@ -1063,7 +1079,7 @@ static uint32_t compute_all_tadd(void)
> uint32_t ret;
>
> ret = get_NZ_icc(CC_DST);
> - ret |= get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
> + ret |= get_C_add_icc(CC_DST, CC_SRC);
> ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
> ret |= get_V_tag_icc(CC_SRC, CC_SRC2);
> return ret;
> @@ -1071,7 +1087,7 @@ static uint32_t compute_all_tadd(void)
>
> static uint32_t compute_C_tadd(void)
> {
> - return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
> + return get_C_add_icc(CC_DST, CC_SRC);
> }
>
> static uint32_t compute_all_taddtv(void)
> @@ -1079,34 +1095,30 @@ static uint32_t compute_all_taddtv(void)
> uint32_t ret;
>
> ret = get_NZ_icc(CC_DST);
> - ret |= get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
> + ret |= get_C_add_icc(CC_DST, CC_SRC);
> return ret;
> }
>
> static uint32_t compute_C_taddtv(void)
> {
> - return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
> + return get_C_add_icc(CC_DST, CC_SRC);
> }
>
> -/* carry = (~src1[31] & src2[31]) | ( dst[31] & (~src1[31] | src2[31])) */
> -static inline uint32_t get_C_sub_icc(target_ulong dst, target_ulong src1,
> - target_ulong src2)
> +static inline uint32_t get_C_sub_icc(uint32_t src1, uint32_t src2)
> {
> uint32_t ret = 0;
>
> - if (((~(src1 & (1ULL << 31))) & (src2 & (1ULL << 31)))
> - | ((dst & (1ULL << 31)) & (( ~(src1 & (1ULL << 31)))
> - | (src2 & (1ULL << 31)))))
> + if (src1 < src2)
> ret |= PSR_CARRY;
> return ret;
> }
>
> -static inline uint32_t get_V_sub_icc(target_ulong dst, target_ulong src1,
> - target_ulong src2)
> +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)) & (1ULL << 31))
> + if (((src1 ^ src2) & (src1 ^ dst)) & (1U << 31))
> ret |= PSR_OVF;
> return ret;
> }
> @@ -1153,14 +1165,14 @@ static uint32_t compute_all_sub(void)
> uint32_t ret;
>
> ret = get_NZ_icc(CC_DST);
> - ret |= get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> + ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
> ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> return ret;
> }
>
> static uint32_t compute_C_sub(void)
> {
> - return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> + return get_C_sub_icc(CC_SRC, CC_SRC2);
> }
>
> #ifdef TARGET_SPARC64
> @@ -1185,12 +1197,32 @@ static uint32_t compute_C_subx_xcc(void)
> }
> #endif
>
> +static uint32_t compute_all_subx(void)
> +{
> + uint32_t ret;
> +
> + ret = get_NZ_icc(CC_DST);
> + ret |= get_C_sub_icc(CC_DST - CC_SRC2, CC_SRC);
> + ret |= get_C_sub_icc(CC_DST, CC_SRC2);
> + ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> + return ret;
> +}
> +
> +static uint32_t compute_C_subx(void)
> +{
> + uint32_t ret;
> +
> + ret = get_C_sub_icc(CC_DST - CC_SRC2, CC_SRC);
> + ret |= get_C_sub_icc(CC_DST, CC_SRC2);
> + return ret;
> +}
> +
> static uint32_t compute_all_tsub(void)
> {
> uint32_t ret;
>
> ret = get_NZ_icc(CC_DST);
> - ret |= get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> + ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
> ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> ret |= get_V_tag_icc(CC_SRC, CC_SRC2);
> return ret;
> @@ -1198,7 +1230,7 @@ static uint32_t compute_all_tsub(void)
>
> static uint32_t compute_C_tsub(void)
> {
> - return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> + return get_C_sub_icc(CC_SRC, CC_SRC2);
> }
>
> static uint32_t compute_all_tsubtv(void)
> @@ -1206,13 +1238,13 @@ static uint32_t compute_all_tsubtv(void)
> uint32_t ret;
>
> ret = get_NZ_icc(CC_DST);
> - ret |= get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> + ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
> return ret;
> }
>
> static uint32_t compute_C_tsubtv(void)
> {
> - return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
> + return get_C_sub_icc(CC_SRC, CC_SRC2);
> }
>
> static uint32_t compute_all_logic(void)
> @@ -1242,11 +1274,11 @@ static const CCTable icc_table[CC_OP_NB] = {
> [CC_OP_FLAGS] = { compute_all_flags, compute_C_flags },
> [CC_OP_DIV] = { compute_all_div, compute_C_div },
> [CC_OP_ADD] = { compute_all_add, compute_C_add },
> - [CC_OP_ADDX] = { compute_all_add, compute_C_add },
> + [CC_OP_ADDX] = { compute_all_addx, compute_C_addx },
> [CC_OP_TADD] = { compute_all_tadd, compute_C_tadd },
> [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_taddtv },
> [CC_OP_SUB] = { compute_all_sub, compute_C_sub },
> - [CC_OP_SUBX] = { compute_all_sub, compute_C_sub },
> + [CC_OP_SUBX] = { compute_all_subx, compute_C_subx },
> [CC_OP_TSUB] = { compute_all_tsub, compute_C_tsub },
> [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_tsubtv },
> [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic },
>
> --
> 1.7.0.1
>
>
[Qemu-devel] [PATCH 1/3] target-sparc: Fix compilation with --enable-debug., Richard Henderson, 2010/05/10
[Qemu-devel] [PATCH 3/3] target-sparc: Inline some generation of carry for ADDX/SUBX., Richard Henderson, 2010/05/10
[Qemu-devel] [PATCH 0/3] Fix ADDX compilation plus improvements, v2, Richard Henderson, 2010/05/12