On 5/11/10, Richard Henderson <r...@twiddle.net> 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 <r...@twiddle.net> > --- > 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 > >