Le 28/11/2016 à 15:54, Richard Henderson a écrit : > On 11/27/2016 11:35 AM, Laurent Vivier wrote: >>>> + tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64); >> This does not extract correctly the C flag when the opsize is word or byte. >> I think we should use a shift instead: >> >> - tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64); >> - >> - /* Note that C=0 if shift count is 0, and we get that for free. */ >> + if (opsize == OS_LONG) { >> + tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64); >> + /* Note that C=0 if shift count is 0, and we get that for >> free. */ >> + } else { >> + TCGv zero = tcg_const_i32(0); >> + tcg_gen_extrl_i64_i32(QREG_CC_N, t64); >> + tcg_gen_shri_i64(t64, t64, bits); >> + tcg_gen_extrl_i64_i32(QREG_CC_C, t64); >> + tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C, >> + s32, zero, zero, QREG_CC_C); >> + tcg_temp_free(zero); >> + } >> >> Do you have a better idea? > > if (opsize == OS_LONG) { > tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64); > } else { > tcg_gen_extrl_i64_i32(QREG_CC_N, t64); > tcg_gen_shri_i32(QREG_CC_C, QREG_CC_N, bits); > } > > Since we zero-extend the input from bits, it's still true that a zero shift > gets C=0 for free. >
It doesn't work because we work with word/byte where the bit sign has been extended to the long word. So in the case of 0 shift, with retrieve C=<original bit sign> and not 0. Laurent