alpha.h (SECONDARY_INPUT_RELOAD_CLASS): Call secondary_reload_class.

* alpha.h (SECONDARY_INPUT_RELOAD_CLASS): Call secondary_reload_class.
        (SECONDARY_OUTPUT_RELOAD_CLASS): Likewise.
        (PREDICATE_CODES): Add addition_operation.
        * alpha-protos.h (addition_operation): Declare.
        (secondary_reload_class): Likewise.
        * alpha.c (addition_operation): New.
        (secondary_reload_class): New, from old SECONDARY_INPUT_RELOAD_CLASS.
        * alpha.md (adddi3): Turn into expander.
        (*lda, *adddi_2): New.
        (movsf, movdf patterns): Don't preference integer regs.
        (movsi, movdi patterns): Don't preference fp regs.

From-SVN: r30277
This commit is contained in:
Richard Henderson 1999-10-30 14:46:57 -07:00 committed by Richard Henderson
parent 1e19333726
commit 3611aef055
5 changed files with 146 additions and 85 deletions

View File

@ -1,3 +1,17 @@
Sat Oct 30 14:41:40 1999 Richard Henderson <rth@cygnus.com>
* alpha.h (SECONDARY_INPUT_RELOAD_CLASS): Call secondary_reload_class.
(SECONDARY_OUTPUT_RELOAD_CLASS): Likewise.
(PREDICATE_CODES): Add addition_operation.
* alpha-protos.h (addition_operation): Declare.
(secondary_reload_class): Likewise.
* alpha.c (addition_operation): New.
(secondary_reload_class): New, from old SECONDARY_INPUT_RELOAD_CLASS.
* alpha.md (adddi3): Turn into expander.
(*lda, *adddi_2): New.
(movsf, movdf patterns): Don't preference integer regs.
(movsi, movdi patterns): Don't preference fp regs.
Sat Oct 30 14:38:22 1999 Richard Henderson <rth@cygnus.com>
* genrecog.c (write_switch): Check for duplicate CODE cases.

View File

@ -66,10 +66,13 @@ extern int any_memory_operand PROTO ((rtx, enum machine_mode));
extern int reg_not_elim_operand PROTO ((rtx, enum machine_mode));
extern int normal_memory_operand PROTO ((rtx, enum machine_mode));
extern int reg_no_subreg_operand PROTO ((rtx, enum machine_mode));
extern int addition_operation PROTO ((rtx, enum machine_mode));
extern void get_aligned_mem PROTO ((rtx, rtx *, rtx *));
extern rtx get_unaligned_address PROTO ((rtx, int));
extern enum reg_class secondary_reload_class PROTO ((enum reg_class,
enum machine_mode,
rtx, int));
extern void alpha_set_memflags PROTO ((rtx, rtx));
extern rtx alpha_emit_set_const PROTO ((rtx, enum machine_mode,
HOST_WIDE_INT, int));

View File

