diff options
author | Joern Rennecke <amylaar@gcc.gnu.org> | 1996-10-29 01:08:53 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 1996-10-29 01:08:53 +0000 |
commit | ae9d19c0e16f6ee8381a170b3478d25b3a8d7229 (patch) | |
tree | 777d75f6715445d7065937174fdc77744381644b /gcc | |
parent | 0f13a422020fd379d217a7ef913b3bb1002730f3 (diff) | |
download | gcc-ae9d19c0e16f6ee8381a170b3478d25b3a8d7229.zip gcc-ae9d19c0e16f6ee8381a170b3478d25b3a8d7229.tar.gz gcc-ae9d19c0e16f6ee8381a170b3478d25b3a8d7229.tar.bz2 |
(EXT_SHIFT_SIGNED): New macro.
(shl_sext_kind, gen_shl_sext): try left shift - sign extend -
left shift - arithmetic right shift in case 2.
From-SVN: r13059
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/sh/sh.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 81cbdd7..cafbc51 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -701,6 +701,11 @@ static short ext_shift_amounts[32][4] = { {16, 8}, {16, 1, 8}, {16, 8, 2}, {16, 8, 1, 2}, {16, 8, 2, 2}, {16, -1, -2, 16}, {16, -2, 16}, {16, -1, 16}}; +/* Assuming we have a value that has been sign-extended by at least one bit, + can we use the ext_shift_amounts with the last shift turned to an arithmetic shift + to shift it by N without data loss, and quicker than by other means? */ +#define EXT_SHIFT_SIGNED(n) (((n) | 8) == 15) + /* This is used in length attributes in sh.md to help compute the length of arbitrary constant shift instructions. */ @@ -1372,17 +1377,21 @@ shl_sext_kind (left_rtx, size_rtx, costp) best_cost = cost; } } - if (size <= 16) + /* Check if we can do a sloppy shift with a final signed shift + restoring the sign. */ + if (EXT_SHIFT_SIGNED (size - ext)) + cost = ext_shift_insns[ext - insize] + ext_shift_insns[size - ext] + 1; + /* If not, maybe it's still cheaper to do the second shift sloppy, + and do a final sign extend? */ + else if (size <= 16) + cost = ext_shift_insns[ext - insize] + 1 + + ext_shift_insns[size > ext ? size - ext : ext - size] + 1; + else + continue; + if (cost < best_cost) { - /* Maybe it's cheaper to do the second shift sloppy, and do a - final sign extend? */ - cost = ext_shift_insns[ext - insize] + 1 - + ext_shift_insns[size > ext ? size - ext : ext - size] + 1; - if (cost < best_cost) - { - kind = ext / 8U + 2; - best_cost = cost; - } + kind = ext / 8U + 2; + best_cost = cost; } } /* Check if we can sign extend in r0 */ @@ -1493,6 +1502,14 @@ gen_shl_sext (dest, left_rtx, size_rtx, source) { if (shift2 > 0) { + if (EXT_SHIFT_SIGNED (shift2)) + { + operands[2] = GEN_INT (shift2 + 1); + gen_shifty_op (ASHIFT, operands); + operands[2] = GEN_INT (1); + gen_shifty_op (ASHIFTRT, operands); + break; + } operands[2] = GEN_INT (shift2); gen_shifty_hi_op (ASHIFT, operands); } |