Commit 3611aef0 by Richard Henderson Committed by Richard Henderson

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
parent 1e193337
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> Sat Oct 30 14:38:22 1999 Richard Henderson <rth@cygnus.com>
* genrecog.c (write_switch): Check for duplicate CODE cases. * genrecog.c (write_switch): Check for duplicate CODE cases.
......
...@@ -66,10 +66,13 @@ extern int any_memory_operand PROTO ((rtx, enum machine_mode)); ...@@ -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 reg_not_elim_operand PROTO ((rtx, enum machine_mode));
extern int normal_memory_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 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 void get_aligned_mem PROTO ((rtx, rtx *, rtx *));
extern rtx get_unaligned_address PROTO ((rtx, int)); 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 void alpha_set_memflags PROTO ((rtx, rtx));
extern rtx alpha_emit_set_const PROTO ((rtx, enum machine_mode, extern rtx alpha_emit_set_const PROTO ((rtx, enum machine_mode,
HOST_WIDE_INT, int)); HOST_WIDE_INT, int));
......
...@@ -939,7 +939,26 @@ reg_no_subreg_operand (op, mode) ...@@ -939,7 +939,26 @@ reg_no_subreg_operand (op, mode)
return 0; return 0;
return register_operand (op, mode); 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. */ /* Return 1 if this function can directly return via $26. */
int int
...@@ -950,7 +969,7 @@ direct_return () ...@@ -950,7 +969,7 @@ direct_return ()
&& current_function_outgoing_args_size == 0 && current_function_outgoing_args_size == 0
&& current_function_pretend_args_size == 0); && current_function_pretend_args_size == 0);
} }
/* REF is an alignable memory location. Place an aligned SImode /* REF is an alignable memory location. Place an aligned SImode
reference into *PALIGNED_MEM and the number of bits to shift into reference into *PALIGNED_MEM and the number of bits to shift into
*PBITNUM. SCRATCH is a free register for use in reloading out *PBITNUM. SCRATCH is a free register for use in reloading out
...@@ -1026,6 +1045,53 @@ get_unaligned_address (ref, extra_offset) ...@@ -1026,6 +1045,53 @@ get_unaligned_address (ref, extra_offset)
return plus_constant (base, offset + 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 /* Subfunction of the following function. Update the flags of any MEM
found in part of X. */ found in part of X. */
......
...@@ -815,42 +815,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, ...@@ -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 We also cannot load an unaligned address or a paradoxical SUBREG into an
FP register. */ FP register. */
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN) \ #define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN) \
(((GET_CODE (IN) == MEM \ secondary_reload_class((CLASS), (MODE), (IN), 1)
|| (GET_CODE (IN) == REG && REGNO (IN) >= FIRST_PSEUDO_REGISTER) \
|| (GET_CODE (IN) == SUBREG \ #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,OUT) \
&& (GET_CODE (SUBREG_REG (IN)) == MEM \ secondary_reload_class((CLASS), (MODE), (OUT), 0)
|| (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_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)
/* If we are copying between general and FP registers, we need a memory /* If we are copying between general and FP registers, we need a memory
location unless the FIX extension is available. */ location unless the FIX extension is available. */
...@@ -2340,7 +2309,8 @@ do { \ ...@@ -2340,7 +2309,8 @@ do { \
{"any_memory_operand", {MEM}}, \ {"any_memory_operand", {MEM}}, \
{"hard_fp_register_operand", {SUBREG, REG}}, \ {"hard_fp_register_operand", {SUBREG, REG}}, \
{"reg_not_elim_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 the `__builtin_va_list' type for the ABI. */
#define BUILD_VA_LIST_TYPE(VALIST) \ #define BUILD_VA_LIST_TYPE(VALIST) \
......
...@@ -542,39 +542,47 @@ ...@@ -542,39 +542,47 @@
operands[7] = gen_lowpart (SImode, operands[5]); operands[7] = gen_lowpart (SImode, operands[5]);
}") }")
(define_insn "adddi3" (define_expand "adddi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r") [(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") (plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "add_operand" "rI,O,K,L")))] (match_operand:DI 2 "add_operand" "")))]
"" ""
"* "")
{
static const char * const pattern[4] = { ;; This pattern exists so that register elimination tries to canonize
\"addq %r1,%2,%0\", ;; (plus (plus reg c1) c2).
\"subq %r1,%n2,%0\",
\"lda %0,%2(%r1)\", (define_insn "*lda"
\"ldah %0,%h2(%r1)\" [(set (match_operand:DI 0 "register_operand" "=r")
}; (match_operand:DI 1 "addition_operation" "p"))]
""
/* The NT stack unwind code can't handle a subq to adjust the stack "lda %0,%a1")
(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 ;; We used to expend quite a lot of effort choosing addq/subq/lda.
exception occurs. ;; With complications like
;;
The 19980616 change to emit prologues as RTL also confused some ;; The NT stack unwind code can't handle a subq to adjust the stack
versions of GDB, which also interprets prologues. This has been ;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
fixed as of GDB 4.18, but it does not harm to unconditionally ;; the exception handling code will loop if a subq is used and an
use lda here. */ ;; exception occurs.
;;
int which = which_alternative; ;; The 19980616 change to emit prologues as RTL also confused some
;; versions of GDB, which also interprets prologues. This has been
if (operands[0] == stack_pointer_rtx ;; fixed as of GDB 4.18, but it does not harm to unconditionally
&& GET_CODE (operands[2]) == CONST_INT ;; use lda here.
&& CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')) ;;
which = 2; ;; and the fact that the three insns schedule exactly the same, it's
;; just not worth the effort.
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 ;; ??? Allow large constants when basing off the frame pointer or some
;; virtual register that may eliminate to the frame pointer. This is ;; virtual register that may eliminate to the frame pointer. This is
...@@ -4004,8 +4012,8 @@ ...@@ -4004,8 +4012,8 @@
;; they are simpler. ;; they are simpler.
(define_insn "" (define_insn ""
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m") [(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"))] (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
"! TARGET_FIX "! TARGET_FIX
&& (register_operand (operands[0], SFmode) && (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))" || reg_or_fp0_operand (operands[1], SFmode))"
...@@ -4019,8 +4027,8 @@ ...@@ -4019,8 +4027,8 @@
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")]) [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
(define_insn "" (define_insn ""
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r") [(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"))] (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
"TARGET_FIX "TARGET_FIX
&& (register_operand (operands[0], SFmode) && (register_operand (operands[0], SFmode)
|| reg_or_fp0_operand (operands[1], SFmode))" || reg_or_fp0_operand (operands[1], SFmode))"
...@@ -4036,8 +4044,8 @@ ...@@ -4036,8 +4044,8 @@
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")]) [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
(define_insn "" (define_insn ""
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m") [(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"))] (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
"! TARGET_FIX "! TARGET_FIX
&& (register_operand (operands[0], DFmode) && (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))" || reg_or_fp0_operand (operands[1], DFmode))"
...@@ -4051,8 +4059,8 @@ ...@@ -4051,8 +4059,8 @@
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")]) [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
(define_insn "" (define_insn ""
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r") [(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"))] (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
"TARGET_FIX "TARGET_FIX
&& (register_operand (operands[0], DFmode) && (register_operand (operands[0], DFmode)
|| reg_or_fp0_operand (operands[1], DFmode))" || reg_or_fp0_operand (operands[1], DFmode))"
...@@ -4090,8 +4098,8 @@ ...@@ -4090,8 +4098,8 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m") [(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"))] (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
"! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
&& (register_operand (operands[0], SImode) && (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))" || reg_or_0_operand (operands[1], SImode))"
...@@ -4107,8 +4115,8 @@ ...@@ -4107,8 +4115,8 @@
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")]) [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m,r,*f") [(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"))] (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
"! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
&& (register_operand (operands[0], SImode) && (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))" || reg_or_0_operand (operands[1], SImode))"
...@@ -4126,8 +4134,8 @@ ...@@ -4126,8 +4134,8 @@
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")]) [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,m") [(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"))] (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
"(TARGET_WINDOWS_NT || TARGET_OPEN_VMS) "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
&& (register_operand (operands[0], SImode) && (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))" || reg_or_0_operand (operands[1], SImode))"
...@@ -4235,8 +4243,8 @@ ...@@ -4235,8 +4243,8 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,Q") [(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"))] (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
"! TARGET_FIX "! TARGET_FIX
&& (register_operand (operands[0], DImode) && (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))" || reg_or_0_operand (operands[1], DImode))"
...@@ -4253,8 +4261,8 @@ ...@@ -4253,8 +4261,8 @@
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")]) [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
(define_insn "" (define_insn ""
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,Q,r,*f") [(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"))] (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
"TARGET_FIX "TARGET_FIX
&& (register_operand (operands[0], DImode) && (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))" || reg_or_0_operand (operands[1], DImode))"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment