diff options
Diffstat (limited to 'sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch')
-rw-r--r-- | sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch | 458 |
1 files changed, 0 insertions, 458 deletions
diff --git a/sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch b/sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch deleted file mode 100644 index d91c9f2738d5..000000000000 --- a/sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers-v2.patch +++ /dev/null @@ -1,458 +0,0 @@ ---- 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 -+ */ |