#else
#define NUM_ARGS current_function_args_info
#endif
+
+#if OPEN_VMS
+#define REG_PV 27
+#define REG_RA 26
+#else
+#define REG_RA 26
+#endif
\f
/* Parse target option strings. */
void
override_options ()
{
+ /* 971208 -- EV6 scheduling parameters are still secret, so don't even
+ pretend and just schedule for an EV5 for now. -- r~ */
alpha_cpu
- = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
+ = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV5
: (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
if (alpha_cpu_string)
target_flags &= ~ (MASK_CIX | MASK_MAX);
}
else if (! strcmp (alpha_cpu_string, "pca56")
- || ! strcmp (alpha_cpu_string, "21164PC"))
+ || ! strcmp (alpha_cpu_string, "21164PC")
+ || ! strcmp (alpha_cpu_string, "21164pc"))
{
alpha_cpu = PROCESSOR_EV5;
target_flags |= MASK_BWX | MASK_MAX;
else if (! strcmp (alpha_cpu_string, "ev6")
|| ! strcmp (alpha_cpu_string, "21264"))
{
- alpha_cpu = PROCESSOR_EV6;
+ alpha_cpu = PROCESSOR_EV5;
target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
}
else
int cost;
{
rtx set, set_src;
+ enum attr_type insn_type, dep_insn_type;
/* If the dependence is an anti-dependence, there is no cost. For an
output dependence, there is sometimes a cost, but it doesn't seem
if (REG_NOTE_KIND (link) != 0)
return 0;
+ /* If we can't recognize the insns, we can't really do anything. */
+ if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
+ return cost;
+
+ insn_type = get_attr_type (insn);
+ dep_insn_type = get_attr_type (dep_insn);
+
if (alpha_cpu == PROCESSOR_EV5)
{
/* And the lord DEC saith: "A special bypass provides an effective
latency of 0 cycles for an ICMP or ILOG insn producing the test
operand of an IBR or CMOV insn." */
- if (recog_memoized (dep_insn) >= 0
- && (get_attr_type (dep_insn) == TYPE_ICMP
- || get_attr_type (dep_insn) == TYPE_ILOG)
- && recog_memoized (insn) >= 0
- && (get_attr_type (insn) == TYPE_IBR
- || (get_attr_type (insn) == TYPE_CMOV
+ if ((dep_insn_type == TYPE_ICMP
+ || dep_insn_type == TYPE_ILOG)
+ && (insn_type == TYPE_IBR
+ || (insn_type == TYPE_CMOV
&& !((set = single_set (dep_insn)) != 0
&& GET_CODE (PATTERN (insn)) == SET
&& (set_src = SET_SRC (PATTERN (insn)),
|| rtx_equal_p (set, XEXP (set_src, 2)))))))
return 0;
- /* On EV5 it takes longer to get data to the multiplier than to
- anywhere else, so increase costs. */
+ /* "The multiplier is unable to receive data from IEU bypass paths.
+ The instruction issues at the expected time, but its latency is
+ increased by the time it takes for the input data to become
+ available to the multiplier" -- which happens in pipeline stage
+ six, when results are comitted to the register file. */
- if (recog_memoized (insn) >= 0
- && recog_memoized (dep_insn) >= 0
- && (get_attr_type (insn) == TYPE_IMULL
- || get_attr_type (insn) == TYPE_IMULQ
- || get_attr_type (insn) == TYPE_IMULH)
+ if ((insn_type == TYPE_IMULL
+ || insn_type == TYPE_IMULQ
+ || insn_type == TYPE_IMULH)
&& (set = single_set (dep_insn)) != 0
&& GET_CODE (PATTERN (insn)) == SET
&& (set_src = SET_SRC (PATTERN (insn)),
rtx_equal_p (set, XEXP (set_src, 0))
|| rtx_equal_p (set, XEXP (set_src, 1))))
{
- switch (get_attr_type (insn))
+ switch (dep_insn_type)
{
+ /* These insns produce their results in pipeline stage five. */
case TYPE_LD:
case TYPE_CMOV:
case TYPE_IMULL:
case TYPE_IMULQ:
case TYPE_IMULH:
+ case TYPE_MVI:
return cost + 1;
- case TYPE_JSR:
- case TYPE_IADD:
- case TYPE_ILOG:
- case TYPE_SHIFT:
- case TYPE_ICMP:
+
+ /* Other integer insns produce results in pipeline stage four. */
+ default:
return cost + 2;
}
}
/* On EV4, if INSN is a store insn and DEP_INSN is setting the data
being stored, we can sometimes lower the cost. */
- if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
+ if (insn_type == TYPE_ST
&& (set = single_set (dep_insn)) != 0
&& GET_CODE (PATTERN (insn)) == SET
&& rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
{
- switch (get_attr_type (dep_insn))
+ switch (dep_insn_type)
{
case TYPE_LD:
/* No savings here. */
two in the MD file. The only case that it is actually two is
for the address in loads and stores. */
- if (recog_memoized (dep_insn) >= 0
- && (get_attr_type (dep_insn) == TYPE_IADD
- || get_attr_type (dep_insn) == TYPE_ILOG))
+ if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
{
- switch (get_attr_type (insn))
+ switch (insn_type)
{
case TYPE_LD:
case TYPE_ST:
/* The final case is when a compare feeds into an integer branch;
the cost is only one cycle in that case. */
- if (recog_memoized (dep_insn) >= 0
- && get_attr_type (dep_insn) == TYPE_ICMP
- && recog_memoized (insn) >= 0
- && get_attr_type (insn) == TYPE_IBR)
+ if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
return 1;
}
}
}
\f
-#if OPEN_VMS
-#define REG_PV 27
-#define REG_RA 26
-#else
-#define REG_RA 26
-#endif
-
-/* Find the current function's return address.
-
- ??? It would be better to arrange things such that if we would ordinarily
- have been a leaf function and we didn't spill the hard reg that we
- wouldn't have to save the register in the prolog. But it's not clear
- how to get the right information at the right time. */
-
-static rtx alpha_return_addr_rtx;
-
-rtx
-alpha_return_addr ()
-{
- rtx ret;
-
- if ((ret = alpha_return_addr_rtx) == NULL)
- {
- alpha_return_addr_rtx = ret = gen_reg_rtx (Pmode);
-
- emit_insn_after (gen_rtx (SET, VOIDmode, ret,
- gen_rtx (REG, Pmode, REG_RA)),
- get_insns ());
- }
-
- return ret;
-}
-
/* This page contains routines that are used to determine what the function
prologue and epilogue code will do and write them out. */
/* Show that we know this function if it is called again. */
SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
-
- alpha_return_addr_rtx = 0;
}
#endif /* !OPEN_VMS */
\f
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in alpha.h.
-(define_attr "cpu" "ev4,ev5,ev6"
+(define_attr "cpu" "ev4,ev5"
(const (symbol_ref "alpha_cpu")))
;; Define an insn type attribute. This is used in function unit delay
;; separately.
(define_attr "type"
- "ld,st,ibr,fbr,jsr,iadd,ilog,shift,cmov,icmp,imull,imulq,imulh,fadd,fmul,fcpys,fdivs,fdivt,ldsym,misc"
+ "ld,st,ibr,fbr,jsr,iadd,ilog,shift,cmov,icmp,imull,imulq,imulh,fadd,fmul,fcpys,fdivs,fdivt,ldsym,misc,mvi"
(const_string "iadd"))
;; The TRAP_TYPE attribute marks instructions that may generate traps
;; those as well.
(define_function_unit "ev5_ebox" 2 0
- (and (eq_attr "cpu" "ev5,ev6")
- (eq_attr "type" "iadd,ilog,icmp,st,shift,imull,imulq,imulh"))
+ (and (eq_attr "cpu" "ev5")
+ (eq_attr "type" "iadd,ilog,icmp,st,shift,imull,imulq,imulh,mvi"))
1 1)
;; Memory takes at least 2 clocks, and load cannot dual issue with stores.
(define_function_unit "ev5_ebox" 2 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "ld,ldsym"))
2 1)
(define_function_unit "ev5_e0" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "ld,ldsym"))
0 1
[(eq_attr "type" "st")])
;; Conditional moves always take 2 ticks.
(define_function_unit "ev5_ebox" 2 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "cmov"))
2 1)
-;; Stores, shifts, and multiplies can only issue to E0
+;; Stores, shifts, multiplies can only issue to E0
(define_function_unit "ev5_e0" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "st"))
1 1)
+;; Motion video insns also issue only to E0, and take two ticks.
+(define_function_unit "ev5_e0" 1 0
+ (and (eq_attr "cpu" "ev5")
+ (eq_attr "type" "mvi"))
+ 2 1)
+
;; But shifts and multiplies don't conflict with loads.
(define_function_unit "ev5_e0" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
- (eq_attr "type" "shift,imull,imulq,imulh"))
+ (and (eq_attr "cpu" "ev5")
+ (eq_attr "type" "shift,imull,imulq,imulh,mvi"))
1 1
- [(eq_attr "type" "st,shift,imull,imulq,imulh")])
+ [(eq_attr "type" "st,shift,imull,imulq,imulh,mvi")])
;; Branches can only issue to E1
(define_function_unit "ev5_e1" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "ibr,jsr"))
1 1)
;; Multiplies also use the integer multiplier.
(define_function_unit "ev5_imult" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "imull"))
8 4)
(define_function_unit "ev5_imult" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "imulq"))
12 8)
(define_function_unit "ev5_imult" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "imulh"))
14 8)
;; on either so we have to play the game again.
(define_function_unit "ev5_fpu" 2 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "fadd,fmul,fcpys,fbr,fdivs,fdivt"))
4 1)
;; Multiplies (resp. adds) also use the fmul (resp. fadd) units.
(define_function_unit "ev5_fm" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "fmul"))
4 1)
(define_function_unit "ev5_fa" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "fadd"))
4 1)
(define_function_unit "ev5_fa" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "fbr"))
1 1)
(define_function_unit "ev5_fa" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "fdivs"))
15 1)
(define_function_unit "ev5_fa" 1 0
- (and (eq_attr "cpu" "ev5,ev6")
+ (and (eq_attr "cpu" "ev5")
(eq_attr "type" "fdivt"))
22 1)
\f
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
"minsb8 %r1,%2,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "mvi")])
(define_insn "uminqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
"minub8 %r1,%2,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "mvi")])
(define_insn "smaxqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
"maxsb8 %r1,%2,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "mvi")])
(define_insn "umaxqi3"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
"maxub8 %r1,%2,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "mvi")])
(define_insn "sminhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
"minsw4 %r1,%2,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "mvi")])
(define_insn "uminhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
"minuw4 %r1,%2,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "mvi")])
(define_insn "smaxhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
"maxsw4 %r1,%2,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "mvi")])
(define_insn "umaxhi3"
[(set (match_operand:HI 0 "register_operand" "=r")