diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/optabs.c | 9 |
2 files changed, 15 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f6b8fe5..b36bdcf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2008-01-26 Richard Sandiford <rsandifo@nildram.co.uk> + PR rtl-optimization/34959 + * optabs.c (expand_unop): In libcall notes, give ffs, clz, ctz, + popcount and parity rtxes the same mode as their operand. + Truncate or extend the result to the return value's mode + if necessary. + +2008-01-26 Richard Sandiford <rsandifo@nildram.co.uk> + PR target/34981 * config/mips/mips-protos.h (mips_expand_call): Return an rtx. * config/mips/mips.h (FIRST_PSEUDO_REGISTER): Rename FAKE_CALL_REGNO diff --git a/gcc/optabs.c b/gcc/optabs.c index 089fccc..448b799 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3273,6 +3273,7 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, { rtx insns; rtx value; + rtx eq_value; enum machine_mode outmode = mode; /* All of these functions return small values. Thus we choose to @@ -3292,8 +3293,12 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, end_sequence (); target = gen_reg_rtx (outmode); - emit_libcall_block (insns, target, value, - gen_rtx_fmt_e (unoptab->code, outmode, op0)); + eq_value = gen_rtx_fmt_e (unoptab->code, mode, op0); + if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode)) + eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode); + else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode)) + eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode); + emit_libcall_block (insns, target, value, eq_value); return target; } |