diff options
author | Stuart Longland <redhatter@gentoo.org> | 2005-09-16 13:01:45 +0000 |
---|---|---|
committer | Stuart Longland <redhatter@gentoo.org> | 2005-09-16 13:01:45 +0000 |
commit | a55ec54daedd633e53589925192c5b05bc9c6d25 (patch) | |
tree | e8aa27098ed8d97820f12ba94d6ae32827e81e04 /sys-devel/gcc/files | |
parent | added timeout option, bug 100980 (diff) | |
download | gentoo-2-a55ec54daedd633e53589925192c5b05bc9c6d25.tar.gz gentoo-2-a55ec54daedd633e53589925192c5b05bc9c6d25.tar.bz2 gentoo-2-a55ec54daedd633e53589925192c5b05bc9c6d25.zip |
Fixed line endings in gcc-3.4.2-mips-ip28_cache_barriers-v2.patch
(Portage version: 2.0.51.19)
Diffstat (limited to 'sys-devel/gcc/files')
-rw-r--r-- | sys-devel/gcc/files/3.4.2/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch | 916 |
1 files changed, 458 insertions, 458 deletions
diff --git a/sys-devel/gcc/files/3.4.2/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch b/sys-devel/gcc/files/3.4.2/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch index 1c85e05ff389..d91c9f2738d5 100644 --- a/sys-devel/gcc/files/3.4.2/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch +++ b/sys-devel/gcc/files/3.4.2/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch @@ -1,458 +1,458 @@ ---- gcc-3.4.2/gcc/config/mips/mips.h Thu Jul 15 02:42:47 2004
-+++ gcc-3.4.2/gcc/config/mips/mips.h Sat Sep 18 00:41:48 2004
-@@ -122,6 +122,7 @@
- extern const char *mips_isa_string; /* for -mips{1,2,3,4} */
- extern const char *mips_abi_string; /* for -mabi={32,n32,64} */
- extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
-+extern const char *mips_ip28_cache_barrier;/* for -mip28-cache-barrier */
- extern int mips_string_length; /* length of strings for mips16 */
- extern const struct mips_cpu_info mips_cpu_info_table[];
- extern const struct mips_cpu_info *mips_arch_info;
-@@ -333,6 +334,7 @@
- #define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000)
- #define TARGET_SB1 (mips_arch == PROCESSOR_SB1)
- #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000)
-+#define TARGET_IP28 (mips_ip28_cache_barrier != 0)
-
- /* Scheduling target defines. */
- #define TUNE_MIPS3000 (mips_tune == PROCESSOR_R3000)
-@@ -752,6 +754,8 @@
- N_("Don't call any cache flush functions"), 0}, \
- { "flush-func=", &mips_cache_flush_func, \
- N_("Specify cache flush function"), 0}, \
-+ { "ip28-cache-barrier", &mips_ip28_cache_barrier, \
-+ N_("Generate special cache barriers for SGI Indigo2 R10k"), 0}, \
- }
-
- /* This is meant to be redefined in the host dependent files. */
-@@ -3448,3 +3452,11 @@
- " TEXT_SECTION_ASM_OP);
- #endif
- #endif
-+
-+#define ASM_OUTPUT_R10K_CACHE_BARRIER(STREAM) \
-+ fprintf (STREAM, "\tcache 0x14,0($sp)\t%s Cache Barrier\n", ASM_COMMENT_START)
-+
-+/*
-+ * mips.h Thu Jul 15 02:42:47 2004
-+ * mips.h Fri Sep 17 23:18:19 2004 ip28
-+ */
---- gcc-3.4.2/gcc/config/mips/mips.c Wed Jul 7 21:21:10 2004
-+++ gcc-3.4.2/gcc/config/mips/mips.c Fri Sep 17 23:33:44 2004
-@@ -502,6 +502,11 @@
-
- const char *mips_cache_flush_func = CACHE_FLUSH_FUNC;
-
-+/* Nonzero means generate special cache barriers to inhibit speculative
-+ stores which might endanger cache coherency or reference invalid
-+ addresses (especially on SGI's Indigo2 R10k (IP28)). */
-+const char *mips_ip28_cache_barrier;
-+
- /* If TRUE, we split addresses into their high and low parts in the RTL. */
- int mips_split_addresses;
-
-@@ -9676,3 +9681,7 @@
- #endif /* TARGET_IRIX */
-
- #include "gt-mips.h"
-+/*
-+ * mips.c Wed Jul 7 21:21:10 2004
-+ * mips.c Fri Sep 17 23:25:53 2004 ip28
-+ */
---- gcc-3.4.2/gcc/final.c Sun Jan 18 23:39:57 2004
-+++ gcc-3.4.2/gcc/final.c Thu Apr 7 00:00:05 2005
-@@ -146,6 +146,13 @@
-
- static rtx last_ignored_compare = 0;
-
-+/* Flag indicating this insn is the start of a new basic block. */
-+
-+#define NEW_BLOCK_LABEL 1
-+#define NEW_BLOCK_BRANCH 2
-+
-+static int new_block = NEW_BLOCK_LABEL;
-+
- /* Assign a unique number to each insn that is output.
- This can be used to generate unique local labels. */
-
-@@ -235,6 +242,7 @@
- #ifdef HAVE_ATTR_length
- static int align_fuzz (rtx, rtx, int, unsigned);
- #endif
-+static int output_store_cache_barrier (FILE *, rtx);
-
- /* Initialize data in final at the beginning of a compilation. */
-
-@@ -1505,6 +1513,7 @@
- int seen = 0;
-
- last_ignored_compare = 0;
-+ new_block = NEW_BLOCK_LABEL;
-
- #ifdef SDB_DEBUGGING_INFO
- /* When producing SDB debugging info, delete troublesome line number
-@@ -1571,6 +1580,7 @@
-
- insn = final_scan_insn (insn, file, optimize, prescan, 0, &seen);
- }
-+ new_block = 0;
- }
-
- const char *
-@@ -1851,6 +1861,7 @@
- #endif
- if (prescan > 0)
- break;
-+ new_block = NEW_BLOCK_LABEL;
-
- if (LABEL_NAME (insn))
- (*debug_hooks->label) (insn);
-@@ -2009,6 +2020,26 @@
-
- break;
- }
-+
-+#ifdef TARGET_IP28
-+ if (new_block)
-+ {
-+ /* .reorder: not really in the branch-delay-slot. */
-+ if (! set_noreorder)
-+ new_block = NEW_BLOCK_LABEL;
-+
-+ if (new_block == NEW_BLOCK_BRANCH)
-+ /* Not yet, only *after* the branch-delay-slot ! */
-+ new_block = NEW_BLOCK_LABEL;
-+ else
-+ {
-+ if (TARGET_IP28)
-+ output_store_cache_barrier (file, insn);
-+ new_block = 0;
-+ }
-+ }
-+#endif
-+
- /* Output this line note if it is the first or the last line
- note in a row. */
- if (notice_source_line (insn))
-@@ -2132,8 +2163,29 @@
- clobbered by the function. */
- if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN)
- {
-+#ifdef TARGET_IP28
-+ if (TARGET_IP28)
-+ new_block = NEW_BLOCK_LABEL;
-+#endif
- CC_STATUS_INIT;
- }
-+#ifdef TARGET_IP28
-+ /* Following a conditional branch sequence, we have a new basic
-+ block. */
-+ if (TARGET_IP28)
-+ {
-+ rtx insn = XVECEXP (body, 0, 0);
-+ rtx body = PATTERN (insn);
-+
-+ if ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
-+ && GET_CODE (SET_SRC (body)) != LABEL_REF)
-+ || (GET_CODE (insn) == JUMP_INSN
-+ && GET_CODE (body) == PARALLEL
-+ && GET_CODE (XVECEXP (body, 0, 0)) == SET
-+ && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))
-+ new_block = NEW_BLOCK_LABEL;
-+ }
-+#endif
- break;
- }
-
-@@ -2188,6 +2240,20 @@
- }
- #endif
-
-+#ifdef TARGET_IP28
-+ /* Following a conditional branch, we have a new basic block.
-+ But if we are inside a sequence, the new block starts after the
-+ last insn of the sequence. */
-+ if (TARGET_IP28 && final_sequence == 0
-+ && (GET_CODE (insn) == CALL_INSN
-+ || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
-+ && GET_CODE (SET_SRC (body)) != LABEL_REF)
-+ || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == PARALLEL
-+ && GET_CODE (XVECEXP (body, 0, 0)) == SET
-+ && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)))
-+ new_block = NEW_BLOCK_BRANCH;
-+#endif
-+
- #ifndef STACK_REGS
- /* Don't bother outputting obvious no-ops, even without -O.
- This optimization is fast and doesn't interfere with debugging.
-@@ -2402,6 +2468,7 @@
-
- if (prev_nonnote_insn (insn) != last_ignored_compare)
- abort ();
-+ new_block = 0;
-
- /* We have already processed the notes between the setter and
- the user. Make sure we don't process them again, this is
-@@ -2435,6 +2502,7 @@
- abort ();
- #endif
-
-+ new_block = 0;
- return new;
- }
-
-@@ -3866,3 +3934,254 @@
- symbol_queue_size = 0;
- }
- }
-+
-+
-+#ifdef TARGET_IP28
-+
-+/* Check, whether an instruction is a possibly harmful store instruction,
-+ i.e. a store which might cause damage, if speculatively executed. */
-+
-+static rtx
-+find_mem_expr (rtx xexp)
-+{
-+ if (xexp)
-+ {
-+ const char *fmt;
-+ int i, j, lng;
-+ rtx x;
-+ RTX_CODE code = GET_CODE (xexp);
-+
-+ if (MEM == code)
-+ return xexp;
-+
-+ fmt = GET_RTX_FORMAT (code);
-+ lng = GET_RTX_LENGTH (code);
-+
-+ for (i = 0; i < lng; ++i)
-+ switch (fmt[i])
-+ {
-+ case 'e':
-+ x = find_mem_expr (XEXP (xexp, i));
-+ if (x)
-+ return x;
-+ break;
-+ case 'E':
-+ if (XVEC (xexp, i))
-+ for (j = 0; j < XVECLEN (xexp, i); ++j)
-+ {
-+ x = find_mem_expr (XVECEXP (xexp, i, j));
-+ if (x)
-+ return x;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int
-+check_mem_expr (rtx memx)
-+{
-+ /* Check the expression `memx' (with type GET_CODE(memx) == MEM)
-+ for the most common stackpointer-addressing modes.
-+ It's not worthwile to avoid a cache barrier also on the
-+ remaining unfrequently used modes. */
-+ rtx x = XEXP (memx, 0);
-+ switch (GET_CODE (x))
-+ {
-+ case REG:
-+ if (REGNO (x) == STACK_POINTER_REGNUM)
-+ return 0;
-+ default:
-+ break;
-+ case PLUS: case MINUS: /* always `SP + const' ? */
-+ if (GET_CODE (XEXP (x, 1)) == REG
-+ && REGNO (XEXP (x, 1)) == STACK_POINTER_REGNUM)
-+ return 0;
-+ case NEG: case SIGN_EXTEND: case ZERO_EXTEND:
-+ if (GET_CODE (XEXP (x, 0)) == REG
-+ && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM)
-+ return 0;
-+ }
-+
-+ /* Stores/Loads to/from constant addresses can be considered
-+ harmless, since:
-+ 1) the address is always valid, even when taken speculatively.
-+ 2a) the location is (hopefully) never used as a dma-target, thus
-+ there is no danger of cache-inconsistency.
-+ 2b) uncached loads/stores are guaranteed to be non-speculative. */
-+ if ( CONSTANT_P(x) )
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* inline */ static int
-+check_pattern_for_store (rtx body)
-+{
-+ /* Check for (set (mem:M (non_stackpointer_address) ...)). Here we
-+ assume, that addressing with the stackpointer accesses neither
-+ uncached-aliased nor invalid memory. (May be, this applies to the
-+ global pointer and frame pointer also, but its saver not to assume
-+ it. And probably it's not worthwile to regard these registers)
-+
-+ Speculative loads from invalid addresses also cause bus errors...
-+ So check for (set (reg:M ...) (mem:M (non_stackpointer_address)))
-+ too. */
-+
-+ if (body && GET_CODE (body) == SET)
-+ {
-+ rtx x = find_mem_expr (body);
-+
-+ if (x && check_mem_expr (x))
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static int
-+check_insn_for_store (int state, rtx insn)
-+{
-+ /* Check for (ins (set (mem:M (dangerous_address)) ...)) or end of the
-+ current basic block.
-+ Criteria to recognize end-of/next basic-block are reduplicated here
-+ from final_scan_insn. */
-+
-+ rtx body;
-+ int code;
-+
-+ if (INSN_DELETED_P (insn))
-+ return 0;
-+
-+ switch (code = GET_CODE (insn))
-+ {
-+ case CODE_LABEL:
-+ return -1;
-+ case CALL_INSN:
-+ case JUMP_INSN:
-+ case INSN:
-+ body = PATTERN (insn);
-+ if (GET_CODE (body) == SEQUENCE)
-+ {
-+ /* A delayed-branch sequence */
-+ rtx ins0 = XVECEXP (body, 0, 0);
-+ rtx pat0 = PATTERN (ins0);
-+ int i;
-+ for (i = 0; i < XVECLEN (body, 0); i++)
-+ {
-+ rtx insq = XVECEXP (body, 0, i);
-+ if (! INSN_DELETED_P (insq))
-+ {
-+ int j = check_insn_for_store (state|1, insq);
-+ if (j)
-+ return j;
-+ }
-+ }
-+ /* Following a conditional branch sequence, we have a new
-+ basic block. */
-+ if (GET_CODE (ins0) == JUMP_INSN)
-+ if ((GET_CODE (pat0) == SET
-+ && GET_CODE (SET_SRC (pat0)) != LABEL_REF)
-+ || (GET_CODE (pat0) == PARALLEL
-+ && GET_CODE (XVECEXP (pat0, 0, 0)) == SET
-+ && GET_CODE (SET_SRC (XVECEXP (pat0, 0, 0))) != LABEL_REF))
-+ return -1;
-+ /* Handle a call sequence like a conditional branch sequence */
-+ if (GET_CODE (ins0) == CALL_INSN)
-+ return -1;
-+ break;
-+ }
-+ if (GET_CODE (body) == PARALLEL)
-+ {
-+ int i;
-+ for (i = 0; i < XVECLEN (body, 0); i++)
-+ if (check_pattern_for_store (XVECEXP (body, 0, i)))
-+ return 1;
-+ }
-+ /* Now, only a `simple' INSN or JUMP_INSN remains to be checked. */
-+ if (code == INSN)
-+ {
-+ /* Since we don't know, what's inside, we must take inline
-+ assembly to be dangerous */
-+ if (GET_CODE (body) == ASM_INPUT)
-+ return 1;
-+
-+ if (check_pattern_for_store (body))
-+ return 1;
-+ }
-+ /* Handle a CALL_INSN instruction like a conditional branch */
-+ if (code == JUMP_INSN || code == CALL_INSN)
-+ {
-+ /* Following a conditional branch, we have a new basic block. */
-+ int ckds = 0;
-+ if (code == CALL_INSN)
-+ ckds = 1;
-+ else
-+ {
-+ code = GET_CODE (body);
-+ if ((code == SET
-+ && GET_CODE (SET_SRC (body)) != LABEL_REF)
-+ || (code == PARALLEL
-+ && GET_CODE (XVECEXP (body, 0, 0)) == SET
-+ && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))
-+ ckds = 1;
-+ }
-+ if (ckds)
-+ {
-+ /* But check insn(s) in delay-slot first. If we could know in
-+ advance that this jump is in `.reorder' mode, where gas will
-+ insert a `nop' into the delay-slot, we could skip this test.
-+ Since we don't know, always assume `.noreorder', sometimes
-+ emitting a cache-barrier, that isn't needed. */
-+ /* But if we are here recursively, already checking a (pseudo-)
-+ delay-slot, we are done. */
-+ if ( !(state & 2) )
-+ for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
-+ switch (GET_CODE (insn))
-+ {
-+ case INSN:
-+ if (check_insn_for_store (state|1|2, insn) > 0)
-+ return 1;
-+ case CODE_LABEL:
-+ case CALL_INSN:
-+ case JUMP_INSN:
-+ return -1;
-+ default:
-+ /* skip NOTE,... */;
-+ }
-+ return -1;
-+ }
-+ }
-+ /*break*/
-+ }
-+ return 0;
-+}
-+
-+/* Scan a basic block, starting with `insn', for a possibly harmful store
-+ instruction. If found, output a cache barrier at the start of this
-+ block. */
-+
-+static int
-+output_store_cache_barrier (FILE *file, rtx insn)
-+{
-+ for (; insn; insn = NEXT_INSN (insn))
-+ {
-+ int found = check_insn_for_store (0, insn);
-+ if (found < 0)
-+ break;
-+ if (found > 0)
-+ {
-+ /* found critical store instruction */
-+ ASM_OUTPUT_R10K_CACHE_BARRIER(file);
-+ return 1;
-+ }
-+ }
-+ fprintf(file, "\t%s Cache Barrier omitted.\n", ASM_COMMENT_START);
-+ return 0;
-+}
-+
-+#endif /* TARGET_IP28 */
-+
-+/*
-+ * final.c Sun Jan 18 23:39:57 2004
-+ * final.c Sat Sep 18 00:23:34 2004 ip28
-+ */
+--- gcc-3.4.2/gcc/config/mips/mips.h Thu Jul 15 02:42:47 2004 ++++ gcc-3.4.2/gcc/config/mips/mips.h Sat Sep 18 00:41:48 2004 +@@ -122,6 +122,7 @@ + extern const char *mips_isa_string; /* for -mips{1,2,3,4} */ + extern const char *mips_abi_string; /* for -mabi={32,n32,64} */ + extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */ ++extern const char *mips_ip28_cache_barrier;/* for -mip28-cache-barrier */ + extern int mips_string_length; /* length of strings for mips16 */ + extern const struct mips_cpu_info mips_cpu_info_table[]; + extern const struct mips_cpu_info *mips_arch_info; +@@ -333,6 +334,7 @@ + #define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000) + #define TARGET_SB1 (mips_arch == PROCESSOR_SB1) + #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000) ++#define TARGET_IP28 (mips_ip28_cache_barrier != 0) + + /* Scheduling target defines. */ + #define TUNE_MIPS3000 (mips_tune == PROCESSOR_R3000) +@@ -752,6 +754,8 @@ + N_("Don't call any cache flush functions"), 0}, \ + { "flush-func=", &mips_cache_flush_func, \ + N_("Specify cache flush function"), 0}, \ ++ { "ip28-cache-barrier", &mips_ip28_cache_barrier, \ ++ N_("Generate special cache barriers for SGI Indigo2 R10k"), 0}, \ + } + + /* This is meant to be redefined in the host dependent files. */ +@@ -3448,3 +3452,11 @@ + " TEXT_SECTION_ASM_OP); + #endif + #endif ++ ++#define ASM_OUTPUT_R10K_CACHE_BARRIER(STREAM) \ ++ fprintf (STREAM, "\tcache 0x14,0($sp)\t%s Cache Barrier\n", ASM_COMMENT_START) ++ ++/* ++ * mips.h Thu Jul 15 02:42:47 2004 ++ * mips.h Fri Sep 17 23:18:19 2004 ip28 ++ */ +--- gcc-3.4.2/gcc/config/mips/mips.c Wed Jul 7 21:21:10 2004 ++++ gcc-3.4.2/gcc/config/mips/mips.c Fri Sep 17 23:33:44 2004 +@@ -502,6 +502,11 @@ + + const char *mips_cache_flush_func = CACHE_FLUSH_FUNC; + ++/* Nonzero means generate special cache barriers to inhibit speculative ++ stores which might endanger cache coherency or reference invalid ++ addresses (especially on SGI's Indigo2 R10k (IP28)). */ ++const char *mips_ip28_cache_barrier; ++ + /* If TRUE, we split addresses into their high and low parts in the RTL. */ + int mips_split_addresses; + +@@ -9676,3 +9681,7 @@ + #endif /* TARGET_IRIX */ + + #include "gt-mips.h" ++/* ++ * mips.c Wed Jul 7 21:21:10 2004 ++ * mips.c Fri Sep 17 23:25:53 2004 ip28 ++ */ +--- gcc-3.4.2/gcc/final.c Sun Jan 18 23:39:57 2004 ++++ gcc-3.4.2/gcc/final.c Thu Apr 7 00:00:05 2005 +@@ -146,6 +146,13 @@ + + static rtx last_ignored_compare = 0; + ++/* Flag indicating this insn is the start of a new basic block. */ ++ ++#define NEW_BLOCK_LABEL 1 ++#define NEW_BLOCK_BRANCH 2 ++ ++static int new_block = NEW_BLOCK_LABEL; ++ + /* Assign a unique number to each insn that is output. + This can be used to generate unique local labels. */ + +@@ -235,6 +242,7 @@ + #ifdef HAVE_ATTR_length + static int align_fuzz (rtx, rtx, int, unsigned); + #endif ++static int output_store_cache_barrier (FILE *, rtx); + + /* Initialize data in final at the beginning of a compilation. */ + +@@ -1505,6 +1513,7 @@ + int seen = 0; + + last_ignored_compare = 0; ++ new_block = NEW_BLOCK_LABEL; + + #ifdef SDB_DEBUGGING_INFO + /* When producing SDB debugging info, delete troublesome line number +@@ -1571,6 +1580,7 @@ + + insn = final_scan_insn (insn, file, optimize, prescan, 0, &seen); + } ++ new_block = 0; + } + + const char * +@@ -1851,6 +1861,7 @@ + #endif + if (prescan > 0) + break; ++ new_block = NEW_BLOCK_LABEL; + + if (LABEL_NAME (insn)) + (*debug_hooks->label) (insn); +@@ -2009,6 +2020,26 @@ + + break; + } ++ ++#ifdef TARGET_IP28 ++ if (new_block) ++ { ++ /* .reorder: not really in the branch-delay-slot. */ ++ if (! set_noreorder) ++ new_block = NEW_BLOCK_LABEL; ++ ++ if (new_block == NEW_BLOCK_BRANCH) ++ /* Not yet, only *after* the branch-delay-slot ! */ ++ new_block = NEW_BLOCK_LABEL; ++ else ++ { ++ if (TARGET_IP28) ++ output_store_cache_barrier (file, insn); ++ new_block = 0; ++ } ++ } ++#endif ++ + /* Output this line note if it is the first or the last line + note in a row. */ + if (notice_source_line (insn)) +@@ -2132,8 +2163,29 @@ + clobbered by the function. */ + if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN) + { ++#ifdef TARGET_IP28 ++ if (TARGET_IP28) ++ new_block = NEW_BLOCK_LABEL; ++#endif + CC_STATUS_INIT; + } ++#ifdef TARGET_IP28 ++ /* Following a conditional branch sequence, we have a new basic ++ block. */ ++ if (TARGET_IP28) ++ { ++ rtx insn = XVECEXP (body, 0, 0); ++ rtx body = PATTERN (insn); ++ ++ if ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET ++ && GET_CODE (SET_SRC (body)) != LABEL_REF) ++ || (GET_CODE (insn) == JUMP_INSN ++ && GET_CODE (body) == PARALLEL ++ && GET_CODE (XVECEXP (body, 0, 0)) == SET ++ && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)) ++ new_block = NEW_BLOCK_LABEL; ++ } ++#endif + break; + } + +@@ -2188,6 +2240,20 @@ + } + #endif + ++#ifdef TARGET_IP28 ++ /* Following a conditional branch, we have a new basic block. ++ But if we are inside a sequence, the new block starts after the ++ last insn of the sequence. */ ++ if (TARGET_IP28 && final_sequence == 0 ++ && (GET_CODE (insn) == CALL_INSN ++ || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET ++ && GET_CODE (SET_SRC (body)) != LABEL_REF) ++ || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == PARALLEL ++ && GET_CODE (XVECEXP (body, 0, 0)) == SET ++ && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))) ++ new_block = NEW_BLOCK_BRANCH; ++#endif ++ + #ifndef STACK_REGS + /* Don't bother outputting obvious no-ops, even without -O. + This optimization is fast and doesn't interfere with debugging. +@@ -2402,6 +2468,7 @@ + + if (prev_nonnote_insn (insn) != last_ignored_compare) + abort (); ++ new_block = 0; + + /* We have already processed the notes between the setter and + the user. Make sure we don't process them again, this is +@@ -2435,6 +2502,7 @@ + abort (); + #endif + ++ new_block = 0; + return new; + } + +@@ -3866,3 +3934,254 @@ + symbol_queue_size = 0; + } + } ++ ++ ++#ifdef TARGET_IP28 ++ ++/* Check, whether an instruction is a possibly harmful store instruction, ++ i.e. a store which might cause damage, if speculatively executed. */ ++ ++static rtx ++find_mem_expr (rtx xexp) ++{ ++ if (xexp) ++ { ++ const char *fmt; ++ int i, j, lng; ++ rtx x; ++ RTX_CODE code = GET_CODE (xexp); ++ ++ if (MEM == code) ++ return xexp; ++ ++ fmt = GET_RTX_FORMAT (code); ++ lng = GET_RTX_LENGTH (code); ++ ++ for (i = 0; i < lng; ++i) ++ switch (fmt[i]) ++ { ++ case 'e': ++ x = find_mem_expr (XEXP (xexp, i)); ++ if (x) ++ return x; ++ break; ++ case 'E': ++ if (XVEC (xexp, i)) ++ for (j = 0; j < XVECLEN (xexp, i); ++j) ++ { ++ x = find_mem_expr (XVECEXP (xexp, i, j)); ++ if (x) ++ return x; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int ++check_mem_expr (rtx memx) ++{ ++ /* Check the expression `memx' (with type GET_CODE(memx) == MEM) ++ for the most common stackpointer-addressing modes. ++ It's not worthwile to avoid a cache barrier also on the ++ remaining unfrequently used modes. */ ++ rtx x = XEXP (memx, 0); ++ switch (GET_CODE (x)) ++ { ++ case REG: ++ if (REGNO (x) == STACK_POINTER_REGNUM) ++ return 0; ++ default: ++ break; ++ case PLUS: case MINUS: /* always `SP + const' ? */ ++ if (GET_CODE (XEXP (x, 1)) == REG ++ && REGNO (XEXP (x, 1)) == STACK_POINTER_REGNUM) ++ return 0; ++ case NEG: case SIGN_EXTEND: case ZERO_EXTEND: ++ if (GET_CODE (XEXP (x, 0)) == REG ++ && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM) ++ return 0; ++ } ++ ++ /* Stores/Loads to/from constant addresses can be considered ++ harmless, since: ++ 1) the address is always valid, even when taken speculatively. ++ 2a) the location is (hopefully) never used as a dma-target, thus ++ there is no danger of cache-inconsistency. ++ 2b) uncached loads/stores are guaranteed to be non-speculative. */ ++ if ( CONSTANT_P(x) ) ++ return 0; ++ ++ return 1; ++} ++ ++/* inline */ static int ++check_pattern_for_store (rtx body) ++{ ++ /* Check for (set (mem:M (non_stackpointer_address) ...)). Here we ++ assume, that addressing with the stackpointer accesses neither ++ uncached-aliased nor invalid memory. (May be, this applies to the ++ global pointer and frame pointer also, but its saver not to assume ++ it. And probably it's not worthwile to regard these registers) ++ ++ Speculative loads from invalid addresses also cause bus errors... ++ So check for (set (reg:M ...) (mem:M (non_stackpointer_address))) ++ too. */ ++ ++ if (body && GET_CODE (body) == SET) ++ { ++ rtx x = find_mem_expr (body); ++ ++ if (x && check_mem_expr (x)) ++ return 1; ++ } ++ return 0; ++} ++ ++static int ++check_insn_for_store (int state, rtx insn) ++{ ++ /* Check for (ins (set (mem:M (dangerous_address)) ...)) or end of the ++ current basic block. ++ Criteria to recognize end-of/next basic-block are reduplicated here ++ from final_scan_insn. */ ++ ++ rtx body; ++ int code; ++ ++ if (INSN_DELETED_P (insn)) ++ return 0; ++ ++ switch (code = GET_CODE (insn)) ++ { ++ case CODE_LABEL: ++ return -1; ++ case CALL_INSN: ++ case JUMP_INSN: ++ case INSN: ++ body = PATTERN (insn); ++ if (GET_CODE (body) == SEQUENCE) ++ { ++ /* A delayed-branch sequence */ ++ rtx ins0 = XVECEXP (body, 0, 0); ++ rtx pat0 = PATTERN (ins0); ++ int i; ++ for (i = 0; i < XVECLEN (body, 0); i++) ++ { ++ rtx insq = XVECEXP (body, 0, i); ++ if (! INSN_DELETED_P (insq)) ++ { ++ int j = check_insn_for_store (state|1, insq); ++ if (j) ++ return j; ++ } ++ } ++ /* Following a conditional branch sequence, we have a new ++ basic block. */ ++ if (GET_CODE (ins0) == JUMP_INSN) ++ if ((GET_CODE (pat0) == SET ++ && GET_CODE (SET_SRC (pat0)) != LABEL_REF) ++ || (GET_CODE (pat0) == PARALLEL ++ && GET_CODE (XVECEXP (pat0, 0, 0)) == SET ++ && GET_CODE (SET_SRC (XVECEXP (pat0, 0, 0))) != LABEL_REF)) ++ return -1; ++ /* Handle a call sequence like a conditional branch sequence */ ++ if (GET_CODE (ins0) == CALL_INSN) ++ return -1; ++ break; ++ } ++ if (GET_CODE (body) == PARALLEL) ++ { ++ int i; ++ for (i = 0; i < XVECLEN (body, 0); i++) ++ if (check_pattern_for_store (XVECEXP (body, 0, i))) ++ return 1; ++ } ++ /* Now, only a `simple' INSN or JUMP_INSN remains to be checked. */ ++ if (code == INSN) ++ { ++ /* Since we don't know, what's inside, we must take inline ++ assembly to be dangerous */ ++ if (GET_CODE (body) == ASM_INPUT) ++ return 1; ++ ++ if (check_pattern_for_store (body)) ++ return 1; ++ } ++ /* Handle a CALL_INSN instruction like a conditional branch */ ++ if (code == JUMP_INSN || code == CALL_INSN) ++ { ++ /* Following a conditional branch, we have a new basic block. */ ++ int ckds = 0; ++ if (code == CALL_INSN) ++ ckds = 1; ++ else ++ { ++ code = GET_CODE (body); ++ if ((code == SET ++ && GET_CODE (SET_SRC (body)) != LABEL_REF) ++ || (code == PARALLEL ++ && GET_CODE (XVECEXP (body, 0, 0)) == SET ++ && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)) ++ ckds = 1; ++ } ++ if (ckds) ++ { ++ /* But check insn(s) in delay-slot first. If we could know in ++ advance that this jump is in `.reorder' mode, where gas will ++ insert a `nop' into the delay-slot, we could skip this test. ++ Since we don't know, always assume `.noreorder', sometimes ++ emitting a cache-barrier, that isn't needed. */ ++ /* But if we are here recursively, already checking a (pseudo-) ++ delay-slot, we are done. */ ++ if ( !(state & 2) ) ++ for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn)) ++ switch (GET_CODE (insn)) ++ { ++ case INSN: ++ if (check_insn_for_store (state|1|2, insn) > 0) ++ return 1; ++ case CODE_LABEL: ++ case CALL_INSN: ++ case JUMP_INSN: ++ return -1; ++ default: ++ /* skip NOTE,... */; ++ } ++ return -1; ++ } ++ } ++ /*break*/ ++ } ++ return 0; ++} ++ ++/* Scan a basic block, starting with `insn', for a possibly harmful store ++ instruction. If found, output a cache barrier at the start of this ++ block. */ ++ ++static int ++output_store_cache_barrier (FILE *file, rtx insn) ++{ ++ for (; insn; insn = NEXT_INSN (insn)) ++ { ++ int found = check_insn_for_store (0, insn); ++ if (found < 0) ++ break; ++ if (found > 0) ++ { ++ /* found critical store instruction */ ++ ASM_OUTPUT_R10K_CACHE_BARRIER(file); ++ return 1; ++ } ++ } ++ fprintf(file, "\t%s Cache Barrier omitted.\n", ASM_COMMENT_START); ++ return 0; ++} ++ ++#endif /* TARGET_IP28 */ ++ ++/* ++ * final.c Sun Jan 18 23:39:57 2004 ++ * final.c Sat Sep 18 00:23:34 2004 ip28 ++ */ |