summaryrefslogtreecommitdiffstats
path: root/patches/gcc-4.2.3/generic/gentoo/91_all_mips-ip28_cache_barriers-v4.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/gcc-4.2.3/generic/gentoo/91_all_mips-ip28_cache_barriers-v4.patch')
-rw-r--r--patches/gcc-4.2.3/generic/gentoo/91_all_mips-ip28_cache_barriers-v4.patch352
1 files changed, 0 insertions, 352 deletions
diff --git a/patches/gcc-4.2.3/generic/gentoo/91_all_mips-ip28_cache_barriers-v4.patch b/patches/gcc-4.2.3/generic/gentoo/91_all_mips-ip28_cache_barriers-v4.patch
deleted file mode 100644
index 48d52f6..0000000
--- a/patches/gcc-4.2.3/generic/gentoo/91_all_mips-ip28_cache_barriers-v4.patch
+++ /dev/null
@@ -1,352 +0,0 @@
----
- gcc/config/mips/mips.c | 7
- gcc/config/mips/mips.opt | 10 +
- gcc/config/mips/r10k-cacheb.c | 298 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 315 insertions(+)
-
-Index: gcc-4.2.3/gcc/config/mips/mips.c
-===================================================================
---- gcc-4.2.3.orig/gcc/config/mips/mips.c
-+++ gcc-4.2.3/gcc/config/mips/mips.c
-@@ -255,6 +255,9 @@ static const char *const mips_fp_conditi
- MIPS_FP_CONDITIONS (STRINGIFY)
- };
-
-+/* R10K Cache Barrier Functions */
-+#include "r10k-cacheb.c"
-+
- /* A function to save or store a register. The first argument is the
- register and the second is the stack slot. */
- typedef void (*mips_save_restore_fn) (rtx, rtx);
-@@ -8908,6 +8911,10 @@ vr4130_avoid_branch_rt_conflict (rtx ins
- XEXP (cond, 1) = tmp;
- }
- }
-+ if (TARGET_R10K_SPECEX)
-+ {
-+ r10k_insert_cache_barriers ();
-+ }
- }
-
- /* Implement -mvr4130-align. Go through each basic block and simulate the
-Index: gcc-4.2.3/gcc/config/mips/mips.opt
-===================================================================
---- gcc-4.2.3.orig/gcc/config/mips/mips.opt
-+++ gcc-4.2.3/gcc/config/mips/mips.opt
-@@ -219,3 +219,13 @@ Perform VR4130-specific alignment optimi
- mxgot
- Target Report Var(TARGET_XGOT)
- Lift restrictions on GOT size
-+
-+mr10k-cache-barrier=
-+Target Report Joined UInteger Var(TARGET_R10K_SPECEX)
-+-mr10k-cache-barrier[=1|2] Generate cache barriers for SGI Indigo2/O2 R10k
-+
-+mr10k-cache-barrier
-+Target Undocumented Var(TARGET_R10K_SPECEX) VarExists
-+
-+mip28-cache-barrier
-+Target Undocumented Var(TARGET_R10K_SPECEX) VarExists
-Index: gcc-4.2.3/gcc/config/mips/r10k-cacheb.c
-===================================================================
---- /dev/null
-+++ gcc-4.2.3/gcc/config/mips/r10k-cacheb.c
-@@ -0,0 +1,298 @@
-+/* Subroutines used for MIPS code generation: generate cache-barriers
-+ for SiliconGraphics IP28 and IP32/R10000 kernel-code.
-+ Copyright (C) 2005,2006 peter fuerst, pf@net.alphadv.de.
-+
-+This file is intended to become part of GCC.
-+
-+This file is free software; you can redistribute it and/or modify it
-+under the terms of the GNU General Public License as published
-+by the Free Software Foundation; either version 2, or (at your
-+option) any later version.
-+
-+This file is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to the
-+Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-+MA 02110-1301 USA. */
-+
-+
-+#define ASM_R10K_CACHE_BARRIER "cache 0x14,0($sp)"
-+
-+static int is_stack_pointer (rtx *x, void *data);
-+static int check_p_mem_expr (rtx *memx, void *data);
-+static int check_p_pattern_for_store (rtx *body, void *data);
-+static int strmatch (const char *txt, const char *match);
-+static int check_insn_for_store (int state, rtx insn);
-+static int bb_insert_store_cache_barrier (rtx head, rtx nxtb);
-+static int scan_1_bb_for_store (rtx head, rtx end);
-+static int r10k_insert_cache_barriers (void);
-+
-+
-+/* Check, whether an instruction is a possibly harmful store instruction,
-+ i.e. a store which might cause damage, if speculatively executed. */
-+
-+/* Return truth value whether the expression `*memx' instantiates
-+ (mem:M (not (stackpointer_address or constant))). */
-+
-+static int
-+is_stack_pointer (rtx *x, void *data)
-+{
-+ return (*x == stack_pointer_rtx);
-+}
-+
-+static int
-+check_p_mem_expr (rtx *memx, void *data)
-+{
-+ if (!MEM_P (*memx) || for_each_rtx (memx, is_stack_pointer, 0))
-+ 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(XEXP (*memx, 0)) )
-+ return 0;
-+
-+ return 1;
-+}
-+
-+/* Return truth value whether we find (set (mem:M (non_stackpointer_address)
-+ ...)) in instruction-pattern `body'.
-+ 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, unless there is an enhanced bus-error handler. */
-+
-+static int
-+check_p_pattern_for_store (rtx *body, void *data)
-+{
-+ if (*body && GET_CODE (*body) == SET)
-+ {
-+ /* Cache-barriers for SET_SRC may be requested as well. */
-+ if (!(TARGET_R10K_SPECEX & 2))
-+ body = &SET_DEST(*body);
-+
-+ if (for_each_rtx (body, check_p_mem_expr, 0))
-+ return 1;
-+
-+ /* Don't traverse sub-expressions again. */
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static int
-+strmatch (const char *txt, const char *match)
-+{
-+ return !strncmp(txt, match, strlen (match));
-+}
-+
-+/* Check for (ins (set (mem:M (dangerous_address)) ...)) or end of the
-+ current basic block in instruction `insn'.
-+ `state': (internal) recursion-counter and delayslot-flag
-+ Criteria to recognize end-of/next basic-block are reduplicated here
-+ from final_scan_insn.
-+ return >0: `insn' is critical.
-+ return <0: `insn' is at end of current basic-block.
-+ return 0: `insn' can be ignored. */
-+
-+static int
-+check_insn_for_store (int state, rtx insn)
-+{
-+ rtx body;
-+
-+ if (INSN_DELETED_P (insn))
-+ return 0;
-+
-+ if (LABEL_P (insn))
-+ return -1;
-+
-+ if (CALL_P (insn) || JUMP_P (insn) || NONJUMP_INSN_P (insn))
-+ {
-+ body = PATTERN (insn);
-+ if (GET_CODE (body) == SEQUENCE)
-+ {
-+ /* A delayed-branch sequence. */
-+ rtx insq;
-+ FOR_EACH_SUBINSN(insq, insn)
-+ if (! INSN_DELETED_P (insq))
-+ {
-+ /* |1: delay-slot completely contained in sequence. */
-+ if (check_insn_for_store (8+state|1, insq) > 0)
-+ return 1;
-+ }
-+ /* Following a (conditional) branch sequence, we have a new
-+ basic block. */
-+ if (JUMP_P (SEQ_BEGIN(insn)))
-+ return -1;
-+ /* Handle a call sequence like a conditional branch sequence. */
-+ if (CALL_P (SEQ_BEGIN(insn)))
-+ return -1;
-+ }
-+ if (GET_CODE (body) == PARALLEL)
-+ if (for_each_rtx (&body, check_p_pattern_for_store, 0))
-+ return 1;
-+
-+ /* Now, only a `simple' INSN or JUMP_INSN remains to be checked. */
-+ if (NONJUMP_INSN_P (insn))
-+ {
-+ /* Since we don't know what's inside, we must take inline
-+ assembly to be dangerous. */
-+ if (GET_CODE (body) == ASM_INPUT)
-+ {
-+ const char *t = XSTR (body, 0);
-+ if (t && !strmatch(t, ASM_R10K_CACHE_BARRIER))
-+ return 1;
-+ }
-+
-+ if (check_p_pattern_for_store (&body, 0) > 0)
-+ return 1;
-+ }
-+ /* Handle a CALL_INSN instruction like a conditional branch. */
-+ if (JUMP_P (insn) || CALL_P (insn))
-+ {
-+ /* Following a (conditional) branch, we have a new basic block. */
-+ /* 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 & 1) )
-+ for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
-+ {
-+ if (LABEL_P (insn) || CALL_P (insn) || JUMP_P (insn))
-+ /* Not in delay-slot at all. */
-+ break;
-+
-+ if (NONJUMP_INSN_P (insn))
-+ {
-+ if (GET_CODE (PATTERN (insn)) == SEQUENCE)
-+ /* Not in delay-slot at all. */
-+ break;
-+
-+ if (check_insn_for_store (8+state|1, insn) > 0)
-+ return 1;
-+ /* We're done anyway. */
-+ break;
-+ }
-+ /* skip NOTE,... */;
-+ }
-+ return -1;
-+ }
-+ }
-+ 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
-+bb_insert_store_cache_barrier (rtx head, rtx nxtb)
-+{
-+ rtx insn = head;
-+
-+ if (!insn || insn == nxtb)
-+ return 0;
-+
-+ while ((insn = NEXT_INSN (insn)) && insn != nxtb)
-+ {
-+ int found;
-+
-+ if (NOTE_INSN_BASIC_BLOCK_P(insn)) /* See scan_1_bb_for_store() */
-+ break;
-+
-+ found = check_insn_for_store (0, insn);
-+ if (found < 0)
-+ break;
-+ if (found > 0)
-+ {
-+ /* found critical store instruction */
-+ insn = gen_rtx_ASM_INPUT (VOIDmode,
-+ ASM_R10K_CACHE_BARRIER "\t"
-+ ASM_COMMENT_START " Cache Barrier");
-+ /* Here we rely on the assumption, that an explicit delay-slot
-+ - if any - is already embedded (in a sequence) in 'head'! */
-+ insn = emit_insn_after (insn, head);
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+/* Scan one basic block for a possibly harmful store instruction.
-+ If found, insert a cache barrier at the start of this block,
-+ return number of inserted cache_barriers. */
-+
-+static int
-+scan_1_bb_for_store (rtx head, rtx end)
-+{
-+ rtx nxtb;
-+ int count;
-+ gcc_assert (head);
-+ gcc_assert (end);
-+
-+ /* Note: 'end' is not necessarily reached from 'head' (hidden in
-+ SEQUENCE, PARALLEL), but 'nxtb' is. */
-+ nxtb = NEXT_INSN (end);
-+
-+ /* Each basic block starts with zero or more CODE_LABEL(s), followed
-+ by one NOTE_INSN_BASIC_BLOCK.
-+ Note: bb_head may equal next_insn(bb_end) already ! */
-+ while (head && head != nxtb && LABEL_P (head))
-+ head = NEXT_INSN (head);
-+
-+ if (!head || head == nxtb)
-+ return 0;
-+
-+ /* Handle the basic block itself, at most up to next CALL_INSN. */
-+ count = bb_insert_store_cache_barrier (head, nxtb);
-+
-+ /* 1) Handle any CALL_INSN instruction like a conditional branch.
-+ 2) There may be "basic blocks" in the list, which are no basic blocks
-+ at all. (containing CODE_LABELs in the body or gathering several
-+ other basic blocks (e.g. bb5 containing bb6,bb7,bb8)). */
-+
-+ while ((head = NEXT_INSN (head)) && head != nxtb)
-+ {
-+ if (INSN_DELETED_P (head))
-+ continue;
-+
-+ /* Later we'll be called again for this bb on its own. */
-+ if (NOTE_INSN_BASIC_BLOCK_P(head))
-+ break;
-+
-+ if (CALL_P (SEQ_BEGIN (head)) || LABEL_P (head))
-+ count += bb_insert_store_cache_barrier (head, nxtb);
-+ }
-+ return count;
-+}
-+
-+static int
-+r10k_insert_cache_barriers (void)
-+{
-+ if (TARGET_R10K_SPECEX)
-+ {
-+ basic_block bb;
-+
-+ FOR_EACH_BB (bb)
-+ if (0 <= bb->index)
-+ scan_1_bb_for_store (BB_HEAD (bb), BB_END (bb));
-+ }
-+ return 0;
-+}