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

Reply via email to