aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.c
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1995-01-07 00:59:42 -0700
committerJeff Law <law@gcc.gnu.org>1995-01-07 00:59:42 -0700
commitc47decad97eca23beacfc3a58006b86ef747fe66 (patch)
tree438449607691411bc40eb5b7c75d60a5a2ceab5e /gcc/config/pa/pa.c
parentc1fe41cbd37fca7d9079cc7fce669c68ac294c99 (diff)
downloadgcc-c47decad97eca23beacfc3a58006b86ef747fe66.zip
gcc-c47decad97eca23beacfc3a58006b86ef747fe66.tar.gz
gcc-c47decad97eca23beacfc3a58006b86ef747fe66.tar.bz2
pa.h (enum processor_type): New enumeration describing the processor to schedule for (700, 7100, 7100LC).
* pa.h (enum processor_type): New enumeration describing the processor to schedule for (700, 7100, 7100LC). (pa_cpu_attr, TARGET_OPTIONS, OVERRIDE_OPTIONS): Define. (pa_cpu_string, pa_cpu): Provide extern decls. * pa.c (pa_cpu, pa_cpu_string): Provide definitions. (override_options): New function. (pa_adjust_cost): Handle PROCESSOR_7100 and PROCESSOR_7100LC scheduling. Handle anti-dependendy cases involving fp division and sqrt. Handle output dependencies correctly. Break TYPE_FPMUL into TYPE_FPMULSGL and TYPE_FPMULDBL. * pa.md (cpu attribute): New attribute. Clean up comments for PROCESSOR_700 scheduling info. Slightly simplify. Make conditional on PROCESSOR_700. Add comments and scheduling information for PROCESSOR_7100 and PROCESSOR_7100LC. Set types for instructions which use the shifter to "shift". Explicitly set lengths and types for all instructions. Break type "fpmul" into "fmulsgl" and "fpmuldbl". From-SVN: r8723
Diffstat (limited to 'gcc/config/pa/pa.c')
-rw-r--r--gcc/config/pa/pa.c170
1 files changed, 161 insertions, 9 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 50e1a3e..2d2eb12 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -41,6 +41,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
rtx hppa_compare_op0, hppa_compare_op1;
enum cmp_type hppa_branch_type;
+/* Which cpu we are scheduling for. */
+enum processor_type pa_cpu;
+
+/* String to hold which cpu we are scheduling for. */
+char *pa_cpu_string;
+
rtx hppa_save_pic_table_rtx;
/* Set by the FUNCTION_PROFILER macro. */
@@ -57,6 +63,34 @@ static rtx find_addr_reg ();
unsigned int total_code_bytes;
+void
+override_options ()
+{
+ /* Default to 700 scheduling which is reasonable for older 800 processors
+ correct for the 700s, and not too bad for the 7100s and 7100LCs. */
+ if (pa_cpu_string == NULL
+ || ! strcmp (pa_cpu_string, "700"))
+ {
+ pa_cpu_string = "700";
+ pa_cpu = PROCESSOR_700;
+ }
+ else if (! strcmp (pa_cpu_string, "7100"))
+ {
+ pa_cpu_string = "7100";
+ pa_cpu = PROCESSOR_7100;
+ }
+ else if (! strncmp (pa_cpu_string, "7100LC"))
+ {
+ pa_cpu_string = "7100LC";
+ pa_cpu = PROCESSOR_7100LC;
+ }
+ else
+ {
+ warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC\n", pa_cpu_string);
+ }
+}
+
+
/* Return non-zero only if OP is a register of mode MODE,
or CONST0_RTX. */
int
@@ -2498,18 +2532,20 @@ pa_adjust_cost (insn, link, dep_insn, cost)
switch (get_attr_type (dep_insn))
{
case TYPE_FPLOAD:
- /* This cost 3 cycles, not 2 as the md says. */
- return cost + 1;
+ /* This cost 3 cycles, not 2 as the md says for the
+ 700 and 7100. Note scaling of cost for 7100. */
+ return cost + (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
case TYPE_FPALU:
- case TYPE_FPMUL:
+ case TYPE_FPMULSGL:
+ case TYPE_FPMULDBL:
case TYPE_FPDIVSGL:
case TYPE_FPDIVDBL:
case TYPE_FPSQRTSGL:
case TYPE_FPSQRTDBL:
/* In these important cases, we save one cycle compared to
when flop instruction feed each other. */
- return cost - 1;
+ return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
default:
return cost;
@@ -2547,16 +2583,52 @@ pa_adjust_cost (insn, link, dep_insn, cost)
switch (get_attr_type (dep_insn))
{
case TYPE_FPALU:
- case TYPE_FPMUL:
+ case TYPE_FPMULSGL:
+ case TYPE_FPMULDBL:
case TYPE_FPDIVSGL:
case TYPE_FPDIVDBL:
case TYPE_FPSQRTSGL:
case TYPE_FPSQRTDBL:
/* A fpload can't be issued until one cycle before a
- preceeding arithmetic operation has finished, if
+ preceeding arithmetic operation has finished if
the target of the fpload is any of the sources
(or destination) of the arithmetic operation. */
- return cost - 1;
+ return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
+
+ default:
+ return 0;
+ }
+ }
+ }
+ else if (get_attr_type (insn) == TYPE_FPALU)
+ {
+ rtx pat = PATTERN (insn);
+ rtx dep_pat = PATTERN (dep_insn);
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ /* This happens for the fldXs,mb patterns. */
+ pat = XVECEXP (pat, 0, 0);
+ }
+ if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+ /* If this happens, we have to extend this to schedule
+ optimally. Return 0 for now. */
+ return 0;
+
+ if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
+ {
+ if (! recog_memoized (dep_insn))
+ return 0;
+ switch (get_attr_type (dep_insn))
+ {
+ case TYPE_FPDIVSGL:
+ case TYPE_FPDIVDBL:
+ case TYPE_FPSQRTSGL:
+ case TYPE_FPSQRTDBL:
+ /* An ALU flop can't be issued until two cycles before a
+ preceeding divide or sqrt operation has finished if
+ the target of the ALU flop is any of the sources
+ (or destination) of the divide or sqrt operation. */
+ return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
default:
return 0;
@@ -2567,9 +2639,89 @@ pa_adjust_cost (insn, link, dep_insn, cost)
/* For other anti dependencies, the cost is 0. */
return 0;
}
+ else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
+ {
+ /* Output dependency; DEP_INSN writes a register that INSN writes some
+ cycles later. */
+ if (get_attr_type (insn) == TYPE_FPLOAD)
+ {
+ rtx pat = PATTERN (insn);
+ rtx dep_pat = PATTERN (dep_insn);
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ /* This happens for the fldXs,mb patterns. */
+ pat = XVECEXP (pat, 0, 0);
+ }
+ if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+ /* If this happens, we have to extend this to schedule
+ optimally. Return 0 for now. */
+ return 0;
+
+ if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
+ {
+ if (! recog_memoized (dep_insn))
+ return 0;
+ switch (get_attr_type (dep_insn))
+ {
+ case TYPE_FPALU:
+ case TYPE_FPMULSGL:
+ case TYPE_FPMULDBL:
+ case TYPE_FPDIVSGL:
+ case TYPE_FPDIVDBL:
+ case TYPE_FPSQRTSGL:
+ case TYPE_FPSQRTDBL:
+ /* A fpload can't be issued until one cycle before a
+ preceeding arithmetic operation has finished if
+ the target of the fpload is the destination of the
+ arithmetic operation. */
+ return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
- /* For output dependencies, the cost is often one too high. */
- return cost - 1;
+ default:
+ return 0;
+ }
+ }
+ }
+ else if (get_attr_type (insn) == TYPE_FPALU)
+ {
+ rtx pat = PATTERN (insn);
+ rtx dep_pat = PATTERN (dep_insn);
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ /* This happens for the fldXs,mb patterns. */
+ pat = XVECEXP (pat, 0, 0);
+ }
+ if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+ /* If this happens, we have to extend this to schedule
+ optimally. Return 0 for now. */
+ return 0;
+
+ if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
+ {
+ if (! recog_memoized (dep_insn))
+ return 0;
+ switch (get_attr_type (dep_insn))
+ {
+ case TYPE_FPDIVSGL:
+ case TYPE_FPDIVDBL:
+ case TYPE_FPSQRTSGL:
+ case TYPE_FPSQRTDBL:
+ /* An ALU flop can't be issued until two cycles before a
+ preceeding divide or sqrt operation has finished if
+ the target of the ALU flop is also the target of
+ of the divide or sqrt operation. */
+ return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
+
+ default:
+ return 0;
+ }
+ }
+ }
+
+ /* For other output dependencies, the cost is 0. */
+ return 0;
+ }
+ else
+ abort ();
}
/* Return any length adjustment needed by INSN which already has its length