From fd94addf1d4edec67c2540454237f7ffd534933a Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Fri, 28 Apr 1995 10:37:27 -0400 Subject: [PATCH] (alpha_emit_set_const): Now returns rtx and take MODE arg. Rework to use a new pseudo for intermediate values if high opt level. Also use expand_{bin,un}op. From-SVN: r9531 --- gcc/config/alpha/alpha.c | 106 ++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 727e0a9df864..ee2a004cc5c9 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -58,6 +58,7 @@ static int inside_function = FALSE; int alpha_function_needs_gp; extern char *version_string; +extern int rtx_equal_function_value_matters; /* Declarations of static functions. */ static void alpha_set_memflags_1 PROTO((rtx, int, int, int)); @@ -657,25 +658,32 @@ alpha_set_memflags (insn, ref) } /* Try to output insns to set TARGET equal to the constant C if it can be - done in less than N insns. Returns 1 if it can be done and the - insns have been emitted. If it would take more than N insns, zero is - returned and no insns and emitted. */ + done in less than N insns. Do all computations in MODE. Returns the place + where the output has been placed if it can be done and the insns have been + emitted. If it would take more than N insns, zero is returned and no + insns and emitted. */ -int -alpha_emit_set_const (target, c, n) +rtx +alpha_emit_set_const (target, mode, c, n) rtx target; + enum machine_mode mode; HOST_WIDE_INT c; int n; { HOST_WIDE_INT new = c; int i, bits; + /* Use a pseudo if highly optimizing and still generating RTL. */ + rtx subtarget + = (flag_expensive_optimizations && rtx_equal_function_value_matters + ? 0 : target); + rtx temp; #if HOST_BITS_PER_WIDE_INT == 64 /* We are only called for SImode and DImode. If this is SImode, ensure that we are sign extended to a full word. This does not make any sense when cross-compiling on a narrow machine. */ - if (GET_MODE (target) == SImode) + if (mode == SImode) c = (c & 0xffffffff) - 2 * (c & 0x80000000); #endif @@ -703,18 +711,17 @@ alpha_emit_set_const (target, c, n) } if (c == low || (low == 0 && extra == 0)) - { - emit_move_insn (target, GEN_INT (c)); - return 1; - } + return copy_to_suggested_reg (GEN_INT (c), target, mode); else if (n >= 2 + (extra != 0)) { - emit_move_insn (target, GEN_INT (low)); + temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode); + if (extra != 0) - emit_insn (gen_add2_insn (target, GEN_INT (extra << 16))); + temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16), + subtarget, 0, OPTAB_WIDEN); - emit_insn (gen_add2_insn (target, GEN_INT (high << 16))); - return 1; + return expand_binop (mode, add_optab, temp, GEN_INT (high << 16), + target, 0, OPTAB_WIDEN); } } @@ -724,7 +731,7 @@ alpha_emit_set_const (target, c, n) SImode (in which case we should have already done something, but do a sanity check here). */ - if (n == 1 || HOST_BITS_PER_WIDE_INT < 64 || GET_MODE (target) != DImode) + if (n == 1 || HOST_BITS_PER_WIDE_INT < 64 || mode != DImode) return 0; /* First, see if can load a value into the target that is the same as the @@ -735,11 +742,9 @@ alpha_emit_set_const (target, c, n) if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0) new |= (HOST_WIDE_INT) 0xff << i; - if (alpha_emit_set_const (target, new, n - 1)) - { - emit_insn (gen_anddi3 (target, target, GEN_INT (c | ~ new))); - return 1; - } + if ((temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0) + return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new), + target, 0, OPTAB_WIDEN); /* Find, see if we can load a related constant and then shift and possibly negate it to get the constant we want. Try this once each increasing @@ -748,13 +753,10 @@ alpha_emit_set_const (target, c, n) for (i = 1; i < n; i++) { /* First try complementing. */ - if (alpha_emit_set_const (target, ~ c, i)) - { - emit_insn (gen_one_cmpldi2 (target, target)); - return 1; - } + if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0) + return expand_unop (mode, one_cmpl_optab, temp, target, 0); - /* First try to form a constant and do a left shift. We can do this + /* Next try to form a constant and do a left shift. We can do this if some low-order bits are zero; the exact_log2 call below tells us that information. The bits we are shifting out could be any value, but here we'll just try the 0- and sign-extended forms of @@ -765,44 +767,44 @@ alpha_emit_set_const (target, c, n) if ((bits = exact_log2 (c & - c)) > 0) for (; bits > 0; bits--) - if (alpha_emit_set_const (target, c >> bits, i) - || alpha_emit_set_const (target, - ((unsigned HOST_WIDE_INT) c) >> bits, - i)) - { - emit_insn (gen_ashldi3 (target, target, GEN_INT (bits))); - return 1; - } + if ((temp = alpha_emit_set_const (subtarget, mode, + c >> bits, i)) != 0 + || ((temp = (alpha_emit_set_const + (subtarget, mode, + ((unsigned HOST_WIDE_INT) c) >> bits, i))) + != 0)) + return expand_binop (mode, ashl_optab, temp, GEN_INT (bits), + target, 0, OPTAB_WIDEN); /* Now try high-order zero bits. Here we try the shifted-in bits as all zero and all ones. */ if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (c) - 1) > 0) for (; bits > 0; bits--) - if (alpha_emit_set_const (target, c << bits, i) - || alpha_emit_set_const (target, - ((c << bits) - | (((HOST_WIDE_INT) 1 << bits) - 1)), - i)) - { - emit_insn (gen_lshrdi3 (target, target, GEN_INT (bits))); - return 1; - } + if ((temp = alpha_emit_set_const (subtarget, mode, + c << bits, i)) != 0 + || ((temp = (alpha_emit_set_const + (subtarget, mode, + ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)), + i))) + != 0)) + return expand_binop (mode, lshr_optab, temp, GEN_INT (bits), + target, 0, OPTAB_WIDEN); /* Now try high-order 1 bits. We get that with a sign-extension. But one bit isn't enough here. */ if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (~ c) - 2) > 0) for (; bits > 0; bits--) - if (alpha_emit_set_const (target, c << bits, i) - || alpha_emit_set_const (target, - ((c << bits) - | (((HOST_WIDE_INT) 1 << bits) - 1)), - i)) - { - emit_insn (gen_ashrdi3 (target, target, GEN_INT (bits))); - return 1; - } + if ((temp = alpha_emit_set_const (subtarget, mode, + c << bits, i)) != 0 + || ((temp = (alpha_emit_set_const + (subtarget, mode, + ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)), + i))) + != 0)) + return expand_binop (mode, ashr_optab, temp, GEN_INT (bits), + target, 0, OPTAB_WIDEN); } return 0; -- 2.47.2