Le 09/11/2016 à 14:46, Richard Henderson a écrit : > diff --git a/target-m68k/translate.c b/target-m68k/translate.c > index 4f224d7..1b3765f 100644 > --- a/target-m68k/translate.c > +++ b/target-m68k/translate.c
> +static inline void shift_reg(DisasContext *s, uint16_t insn, int opsize) > +{ > + int logical = insn & 8; > + int left = insn & 0x100; > + int bits = opsize_bytes(opsize) * 8; > + TCGv reg = gen_extend(DREG(insn, 0), opsize, !logical); > + TCGv s32; > + TCGv_i64 t64, s64; > + > + t64 = tcg_temp_new_i64(); > + s64 = tcg_temp_new_i64(); > + s32 = tcg_temp_new(); > + > + /* Note that m68k truncates the shift count modulo 64, not 32. > + In addition, a 64-bit shift makes it easy to find "the last > + bit shifted out", for the carry flag. */ > + tcg_gen_andi_i32(s32, DREG(insn, 9), 63); > + tcg_gen_extu_i32_i64(s64, s32); > + tcg_gen_extu_i32_i64(t64, reg); > + > + /* Optimistically set V=0. Also used as a zero source below. */ > + tcg_gen_movi_i32(QREG_CC_V, 0); > + if (left) { > + tcg_gen_shl_i64(t64, t64, s64); > + > + 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? thanks, Laurent