@ -939,7 +939,26 @@ reg_no_subreg_operand (op, mode)
return 0;
return register_operand (op, mode);
}
/* Recognize a addition operation that includes a constant. Used to
convince reload to canonize (plus (plus reg c1) c2) during register
elimination. */
int
addition_operation (op, mode)
register rtx op;
enum machine_mode mode;
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
if (GET_CODE (op) == PLUS
&& register_operand (XEXP (op, 0), mode)
&& GET_CODE (XEXP (op, 1)) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
return 1;
return 0;
}
/* Return 1 if this function can directly return via $26. */
int
@ -950,7 +969,7 @@ direct_return ()
&& current_function_outgoing_args_size == 0
&& current_function_pretend_args_size == 0);
}
/* REF is an alignable memory location. Place an aligned SImode
reference into *PALIGNED_MEM and the number of bits to shift into
*PBITNUM. SCRATCH is a free register for use in reloading out
@ -1026,6 +1045,53 @@ get_unaligned_address (ref, extra_offset)
return plus_constant (base, offset + extra_offset);
}
/* Loading and storing HImode or QImode values to and from memory
usually requires a scratch register. The exceptions are loading
QImode and HImode from an aligned address to a general register
unless byte instructions are permitted.
We also cannot load an unaligned address or a paradoxical SUBREG
into an FP register.
We also cannot do integral arithmetic into FP regs, as might result
from register elimination into a DImode fp register. */
enum reg_class
secondary_reload_class (class, mode, x, in)
enum reg_class class;
enum machine_mode mode;
rtx x;
int in;
{
if ((GET_CODE (x) == MEM
|| (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
|| (GET_CODE (x) == SUBREG
&& (GET_CODE (SUBREG_REG (x)) == MEM
|| (GET_CODE (SUBREG_REG (x)) == REG
&& REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
&& ((class == FLOAT_REGS
&& (mode == SImode || mode == HImode || mode == QImode))
|| ((mode == QImode || mode == HImode)
&& ! TARGET_BWX && ! aligned_memory_operand (x, mode))))
return GENERAL_REGS;
if (class == FLOAT_REGS)
{
if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
return GENERAL_REGS;
if (GET_CODE (x) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (x))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
return GENERAL_REGS;
if (in && INTEGRAL_MODE_P (mode) && ! general_operand (x, mode))
return GENERAL_REGS;
}
return NO_REGS;
}
/* Subfunction of the following function. Update the flags of any MEM
found in part of X. */

View File

@ -815,42 +815,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
We also cannot load an unaligned address or a paradoxical SUBREG into an
FP register. */
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN) \
(((GET_CODE (IN) == MEM \
|| (GET_CODE (IN) == REG && REGNO (IN) >= FIRST_PSEUDO_REGISTER) \
|| (GET_CODE (IN) == SUBREG \
&& (GET_CODE (SUBREG_REG (IN)) == MEM \
|| (GET_CODE (SUBREG_REG (IN)) == REG \
&& REGNO (SUBREG_REG (IN)) >= FIRST_PSEUDO_REGISTER)))) \
&& (((CLASS) == FLOAT_REGS \
&& ((MODE) == SImode || (MODE) == HImode || (MODE) == QImode)) \
|| (((MODE) == QImode || (MODE) == HImode) \
&& ! TARGET_BWX && ! aligned_memory_operand (IN, MODE)))) \
? GENERAL_REGS \
: ((CLASS) == FLOAT_REGS && GET_CODE (IN) == MEM \
&& GET_CODE (XEXP (IN, 0)) == AND) ? GENERAL_REGS \
: ((CLASS) == FLOAT_REGS && GET_CODE (IN) == SUBREG \
&& (GET_MODE_SIZE (GET_MODE (IN)) \
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (IN))))) ? GENERAL_REGS \
: NO_REGS)
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN) \
secondary_reload_class((CLASS), (MODE), (IN), 1)
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,OUT) \
(((GET_CODE (OUT) == MEM \
|| (GET_CODE (OUT) == REG && REGNO (OUT) >= FIRST_PSEUDO_REGISTER) \
|| (GET_CODE (OUT) == SUBREG \
&& (GET_CODE (SUBREG_REG (OUT)) == MEM \
|| (GET_CODE (SUBREG_REG (OUT)) == REG \
&& REGNO (SUBREG_REG (OUT)) >= FIRST_PSEUDO_REGISTER)))) \
&& ((((MODE) == HImode || (MODE) == QImode) \
&& (! TARGET_BWX || (CLASS) == FLOAT_REGS)) \
|| ((MODE) == SImode && (CLASS) == FLOAT_REGS))) \
? GENERAL_REGS \
: ((CLASS) == FLOAT_REGS && GET_CODE (OUT) == MEM \
&& GET_CODE (XEXP (OUT, 0)) == AND) ? GENERAL_REGS \
: ((CLASS) == FLOAT_REGS && GET_CODE (OUT) == SUBREG \
&& (GET_MODE_SIZE (GET_MODE (OUT)) \
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (OUT))))) ? GENERAL_REGS \
: NO_REGS)
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,OUT) \
secondary_reload_class((CLASS), (MODE), (OUT), 0)
/* If we are copying between general and FP registers, we need a memory
location unless the FIX extension is available. */
@ -2340,7 +2309,8 @@ do { \
{"any_memory_operand", {MEM}}, \
{"hard_fp_register_operand", {SUBREG, REG}}, \
{"reg_not_elim_operand", {SUBREG, REG}}, \
{"reg_no_subreg_operand", {REG}},
{"reg_no_subreg_operand", {REG}}, \
{"addition_operation", {PLUS}},
/* Define the `__builtin_va_list' type for the ABI. */
#define BUILD_VA_LIST_TYPE(VALIST) \

View File

@ -542,39 +542,47 @@
operands[7] = gen_lowpart (SImode, operands[5]);
}")
(define_insn "adddi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
(match_operand:DI 2 "add_operand" "rI,O,K,L")))]
(define_expand "adddi3"
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "add_operand" "")))]
""
"*
{
static const char * const pattern[4] = {
\"addq %r1,%2,%0\",
\"subq %r1,%n2,%0\",
\"lda %0,%2(%r1)\",
\"ldah %0,%h2(%r1)\"
};
"")
/* The NT stack unwind code can't handle a subq to adjust the stack
(that's a bug, but not one we can do anything about). As of NT4.0 SP3,
the exception handling code will loop if a subq is used and an
exception occurs.
;; This pattern exists so that register elimination tries to canonize
;; (plus (plus reg c1) c2).
The 19980616 change to emit prologues as RTL also confused some
versions of GDB, which also interprets prologues. This has been
fixed as of GDB 4.18, but it does not harm to unconditionally
use lda here. */
(define_insn "*lda"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand:DI 1 "addition_operation" "p"))]
""
"lda %0,%a1")
int which = which_alternative;
;; We used to expend quite a lot of effort choosing addq/subq/lda.
;; With complications like
;;
;; The NT stack unwind code can't handle a subq to adjust the stack
;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
;; the exception handling code will loop if a subq is used and an
;; exception occurs.
;;
;; The 19980616 change to emit prologues as RTL also confused some
;; versions of GDB, which also interprets prologues. This has been
;; fixed as of GDB 4.18, but it does not harm to unconditionally
;; use lda here.
;;
;; and the fact that the three insns schedule exactly the same, it's
;; just not worth the effort.
if (operands[0] == stack_pointer_rtx
&& GET_CODE (operands[2]) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
which = 2;
return pattern[which];
}")
(define_insn "*adddi_2"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
(match_operand:DI 2 "add_operand" "r,K,L")))]
""
"@
addq %1,%2,%0
lda %0,%2(%1)
ldah %0,%h2(%1)")
;; ??? Allow large constants when basing off the frame pointer or some
;; virtual register that may eliminate to the frame pointer. This is
@ -4004,8 +4012,8 @@
;; they are simpler.
(define_insn ""
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
(match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r"))]
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
"! TARGET_FIX
&& (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))"
@ -4019,8 +4027,8 @@
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
(define_insn ""
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
(match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
"TARGET_FIX
&& (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))"
@ -4036,8 +4044,8 @@
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
(define_insn ""
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
(match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r"))]
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
"! TARGET_FIX
&& (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))"
@ -4051,8 +4059,8 @@
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
(define_insn ""
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
(match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
"TARGET_FIX
&& (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))"
@ -4090,8 +4098,8 @@
}")
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m")
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
"! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
@ -4107,8 +4115,8 @@
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m,r,*f")
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f,f,*r"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
"! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
@ -4126,8 +4134,8 @@
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,m")
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,m,f"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
"(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
@ -4235,8 +4243,8 @@
}")
(define_insn ""
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f"))]
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
"! TARGET_FIX
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
@ -4253,8 +4261,8 @@
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
(define_insn ""
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,Q,r,*f")
(match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f,f,*r"))]
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
(match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
"TARGET_FIX
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"