c4x.c (c4x_emit_move_sequence): Do not force large constants into memory.
Sat Sep 4 11:37:15 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz> * config/c4x/c4x.c (c4x_emit_move_sequence): Do not force large constants into memory. (c4x_shiftable_constant): New function. * config/c4x/c4x.c (LEGITIMATE_CONSTANT_P): Allow any CONST_INT. (c4x_shiftable_constant): Declare. * config/c4x/c4x.md (loadqi_big_constant, loadhi_big_constant, ashlqi3_noclobber): Add new patterns and associated splitters. From-SVN: r29092
This commit is contained in:
parent
3de900268e
commit
483dd5bec1
4 changed files with 167 additions and 20 deletions
|
@ -1,3 +1,13 @@
|
|||
Sat Sep 4 11:37:15 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
|
||||
* config/c4x/c4x.c (c4x_emit_move_sequence): Do not force large
|
||||
constants into memory.
|
||||
(c4x_shiftable_constant): New function.
|
||||
* config/c4x/c4x.c (LEGITIMATE_CONSTANT_P): Allow any CONST_INT.
|
||||
(c4x_shiftable_constant): Declare.
|
||||
* config/c4x/c4x.md (loadqi_big_constant, loadhi_big_constant,
|
||||
ashlqi3_noclobber): Add new patterns and associated splitters.
|
||||
|
||||
Fri Sep 3 16:22:17 1999 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* dbxout.c (dbxout_init): Use xcalloc instead of xmalloc+bzero.
|
||||
|
|
|
@ -1074,20 +1074,6 @@ c4x_emit_move_sequence (operands, mode)
|
|||
constants... */
|
||||
op1 = force_const_mem (mode, op1);
|
||||
}
|
||||
else if (mode == QImode && CONSTANT_P (op1) && ! LEGITIMATE_CONSTANT_P (op1))
|
||||
{
|
||||
/* We shouldn't need this test if only emit_move_insn was called.
|
||||
However, some routines call gen_move_insn which doesn't check that
|
||||
the constants are legitimate. */
|
||||
op1 = force_const_mem (mode, op1);
|
||||
}
|
||||
else if (mode == HImode && CONSTANT_P (op1) && ! LEGITIMATE_CONSTANT_P (op1))
|
||||
{
|
||||
/* We could load all sorts of constants in two goes by pulling all
|
||||
sorts of tricks... The tricky thing is that we cannot clobber CC
|
||||
so that stifles most of the obvious methods. */
|
||||
op1 = force_const_mem (mode, op1);
|
||||
}
|
||||
|
||||
/* Convert (MEM (SYMREF)) to a (MEM (LO_SUM (REG) (SYMREF)))
|
||||
and emit associated (HIGH (SYMREF)) if large memory model.
|
||||
|
@ -2258,6 +2244,27 @@ c4x_immed_float_constant (op)
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
c4x_shiftable_constant (op)
|
||||
rtx op;
|
||||
{
|
||||
int i;
|
||||
int mask;
|
||||
int val = INTVAL (op);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (val & (1 << i))
|
||||
break;
|
||||
}
|
||||
mask = ((0xffff >> i) << 16) | 0xffff;
|
||||
if (IS_INT16_CONST (val & 0x80000000 ? (val >> i) | ~mask
|
||||
: (val >> i) & mask))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
c4x_H_constant (op)
|
||||
rtx op;
|
||||
|
@ -2760,7 +2767,7 @@ reg_operand (op, mode)
|
|||
int
|
||||
mixed_subreg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
/* Allow (subreg:HF (reg:HI)) that be generated for a union of an
|
||||
int and a long double. */
|
||||
|
|
|
@ -1675,7 +1675,7 @@ extern struct rtx_def *c4x_legitimize_reload_address ();
|
|||
|
||||
#define LEGITIMATE_CONSTANT_P(X) \
|
||||
((GET_CODE (X) == CONST_DOUBLE && c4x_H_constant (X)) \
|
||||
|| (GET_CODE (X) == CONST_INT && c4x_I_constant (X)) \
|
||||
|| (GET_CODE (X) == CONST_INT) \
|
||||
|| (GET_CODE (X) == SYMBOL_REF) \
|
||||
|| (GET_CODE (X) == LABEL_REF) \
|
||||
|| (GET_CODE (X) == CONST) \
|
||||
|
@ -2750,6 +2750,8 @@ extern int not_rc_reg ();
|
|||
|
||||
extern int not_modify_reg ();
|
||||
|
||||
extern int c4x_shiftable_constant ();
|
||||
|
||||
extern int c4x_H_constant ();
|
||||
|
||||
extern int c4x_I_constant ();
|
||||
|
|
|
@ -1130,11 +1130,13 @@
|
|||
"")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:QI 0 "std_reg_operand" "")
|
||||
[(set (match_operand:QI 0 "reg_operand" "")
|
||||
(match_operand:QI 1 "const_int_operand" ""))]
|
||||
"! TARGET_C3X
|
||||
&& (INTVAL (operands[1]) & ~0xffff) != 0
|
||||
&& (INTVAL (operands[1]) & 0xffff) != 0"
|
||||
&& ! IS_INT16_CONST (INTVAL (operands[1]))
|
||||
&& ! IS_HIGH_CONST (INTVAL (operands[1]))
|
||||
&& reload_completed
|
||||
&& std_reg_operand (operands[0], QImode)"
|
||||
[(set (match_dup 0) (match_dup 2))
|
||||
(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
|
||||
"
|
||||
|
@ -1143,6 +1145,104 @@
|
|||
operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
|
||||
}")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:QI 0 "reg_operand" "")
|
||||
(match_operand:QI 1 "const_int_operand" ""))]
|
||||
"TARGET_C3X && ! TARGET_SMALL
|
||||
&& ! IS_INT16_CONST (INTVAL (operands[1]))
|
||||
&& reload_completed
|
||||
&& std_reg_operand (operands[0], QImode)
|
||||
&& c4x_shiftable_constant (operands[1]) < 0"
|
||||
[(set (match_dup 0) (match_dup 2))
|
||||
(set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 4)))
|
||||
(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 3)))]
|
||||
"
|
||||
{
|
||||
/* Generate two's complement value of 16 MSBs. */
|
||||
operands[2] = gen_rtx (CONST_INT, VOIDmode,
|
||||
(((INTVAL (operands[1]) >> 16) & 0xffff)
|
||||
- 0x8000) ^ ~0x7fff);
|
||||
operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff);
|
||||
operands[4] = gen_rtx (CONST_INT, VOIDmode, 16);
|
||||
}")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:QI 0 "reg_operand" "")
|
||||
(match_operand:QI 1 "const_int_operand" ""))]
|
||||
"TARGET_C3X
|
||||
&& ! IS_INT16_CONST (INTVAL (operands[1]))
|
||||
&& reload_completed
|
||||
&& std_reg_operand (operands[0], QImode)
|
||||
&& c4x_shiftable_constant (operands[1]) >= 0"
|
||||
[(set (match_dup 0) (match_dup 2))
|
||||
(set (match_dup 0) (ashift:QI (match_dup 0) (match_dup 3)))]
|
||||
"
|
||||
{
|
||||
/* Generate two's complement value of MSBs. */
|
||||
int shift = c4x_shiftable_constant (operands[1]);
|
||||
|
||||
operands[2] = gen_rtx (CONST_INT, VOIDmode,
|
||||
(((INTVAL (operands[1]) >> shift) & 0xffff)
|
||||
- 0x8000) ^ ~0x7fff);
|
||||
operands[3] = gen_rtx (CONST_INT, VOIDmode, shift);
|
||||
}")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:QI 0 "reg_operand" "")
|
||||
(match_operand:QI 1 "const_int_operand" ""))]
|
||||
"! TARGET_SMALL
|
||||
&& ! IS_INT16_CONST (INTVAL (operands[1]))
|
||||
&& ! IS_HIGH_CONST (INTVAL (operands[1]))
|
||||
&& reload_completed
|
||||
&& ! std_reg_operand (operands[0], QImode)"
|
||||
[(set (match_dup 2) (high:QI (match_dup 3)))
|
||||
(set (match_dup 0) (match_dup 4))
|
||||
(use (match_dup 1))]
|
||||
"
|
||||
{
|
||||
rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
|
||||
operands[2] = dp_reg;
|
||||
operands[3] = force_const_mem (Pmode, operands[1]);
|
||||
operands[4] = change_address (operands[3], QImode,
|
||||
gen_rtx_LO_SUM (Pmode, dp_reg,
|
||||
XEXP (operands[3], 0)));
|
||||
operands[3] = XEXP (operands[3], 0);
|
||||
}")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:QI 0 "reg_operand" "")
|
||||
(match_operand:QI 1 "const_int_operand" ""))]
|
||||
"TARGET_SMALL
|
||||
&& ! IS_INT16_CONST (INTVAL (operands[1]))
|
||||
&& ! IS_HIGH_CONST (INTVAL (operands[1]))
|
||||
&& reload_completed
|
||||
&& (TARGET_C3X && c4x_shiftable_constant (operands[1]) < 0
|
||||
|| ! std_reg_operand (operands[0], QImode))"
|
||||
[(set (match_dup 0) (match_dup 2))
|
||||
(use (match_dup 1))]
|
||||
"
|
||||
{
|
||||
rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
|
||||
operands[2] = force_const_mem (Pmode, operands[1]);
|
||||
operands[2] = change_address (operands[2], QImode,
|
||||
gen_rtx_LO_SUM (Pmode, dp_reg,
|
||||
XEXP (operands[2], 0)));
|
||||
}")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:HI 0 "reg_operand" "")
|
||||
(match_operand:HI 1 "const_int_operand" ""))]
|
||||
"reload_completed"
|
||||
[(set (match_dup 2) (match_dup 4))
|
||||
(set (match_dup 3) (match_dup 5))]
|
||||
"
|
||||
{
|
||||
operands[2] = c4x_operand_subword (operands[0], 0, 1, HImode);
|
||||
operands[3] = c4x_operand_subword (operands[0], 1, 1, HImode);
|
||||
operands[4] = c4x_operand_subword (operands[1], 0, 1, HImode);
|
||||
operands[5] = c4x_operand_subword (operands[1], 1, 1, HImode);
|
||||
}")
|
||||
|
||||
; CC has been selected to load a symbolic address. We force the address
|
||||
; into memory and then generate LDP and LDIU insns.
|
||||
; This is also required for the C30 if we pretend that we can
|
||||
|
@ -1189,7 +1289,14 @@
|
|||
(define_insn "load_immed_address"
|
||||
[(set (match_operand:QI 0 "reg_operand" "=a?x?c*r")
|
||||
(match_operand:QI 1 "symbolic_address_operand" ""))]
|
||||
"TARGET_LOAD_ADDRESS"
|
||||
"TARGET_LOAD_ADDRESS"
|
||||
"#"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "loadhi_big_constant"
|
||||
[(set (match_operand:HI 0 "reg_operand" "=c*d")
|
||||
(match_operand:HI 1 "const_int_operand" ""))]
|
||||
""
|
||||
"#"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
|
@ -1207,6 +1314,14 @@
|
|||
"stik\\t%1,%0"
|
||||
[(set_attr "type" "store")])
|
||||
|
||||
(define_insn "loadqi_big_constant"
|
||||
[(set (match_operand:QI 0 "reg_operand" "=c*d")
|
||||
(match_operand:QI 1 "const_int_operand" ""))]
|
||||
"! IS_INT16_CONST (INTVAL (operands[1]))
|
||||
&& ! IS_HIGH_CONST (INTVAL (operands[1]))"
|
||||
"#"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
; We must provide an alternative to store to memory in case we have to
|
||||
; spill a register.
|
||||
(define_insn "movqi_noclobber"
|
||||
|
@ -2516,6 +2631,19 @@
|
|||
[(set_attr "type" "binarycc,binarycc,binarycc")])
|
||||
; Default to int16 data attr.
|
||||
|
||||
(define_insn "ashlqi3_noclobber"
|
||||
[(set (match_operand:QI 0 "std_reg_operand" "=c,c,?c")
|
||||
(ashift:QI (match_operand:QI 1 "src_operand" "0,rR,rS<>")
|
||||
(match_operand:QI 2 "src_operand" "rIm,JR,rS<>")))]
|
||||
"valid_operands (ASHIFT, operands, QImode)"
|
||||
"@
|
||||
ash\\t%2,%0
|
||||
ash3\\t%2,%1,%0
|
||||
ash3\\t%2,%1,%0"
|
||||
[(set_attr "type" "binary,binary,binary")])
|
||||
; Default to int16 data attr.
|
||||
|
||||
|
||||
; This is only used by lshrhi3_reg where we need a LSH insn that will
|
||||
; shift both ways.
|
||||
(define_insn "*lshlqi3_clobber"
|
||||
|
|
Loading…
Add table
Reference in a new issue