From: David S. Miller Date: Fri, 14 Aug 1998 14:11:34 +0000 (+0000) Subject: sparc.c (sparc_emit_set_const64_quick2, [...]): Fix more bugs in 64-bit constant... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f710f868cbda44939f994e843d33e85c7ea1bdb5;p=gcc.git sparc.c (sparc_emit_set_const64_quick2, [...]): Fix more bugs in 64-bit constant formation. * config/sparc/sparc.c (sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, const64_is_2insns, create_simple_focus_bits, sparc_emit_set_const64): Fix more bugs in 64-bit constant formation. * config/sparc/sparc.md (snesi_zero_extend split): Generate rtl for addx not subx. (define_insn movdi_const64_special): Make available even when HOST_BITS_PER_WIDE_INT is not 64. (movdi_lo_sum_sp64_cint, movdi_high_sp64_cint): Remove. (losum_di_medlow, sethm, setlo): Make op2 symbolic_operand. (cmp_siqi_trunc_set, cmp_diqi_trunc_set): Encapsulate both instances of operand 1 inside a QI subreg. (xordi3_sp64_dbl): Remove '%' constraint for op1. (one_cmpldi2_sp64): Fix output string. (one_cmplsi2_not_liveg0): Rewrite to remove unneeded extra alternative case. (unnamed arch64 ashift DI): Truncate shift count if greater than 63, not 31. From-SVN: r21733 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 11d6b7cd1e9..dd51f8da19e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +Fri Aug 14 12:58:21 1998 David S. Miller + + * config/sparc/sparc.c (sparc_emit_set_const64_quick2, + sparc_emit_set_const64_longway, const64_is_2insns, + create_simple_focus_bits, sparc_emit_set_const64): Fix more bugs + in 64-bit constant formation. + * config/sparc/sparc.md (snesi_zero_extend split): Generate + rtl for addx not subx. + (define_insn movdi_const64_special): Make available even when + HOST_BITS_PER_WIDE_INT is not 64. + (movdi_lo_sum_sp64_cint, movdi_high_sp64_cint): Remove. + (losum_di_medlow, sethm, setlo): Make op2 symbolic_operand. + (cmp_siqi_trunc_set, cmp_diqi_trunc_set): Encapsulate both + instances of operand 1 inside a QI subreg. + (xordi3_sp64_dbl): Remove '%' constraint for op1. + (one_cmpldi2_sp64): Fix output string. + (one_cmplsi2_not_liveg0): Rewrite to remove unneeded extra + alternative case. + (unnamed arch64 ashift DI): Truncate shift count if greater than + 63, not 31. + Fri Aug 14 21:52:53 1998 J"orn Rennecke * expr.c (store_expr): Don't optimize away load-store pair diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index d6861b12f60..6651ee3a75e 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1229,7 +1229,7 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1) { /* Getting this right wrt. reloading is really tricky. We _MUST_ have a seperate temporary at this point, - if we don't barf immediately instead of generating + so we barf immediately instead of generating incorrect code. */ if (temp1 == op0) abort (); @@ -1369,7 +1369,7 @@ sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count) } else { - emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high_bits))); + emit_insn (gen_safe_SET64 (temp, high_bits)); temp2 = temp; } @@ -1416,7 +1416,7 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits) } else { - emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high_bits))); + emit_insn (gen_safe_SET64 (temp, high_bits)); sub_temp = temp; } @@ -1432,10 +1432,17 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits) sparc_emit_set_safe_HIGH64 (temp2, low_bits); if ((low_bits & ~0xfffffc00) != 0) - emit_insn (gen_rtx_SET (VOIDmode, temp3, - gen_safe_OR64 (temp2, (low_bits & 0x3ff)))); - emit_insn (gen_rtx_SET (VOIDmode, op0, - gen_rtx_PLUS (DImode, temp4, temp3))); + { + emit_insn (gen_rtx_SET (VOIDmode, temp3, + gen_safe_OR64 (temp2, (low_bits & 0x3ff)))); + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_PLUS (DImode, temp4, temp3))); + } + else + { + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_PLUS (DImode, temp4, temp2))); + } } else { @@ -1572,17 +1579,14 @@ const64_is_2insns (high_bits, low_bits) &highest_bit_set, &lowest_bit_set, &all_bits_between_are_set); - if (highest_bit_set == 63 + if ((highest_bit_set == 63 + || lowest_bit_set == 0) && all_bits_between_are_set != 0) return 1; if ((highest_bit_set - lowest_bit_set) < 21) return 1; - if (high_bits == 0 - || high_bits == 0xffffffff) - return 1; - return 0; } @@ -1595,7 +1599,7 @@ create_simple_focus_bits (high_bits, low_bits, highest_bit_set, lowest_bit_set, unsigned HOST_WIDE_INT high_bits, low_bits; int highest_bit_set, lowest_bit_set, shift; { - int hi, lo; + HOST_WIDE_INT hi, lo; if (lowest_bit_set < 32) { @@ -1634,13 +1638,14 @@ sparc_emit_set_const64 (op0, op1) && REGNO (op0) <= SPARC_LAST_V9_FP_REG)) abort (); + if (reload_in_progress || reload_completed) + temp = op0; + else + temp = gen_reg_rtx (DImode); + if (GET_CODE (op1) != CONST_DOUBLE && GET_CODE (op1) != CONST_INT) { - if (reload_in_progress || reload_completed) - temp = op0; - else - temp = gen_reg_rtx (DImode); sparc_emit_set_symbolic_const64 (op0, op1, temp); return; } @@ -1671,11 +1676,6 @@ sparc_emit_set_const64 (op0, op1) /* low_bits bits 0 --> 31 high_bits bits 32 --> 63 */ - if (reload_in_progress || reload_completed) - temp = op0; - else - temp = gen_reg_rtx (DImode); - analyze_64bit_constant (high_bits, low_bits, &highest_bit_set, &lowest_bit_set, &all_bits_between_are_set); @@ -1699,15 +1699,9 @@ sparc_emit_set_const64 (op0, op1) HOST_WIDE_INT the_const = -1; int shift = lowest_bit_set; - if (highest_bit_set == lowest_bit_set) - { - /* There is no way to get here like this, because this case - can be done in one instruction. */ - if (lowest_bit_set < 32) - abort (); - the_const = 1; - } - else if (all_bits_between_are_set == 0) + if ((highest_bit_set != 63 + && lowest_bit_set != 0) + || all_bits_between_are_set == 0) { the_const = create_simple_focus_bits (high_bits, low_bits, @@ -1717,6 +1711,9 @@ sparc_emit_set_const64 (op0, op1) else if (lowest_bit_set == 0) shift = -(63 - highest_bit_set); + if (! SPARC_SIMM13_P (the_const)) + abort (); + emit_insn (gen_safe_SET64 (temp, the_const)); if (shift > 0) emit_insn (gen_rtx_SET (VOIDmode, @@ -1746,6 +1743,10 @@ sparc_emit_set_const64 (op0, op1) unsigned HOST_WIDE_INT focus_bits = create_simple_focus_bits (high_bits, low_bits, highest_bit_set, lowest_bit_set, 10); + + if (! SPARC_SETHI_P (focus_bits)) + abort (); + sparc_emit_set_safe_HIGH64 (temp, focus_bits); /* If lowest_bit_set == 10 then a sethi alone could have done it. */ @@ -1777,20 +1778,20 @@ sparc_emit_set_const64 (op0, op1) return; } + /* Now, try 3-insn sequences. */ + /* 1) sethi %hi(high_bits), %reg * or %reg, %lo(high_bits), %reg * sllx %reg, 32, %reg */ - if (low_bits == 0 - || (SPARC_SIMM13_P(low_bits) - && ((HOST_WIDE_INT)low_bits > 0))) + if (low_bits == 0) { - sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32); + sparc_emit_set_const64_quick2 (op0, temp, high_bits, 0, 32); return; } - /* Now, try 3-insn sequences. But first we may be able to do something - quick when the constant is negated, so try that. */ + /* We may be able to do something quick + when the constant is negated, so try that. */ if (const64_is_2insns ((~high_bits) & 0xffffffff, (~low_bits) & 0xfffffc00)) { @@ -1832,10 +1833,15 @@ sparc_emit_set_const64 (op0, op1) /* 1) sethi %hi(xxx), %reg * or %reg, %lo(xxx), %reg * sllx %reg, yyy, %reg + * + * ??? This is just a generalized version of the low_bits==0 + * thing above, FIXME... */ if ((highest_bit_set - lowest_bit_set) < 32) { - unsigned HOST_WIDE_INT hi, lo, focus_bits; + unsigned HOST_WIDE_INT focus_bits = + create_simple_focus_bits (high_bits, low_bits, + highest_bit_set, lowest_bit_set, 0); /* We can't get here in this state. */ if (highest_bit_set < 32 @@ -1844,17 +1850,24 @@ sparc_emit_set_const64 (op0, op1) /* So what we know is that the set bits straddle the middle of the 64-bit word. */ - hi = (low_bits >> lowest_bit_set); - lo = (high_bits << (32 - lowest_bit_set)); - if (hi & lo) - abort (); - focus_bits = (hi | lo); sparc_emit_set_const64_quick2 (op0, temp, focus_bits, 0, lowest_bit_set); return; } + /* 1) sethi %hi(high_bits), %reg + * or %reg, %lo(high_bits), %reg + * sllx %reg, 32, %reg + * or %reg, low_bits, %reg + */ + if (SPARC_SIMM13_P(low_bits) + && ((int)low_bits > 0)) + { + sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32); + return; + } + /* The easiest way when all else fails, is full decomposition. */ #if 0 printf ("sparc_emit_set_const64: Hard constant [%08lx%08lx] neg[%08lx%08lx]\n", diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 47b10ac9ee9..72795121ec0 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1097,10 +1097,10 @@ && reload_completed" [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1)) (const_int 0))) - (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0) - (const_int 0)) - (ltu:SI (reg:CC_NOOV 100) - (const_int 0)))))] + (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0) + (const_int 0)) + (ltu:SI (reg:CC_NOOV 100) + (const_int 0)))))] "") (define_insn "*snedi_zero" @@ -2332,6 +2332,7 @@ [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*") (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")]) +;; The following are generated by sparc_emit_set_const64 (define_insn "*movdi_sp64_dbl" [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "const64_operand" ""))] @@ -2341,11 +2342,12 @@ [(set_attr "type" "move") (set_attr "length" "1")]) +;; This is needed to show CSE exactly which bits are set +;; in a 64-bit register by sethi instructions. (define_insn "*movdi_const64_special" [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "const64_high_operand" ""))] - "(TARGET_ARCH64 - && HOST_BITS_PER_WIDE_INT != 64)" + "TARGET_ARCH64" "sethi\\t%%hi(%a1), %0" [(set_attr "type" "move") (set_attr "length" "1")]) @@ -2368,24 +2370,6 @@ [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore") (set_attr "length" "1")]) -;; The following are generated by sparc_emit_set_const64 -(define_insn "*movdi_lo_sum_sp64_cint" - [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "in")))] - "TARGET_ARCH64" - "or\\t%1, %%lo(%a2), %0" - [(set_attr "type" "ialu") - (set_attr "length" "1")]) - -(define_insn "*movdi_high_sp64_cint" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand:DI 1 "const_int_operand" "in")))] - "TARGET_ARCH64" - "sethi\\t%%hi(%a1), %0" - [(set_attr "type" "move") - (set_attr "length" "1")]) - ;; ??? revisit this... (define_insn "move_label_di" [(set (match_operand:DI 0 "register_operand" "=r") @@ -2439,7 +2423,7 @@ (define_insn "*losum_di_medlow" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "" "")))] + (match_operand:DI 2 "symbolic_operand" "")))] "TARGET_CM_MEDLOW" "or\\t%1, %%lo(%a2), %0" [(set_attr "length" "1")]) @@ -2488,7 +2472,7 @@ (define_insn "sethm" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (unspec:DI [(match_operand:DI 2 "" "")] 18)))] + (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))] "TARGET_CM_MEDANY" "or\\t%1, %%hm(%a2), %0" [(set_attr "length" "1")]) @@ -2496,7 +2480,7 @@ (define_insn "setlo" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "" "")))] + (match_operand:DI 2 "symbolic_operand" "")))] "TARGET_CM_MEDANY" "or\\t%1, %%lo(%a2), %0" [(set_attr "length" "1")]) @@ -3915,7 +3899,7 @@ (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0) (const_int 0))) (set (match_operand:QI 0 "register_operand" "=r") - (match_dup 1))] + (subreg:QI (match_dup 1) 0))] "" "andcc\\t%1, 0xff, %0" [(set_attr "type" "compare") @@ -3935,7 +3919,7 @@ (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0) (const_int 0))) (set (match_operand:QI 0 "register_operand" "=r") - (match_dup 1))] + (subreg:QI (match_dup 1) 0))] "TARGET_ARCH64" "andcc\\t%1, 0xff, %0" [(set_attr "type" "compare") @@ -4149,7 +4133,7 @@ (GET_CODE (operands[2]) == CONST_INT ? INTVAL (operands[2]) : CONST_DOUBLE_LOW (operands[2])) - len; - unsigned mask = ((1 << len) - 1) << pos; + HOST_WIDE_INT mask = ((1 << len) - 1) << pos; operands[1] = GEN_INT (mask); return \"andcc\\t%0, %1, %%g0\"; @@ -4178,7 +4162,7 @@ (GET_CODE (operands[2]) == CONST_INT ? INTVAL (operands[2]) : CONST_DOUBLE_LOW (operands[2])) - len; - unsigned HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; + HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; operands[1] = GEN_INT (mask); return \"andcc\\t%0, %1, %%g0\"; @@ -5644,7 +5628,7 @@ (define_insn "*xordi3_sp64_dbl" [(set (match_operand:DI 0 "register_operand" "=r") - (xor:DI (match_operand:DI 1 "register_operand" "%r") + (xor:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "const64_operand" "")))] "(TARGET_ARCH64 && HOST_BITS_PER_WIDE_INT != 64)" @@ -6058,7 +6042,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "xnor\\t%1, 0, %0" + "xnor\\t%%g0, %1, %0" [(set_attr "type" "unary") (set_attr "length" "1")]) @@ -6085,15 +6069,14 @@ }") (define_insn "*one_cmplsi2_not_liveg0" - [(set (match_operand:SI 0 "register_operand" "=r,r,d") - (not:SI (match_operand:SI 1 "arith_operand" "r,I,d")))] + [(set (match_operand:SI 0 "register_operand" "=r,d") + (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))] "! TARGET_LIVE_G0" "@ - xnor\\t%1, 0, %0 xnor\\t%%g0, %1, %0 fnot1s\\t%1, %0" - [(set_attr "type" "unary,unary,fp") - (set_attr "length" "1,1,1")]) + [(set_attr "type" "unary,fp") + (set_attr "length" "1,1")]) (define_insn "*one_cmplsi2_liveg0" [(set (match_operand:SI 0 "register_operand" "=r,d") @@ -6434,7 +6417,7 @@ "* { if (GET_CODE (operands[2]) == CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31) + && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63) operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); return \"sllx\\t%1, %2, %0\";