In expr.c, convert_move() tries to synthesize sign extension in modes larger than those directly supported by the target. There are two strategies for generating the sign bit copies:
1) Compare with 0 and use "slt" if STORE_FLAG_VALUE == -1. 2) Use a signed right shift of one bit less than the operand width. /* Compute the value to put in each remaining word. */ if (unsignedp) fill_value = const0_rtx; else { #ifdef HAVE_slt if (HAVE_slt && insn_data[(int) CODE_FOR_slt].operand[0].mode == word_mode && STORE_FLAG_VALUE == -1) { emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX, lowpart_mode, 0); fill_value = gen_reg_rtx (word_mode); emit_insn (gen_slt (fill_value)); } else #endif { fill_value = expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom, size_int (GET_MODE_BITSIZE (lowpart_mode) - 1), NULL_RTX, 0); fill_value = convert_to_mode (word_mode, fill_value, 1); } } My questions center around the first aproach: 1) Shouldn't it check that the comparison is directly supported by the target rather than implemented by a library call? If not, how does it know that it sets the codition codes? Also, several targets don't emit a comparison instruction until they know how the result is used. Instead, they save away the comparison operands. That will fail if the comparison is made by a library call. 2) How does it handle failure of gen_slt? I've now hit a case (mulvsi3 on ia16) where it tries to sign extend from SImode to DImode. It's just that cmpsi2 is implemented as a library call and gen_slt() fails. Result: "Junk extended" arguments are passed to muldi3. -- Rask Ingemann Lambertsen