pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a constant can be loaded in a single...

* pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a
	constant can be loaded in a single instruction to a register.  When
	loading immediate constants, use PLUS instead of HIGH/LO_SUM.  Use
	depdi for insertion of most significant 32-bits on 64-bit hosts.
	* pa.h (LEGITIMATE_CONSTANT_P): Accept constants that can be built
	with ldil/ldo/depdi instruction sequence on 64-bit hosts.
	* pa.md: New addmove pattern for adding constant_int to HImode
	register and moving result to HImode register.  Remove HImode HIGH
	and LO_SUM patterns.

From-SVN: r46908
This commit is contained in:
John David Anglin 2001-11-10 00:22:52 +00:00 committed by Jeff Law
parent 5d69f816bc
commit b8e42321fb
4 changed files with 65 additions and 31 deletions

View File

@ -1,3 +1,15 @@
2001-11-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
* pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a
constant can be loaded in a single instruction to a register. When
loading immediate constants, use PLUS instead of HIGH/LO_SUM. Use
depdi for insertion of most significant 32-bits on 64-bit hosts.
* pa.h (LEGITIMATE_CONSTANT_P): Accept constants that can be built
with ldil/ldo/depdi instruction sequence on 64-bit hosts.
* pa.md: New addmove pattern for adding constant_int to HImode
register and moving result to HImode register. Remove HImode HIGH
and LO_SUM patterns.
2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
* Makefile.in: Update.

View File

@ -1394,7 +1394,8 @@ emit_move_sequence (operands, mode, scratch_reg)
else if (register_operand (operand0, mode))
{
if (register_operand (operand1, mode)
|| (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
|| (GET_CODE (operand1) == CONST_INT
&& cint_ok_for_move (INTVAL (operand1)))
|| (operand1 == CONST0_RTX (mode))
|| (GET_CODE (operand1) == HIGH
&& !symbolic_operand (XEXP (operand1, 0), VOIDmode))
@ -1596,8 +1597,8 @@ emit_move_sequence (operands, mode, scratch_reg)
else if (GET_CODE (operand1) != CONST_INT
|| ! cint_ok_for_move (INTVAL (operand1)))
{
rtx extend = NULL_RTX;
rtx temp;
int need_zero_extend = 0;
if (TARGET_64BIT && GET_CODE (operand1) == CONST_INT
&& HOST_BITS_PER_WIDE_INT > 32
@ -1606,15 +1607,18 @@ emit_move_sequence (operands, mode, scratch_reg)
HOST_WIDE_INT val = INTVAL (operand1);
HOST_WIDE_INT nval;
/* If the value is the same after a 32->64bit sign
extension, then we can use it as-is. Else we will
need to sign extend the constant from 32->64bits
then zero extend the result from 32->64bits. */
/* Extract the low order 32 bits of the value and sign extend.
If the new value is the same as the original value, we can
can use the original value as-is. If the new value is
different, we use it and insert the most-significant 32-bits
of the original value into the final result. */
nval = ((val & (((HOST_WIDE_INT) 2 << 31) - 1))
^ ((HOST_WIDE_INT) 1 << 31)) - ((HOST_WIDE_INT) 1 << 31);
if (val != nval)
{
need_zero_extend = 1;
#if HOST_BITS_PER_WIDE_INT > 32
extend = GEN_INT (val >> 32);
#endif
operand1 = GEN_INT (nval);
}
}
@ -1624,18 +1628,43 @@ emit_move_sequence (operands, mode, scratch_reg)
else
temp = gen_reg_rtx (mode);
emit_insn (gen_rtx_SET (VOIDmode, temp,
gen_rtx_HIGH (mode, operand1)));
operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
if (GET_CODE (operand1) == CONST_INT)
{
/* Directly break constant into low and high parts. This
provides better optimization opportunities because various
passes recognize constants split with PLUS but not LO_SUM.
We use a 14-bit signed low part except when the addition
of 0x4000 to the high part might change the sign of the
high part. */
HOST_WIDE_INT value = INTVAL (operand1);
HOST_WIDE_INT low = value & 0x3fff;
HOST_WIDE_INT high = value & ~ 0x3fff;
if (low >= 0x2000)
{
if (high == 0x7fffc000 || (mode == HImode && high == 0x4000))
high += 0x2000;
else
high += 0x4000;
}
low = value - high;
emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high)));
operands[1] = gen_rtx_PLUS (mode, temp, GEN_INT (low));
}
else
{
emit_insn (gen_rtx_SET (VOIDmode, temp,
gen_rtx_HIGH (mode, operand1)));
operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
}
emit_move_insn (operands[0], operands[1]);
if (need_zero_extend)
{
emit_insn (gen_zero_extendsidi2 (operands[0],
gen_rtx_SUBREG (SImode,
operands[0],
4)));
}
if (extend != NULL_RTX)
emit_insn (gen_insv (operands[0], GEN_INT (32), const0_rtx,
extend));
return 1;
}

View File

@ -1106,8 +1106,8 @@ extern int may_call_alloca;
&& !(TARGET_64BIT && GET_CODE (X) == CONST_DOUBLE) \
&& !(TARGET_64BIT && GET_CODE (X) == CONST_INT \
&& !(HOST_BITS_PER_WIDE_INT <= 32 \
|| (INTVAL (X) >= (HOST_WIDE_INT) -1 << 31 \
&& INTVAL (X) < (HOST_WIDE_INT) 1 << 32) \
|| (INTVAL (X) >= (HOST_WIDE_INT) -32 << 31 \
&& INTVAL (X) < (HOST_WIDE_INT) 32 << 31) \
|| cint_ok_for_move (INTVAL (X)))) \
&& !function_label_operand (X, VOIDmode))

View File

@ -2604,19 +2604,12 @@
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(high:HI (match_operand 1 "const_int_operand" "")))]
(plus:HI (match_operand:HI 1 "register_operand" "r")
(match_operand 2 "const_int_operand" "J")))]
""
"ldil L'%G1,%0"
[(set_attr "type" "move")
(set_attr "length" "4")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(lo_sum:HI (match_operand:HI 1 "register_operand" "r")
(match_operand 2 "const_int_operand" "")))]
""
"ldo R'%G2(%1),%0"
[(set_attr "type" "move")
"ldo %2(%1),%0"
[(set_attr "type" "binary")
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4")])
(define_expand "movqi"