2010/5/12 Richard Henderson <r...@twiddle.net>: > 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. > > Simplify the ADD carry generation to not consider a possible carry-in. > Use the more complex carry computation for ADDX only. Use the same > carry algorithm for the XCC result of ADDX. Similarly for SUB/SUBX. > > Use the ADD carry generation functions for TADD/TADDTV. Similarly > for SUB and TSUB/TSUBTV. > > Tidy the code with respect to CODING_STYLE. > > Signed-off-by: Richard Henderson <r...@twiddle.net> > --- > target-sparc/op_helper.c | 220 > +++++++++++++++++++++++++++++----------------- > 1 files changed, 140 insertions(+), 80 deletions(-) > > diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c > index 09449c5..3783b02 100644 > --- a/target-sparc/op_helper.c > +++ b/target-sparc/op_helper.c > @@ -896,14 +896,15 @@ 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)) > - ret |= PSR_ZERO; > - if ((int32_t) (dst & 0xffffffffULL) < 0) > - ret |= PSR_NEG; > + if (dst == 0) { > + ret = PSR_ZERO; > + } else if (dst < 0) { > + ret = PSR_NEG; > + } > return ret; > } > > @@ -918,14 +919,15 @@ 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) > - ret |= PSR_NEG; > + if (!dst) { > + ret = PSR_ZERO; > + } else if (dst < 0) { > + ret = PSR_NEG; > + } > return ret; > } > #endif > @@ -934,8 +936,9 @@ static inline uint32_t get_V_div_icc(target_ulong src2) > { > uint32_t ret = 0; > > - if (src2 != 0) > - ret |= PSR_OVF; > + if (src2 != 0) { > + ret = PSR_OVF; > + } > return ret; > } > > @@ -953,26 +956,35 @@ 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))))) > - ret |= PSR_CARRY; > + 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_C_addx_icc(uint32_t dst, uint32_t src1, > + uint32_t src2) > { > uint32_t ret = 0; > > - if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 31)) > - ret |= PSR_OVF; > + 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; > } > > @@ -981,8 +993,20 @@ static inline uint32_t get_C_add_xcc(target_ulong dst, > target_ulong src1) > { > uint32_t ret = 0; > > - if (dst < src1) > - ret |= PSR_CARRY; > + 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; > } > > @@ -991,8 +1015,9 @@ static inline uint32_t get_V_add_xcc(target_ulong dst, > target_ulong src1, > { > uint32_t ret = 0; > > - if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 63)) > - ret |= PSR_OVF; > + if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 63)) { > + ret = PSR_OVF; > + } > return ret; > } > > @@ -1017,14 +1042,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 > @@ -1033,8 +1058,7 @@ static uint32_t compute_all_addx_xcc(void) > uint32_t ret; > > ret = get_NZ_xcc(CC_DST); > - ret |= get_C_add_xcc(CC_DST - CC_SRC2, CC_SRC); > - ret |= get_C_add_xcc(CC_DST, CC_SRC); > + ret |= get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2); > ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2); > return ret; > } > @@ -1043,18 +1067,36 @@ static uint32_t compute_C_addx_xcc(void) > { > uint32_t ret; > > - ret = get_C_add_xcc(CC_DST - CC_SRC2, CC_SRC); > - ret |= get_C_add_xcc(CC_DST, CC_SRC); > + ret = get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2); > return ret; > } > #endif > > +static uint32_t compute_all_addx(void) > +{ > + uint32_t ret; > + > + ret = get_NZ_icc(CC_DST); > + ret |= get_C_addx_icc(CC_DST, CC_SRC, CC_SRC2); > + 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_addx_icc(CC_DST, CC_SRC, CC_SRC2); > + return ret; > +} > + > 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; > + if ((src1 | src2) & 0x3) { > + ret = PSR_OVF; > + } > return ret; > } > > @@ -1063,51 +1105,50 @@ 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; > } > > -static uint32_t compute_C_tadd(void) > -{ > - return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2); > -} > - > 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) > +static inline uint32_t get_C_sub_icc(uint32_t src1, uint32_t src2) > { > - return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2); > + uint32_t ret = 0; > + > + if (src1 < src2) { > + ret = PSR_CARRY; > + } > + return ret; > } > > -/* 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_subx_icc(uint32_t dst, 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))))) > - ret |= PSR_CARRY; > + if (((~src1 & src2) | (dst & (~src1 | src2))) & (1U << 31)) { > + 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)) > - ret |= PSR_OVF; > + if (((src1 ^ src2) & (src1 ^ dst)) & (1U << 31)) { > + ret = PSR_OVF; > + } > return ret; > } > > @@ -1117,8 +1158,20 @@ static inline uint32_t get_C_sub_xcc(target_ulong > src1, target_ulong src2) > { > uint32_t ret = 0; > > - if (src1 < src2) > - ret |= PSR_CARRY; > + 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; > } > > @@ -1127,8 +1180,9 @@ static inline uint32_t get_V_sub_xcc(target_ulong dst, > target_ulong src1, > { > uint32_t ret = 0; > > - if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 63)) > - ret |= PSR_OVF; > + if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 63)) { > + ret = PSR_OVF; > + } > return ret; > } > > @@ -1153,14 +1207,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 > @@ -1169,8 +1223,7 @@ static uint32_t compute_all_subx_xcc(void) > uint32_t ret; > > ret = get_NZ_xcc(CC_DST); > - ret |= get_C_sub_xcc(CC_DST - CC_SRC2, CC_SRC); > - ret |= get_C_sub_xcc(CC_DST, CC_SRC2); > + ret |= get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2); > ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2); > return ret; > } > @@ -1179,40 +1232,47 @@ static uint32_t compute_C_subx_xcc(void) > { > uint32_t ret; > > - ret = get_C_sub_xcc(CC_DST - CC_SRC2, CC_SRC); > - ret |= get_C_sub_xcc(CC_DST, CC_SRC2); > + ret = get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2); > return ret; > } > #endif > > -static uint32_t compute_all_tsub(void) > +static uint32_t compute_all_subx(void) > { > uint32_t ret; > > ret = get_NZ_icc(CC_DST); > - ret |= get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2); > + ret |= get_C_subx_icc(CC_DST, 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; > } > > -static uint32_t compute_C_tsub(void) > +static uint32_t compute_C_subx(void) > { > - return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2); > + uint32_t ret; > + > + ret = get_C_subx_icc(CC_DST, CC_SRC, CC_SRC2); > + return ret; > } > > -static uint32_t compute_all_tsubtv(void) > +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; > } > > -static uint32_t compute_C_tsubtv(void) > +static uint32_t compute_all_tsubtv(void) > { > - return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2); > + uint32_t ret; > + > + ret = get_NZ_icc(CC_DST); > + ret |= get_C_sub_icc(CC_SRC, CC_SRC2); > + return ret; > } > > static uint32_t compute_all_logic(void) > @@ -1242,13 +1302,13 @@ 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_TADD] = { compute_all_tadd, compute_C_tadd }, > - [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_taddtv }, > + [CC_OP_ADDX] = { compute_all_addx, compute_C_addx }, > + [CC_OP_TADD] = { compute_all_tadd, compute_C_add }, > + [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_add }, > [CC_OP_SUB] = { compute_all_sub, compute_C_sub }, > - [CC_OP_SUBX] = { compute_all_sub, compute_C_sub }, > - [CC_OP_TSUB] = { compute_all_tsub, compute_C_tsub }, > - [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_tsubtv }, > + [CC_OP_SUBX] = { compute_all_subx, compute_C_subx }, > + [CC_OP_TSUB] = { compute_all_tsub, compute_C_sub }, > + [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_sub }, > [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic }, > }; > > -- > 1.7.0.1 > >
This one looks much better and passes the smoke test. Haven't tested 3/3 yet. -- Regards, Artyom Tarasenko solaris/sparc under qemu blog: http://tyom.blogspot.com/