From 2eddfed1f242d4c8ab33faec15e52eef1cbff6f4 Mon Sep 17 00:00:00 2001 From: Jeffrey A Law Date: Tue, 2 Sep 1997 05:33:19 +0000 Subject: [PATCH] pa.c (restore_unscaled_index_insn_codes): New function. * pa.c (restore_unscaled_index_insn_codes): New function. (record_unscaled_index_insn_codes): Likewise. (output_function_prologue): Call restore_unscaled_index_insn_codes. (output_function_epilogue): Free memory for unscaled_index_insn_codes. (pa_reorg): Call record_unscaled_index_insn_codes. From-SVN: r15028 --- gcc/ChangeLog | 6 +++ gcc/config/pa/pa.c | 113 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c6479d1fa2..d28a963dfa2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,12 @@ Mon Sep 1 22:13:18 1997 Jeffrey A Law (law@cygnus.com) * version.c: Bump for snapshot. + * pa.c (restore_unscaled_index_insn_codes): New function. + (record_unscaled_index_insn_codes): Likewise. + (output_function_prologue): Call restore_unscaled_index_insn_codes. + (output_function_epilogue): Free memory for unscaled_index_insn_codes. + (pa_reorg): Call record_unscaled_index_insn_codes. + * haifa-sched.c (move_insn): Handle notes correctly for insns with SCHED_GROUP_P set. diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index b809f4c8dbf..37a7d494e5d 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -37,6 +37,9 @@ Boston, MA 02111-1307, USA. */ #include "expr.h" #include "obstack.h" +static void restore_unscaled_index_insn_codes PROTO((rtx)); +static void record_unscaled_index_insn_codes PROTO((rtx)); + /* Save the operands last given to a compare for use when we generate a scc or bcc insn. */ @@ -77,6 +80,13 @@ struct deferred_plabel } *deferred_plabels = 0; int n_deferred_plabels = 0; +/* Array indexed by INSN_UIDs holding the INSN_CODE of an insn which + uses an unscaled indexed address before delay slot scheduling. */ +static int *unscaled_index_insn_codes; + +/* Upper bound for the array. */ +static int max_unscaled_index_insn_codes_uid; + void override_options () { @@ -2567,6 +2577,9 @@ output_function_prologue (file, size) total_code_bytes = -1; remove_useless_addtr_insns (get_insns (), 0); + + /* Restore INSN_CODEs for insn which use unscaled indexed addresses. */ + restore_unscaled_index_insn_codes (get_insns ()); } void @@ -2916,6 +2929,11 @@ output_function_epilogue (file, size) fputs ("\tnop\n", file); fputs ("\t.EXIT\n\t.PROCEND\n", file); + + /* Free up stuff we don't need anymore. */ + if (unscaled_index_insn_codes) + free (unscaled_index_insn_codes); + max_unscaled_index_insn_codes_uid = 0; } void @@ -5802,6 +5820,97 @@ following_call (insn) return 0; } +/* Restore any INSN_CODEs for insns with unscaled indexed addresses since + the INSN_CODE might be clobberd by rerecognition triggered by reorg. */ + +static void +restore_unscaled_index_insn_codes (insns) + rtx insns; +{ + rtx insn; + + for (insn = insns; insn; insn = NEXT_INSN (insn)) + { + if (INSN_UID (insn) < max_unscaled_index_insn_codes_uid + && unscaled_index_insn_codes[INSN_UID (insn)] != -1) + INSN_CODE (insn) = unscaled_index_insn_codes[INSN_UID (insn)]; + } +} + +/* Severe braindamage: + + On the PA, address computations within MEM expressions are not + commutative because of the implicit space register selection + from the base register (instead of the entire effective address). + + Because of this mis-feature we have to know which register in a reg+reg + address is the base and which is the index. + + Before reload, the base can be identified by REGNO_POINTER_FLAG. We use + this to force base + index addresses to match a different insn than + index + base addresses. + + We assume that no pass during or after reload creates new unscaled indexed + addresses, so any unscaled indexed address we find after reload must have + at one time been recognized a base + index or index + base and we accept + any register as a base register. + + This scheme assumes that no pass during/after reload will rerecognize an + insn with an unscaled indexed address. This failed due to a reorg call + to rerecognize certain insns. + + So, we record if an insn uses an unscaled indexed address and which + register is the base (via recording of the INSN_CODE for such insns). + + Just before we output code for the function, we make sure all the insns + using unscaled indexed addresses have the same INSN_CODE as they did + immediately before delay slot scheduling. + + This is extremely gross. Long term, I'd like to be able to look at + REG_POINTER_FLAG to handle these kinds of problems. */ + +static void +record_unscaled_index_insn_codes (insns) + rtx insns; +{ + rtx insn; + + max_unscaled_index_insn_codes_uid = get_max_uid (); + unscaled_index_insn_codes + = (int *)xmalloc (max_unscaled_index_insn_codes_uid * sizeof (int)); + memset (unscaled_index_insn_codes, -1, + max_unscaled_index_insn_codes_uid * sizeof (int)); + + for (insn = insns; insn; insn = NEXT_INSN (insn)) + { + rtx set = single_set (insn); + rtx mem = NULL_RTX; + + /* Ignore anything that isn't a normal SET. */ + if (set == NULL_RTX) + continue; + + /* No insns can have more than one MEM. */ + if (GET_CODE (SET_SRC (set)) == MEM) + mem = SET_SRC (set); + + if (GET_CODE (SET_DEST (set)) == MEM) + mem = SET_DEST (set); + + /* If neither operand is a mem, then there's nothing to do. */ + if (mem == NULL_RTX) + continue; + + if (GET_CODE (XEXP (mem, 0)) != PLUS) + continue; + + /* If both are REGs (or SUBREGs), then record the insn code for + this insn. */ + if (REG_P (XEXP (XEXP (mem, 0), 0)) && REG_P (XEXP (XEXP (mem, 0), 1))) + unscaled_index_insn_codes[INSN_UID (insn)] = INSN_CODE (insn); + } +} + /* We use this hook to perform a PA specific optimization which is difficult to do in earlier passes. @@ -5840,6 +5949,10 @@ pa_reorg (insns) { rtx insn; + /* Keep track of which insns have unscaled indexed addresses, and which + register is the base address in such insns. */ + record_unscaled_index_insn_codes (insns); + remove_useless_addtr_insns (insns, 1); pa_combine_instructions (get_insns ()); -- 2.30.2