diff options
author | Jeff Law <law@gcc.gnu.org> | 1995-01-07 00:59:42 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1995-01-07 00:59:42 -0700 |
commit | c47decad97eca23beacfc3a58006b86ef747fe66 (patch) | |
tree | 438449607691411bc40eb5b7c75d60a5a2ceab5e /gcc/config/pa/pa.c | |
parent | c1fe41cbd37fca7d9079cc7fce669c68ac294c99 (diff) | |
download | gcc-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.c | 170 |
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 |