mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 17:11:01 +08:00
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:
parent
1e19333726
commit
3611aef055
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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. */
|
||||
|
@ -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) \
|
||||
|
@ -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))"
|
||||
|
Loading…
x
Reference in New Issue
Block a user