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:
parent
6036acbbf2
commit
f710f868cb
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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\";
|
||||
|
Loading…
Reference in New Issue
Block a user