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
This commit is contained in:
David S. Miller 1998-08-14 14:11:34 +00:00 committed by David S. Miller
parent 6036acbbf2
commit f710f868cb
3 changed files with 99 additions and 82 deletions

View File

@ -1,3 +1,24 @@
Fri Aug 14 12:58:21 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
* 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 <amylaar@cygnus.co.uk>
* expr.c (store_expr): Don't optimize away load-store pair

View File

@ -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",

View File

@ -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\";