+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
{
/* 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 ();
}
else
{
- emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high_bits)));
+ emit_insn (gen_safe_SET64 (temp, high_bits));
temp2 = temp;
}
}
else
{
- emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high_bits)));
+ emit_insn (gen_safe_SET64 (temp, high_bits));
sub_temp = temp;
}
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
{
&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;
}
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)
{
&& 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;
}
/* 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);
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,
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,
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. */
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))
{
/* 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
/* 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",
&& 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"
[(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" ""))]
[(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")])
[(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")
(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")])
(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")])
(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")])
(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")
(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")
(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\";
(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\";
(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)"
[(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")])
}")
(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")
"*
{
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\";