Add ip28 cache barrier patch for gcc-mips64. Anyone using this probably has an inkli...
authorJoshua Kinard <kumba@gentoo.org>
Sun, 9 Jan 2005 19:14:57 +0000 (19:14 +0000)
committerJoshua Kinard <kumba@gentoo.org>
Sun, 9 Jan 2005 19:14:57 +0000 (19:14 +0000)
sys-devel/gcc-mips64/ChangeLog
sys-devel/gcc-mips64/Manifest
sys-devel/gcc-mips64/files/digest-gcc-mips64-3.4.3-r1 [moved from sys-devel/gcc-mips64/files/digest-gcc-mips64-3.4.3 with 100% similarity]
sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers.patch [new file with mode: 0644]
sys-devel/gcc-mips64/gcc-mips64-3.3.4.ebuild
sys-devel/gcc-mips64/gcc-mips64-3.4.3-r1.ebuild [moved from sys-devel/gcc-mips64/gcc-mips64-3.4.3.ebuild with 92% similarity]

index af0df97413786104cf1ab4da56d4cdb40463162a..b1ed33baff9d4683fa25981b8059379231b87fdd 100644 (file)
@@ -1,6 +1,15 @@
 # ChangeLog for sys-devel/gcc-mips64
-# Copyright 2000-2004 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-mips64/ChangeLog,v 1.10 2004/12/09 09:09:31 kumba Exp $
+# Copyright 2000-2005 Gentoo Foundation; Distributed under the GPL v2
+# $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-mips64/ChangeLog,v 1.11 2005/01/09 19:14:57 kumba Exp $
+
+*gcc-mips64-3.4.3-r1 (09 Jan 2005)
+
+  09 Jan 2005; Joshua Kinard <kumba@gentoo.org>
+  +files/gcc-3.4.2-mips-ip28_cache_barriers.patch,
+  +gcc-mips64-3.4.3-r1.ebuild, -gcc-mips64-3.4.3.ebuild:
+  Add ip28 cache barrier patch for gcc-mips64. Anyone using this probably has an
+  inkling of what it does. Only used in this case for kernels. The system gcc
+  can use it for other things is absolutely needed.
 
   09 Dec 2004; Joshua Kinard <kumba@gentoo.org>
   -files/gcc-3.3.1-gentoo-branding.patch,
index c56ead27d7ef0556fbd17560f533a569d809a97c..5e432d71877ef0c45b016c714329540856648f6f 100644 (file)
@@ -1,7 +1,8 @@
-MD5 3f317a7f3997988a364ac24aca50bc72 ChangeLog 2115
-MD5 d7fe0f1e03d3a3da354d85d9736a2abd gcc-mips64-3.3.4.ebuild 3199
-MD5 2de4dbb62f15fd281adcf46292702343 gcc-mips64-3.4.3.ebuild 3439
+MD5 dc61ca27c76aab1530ce71a6f6729c1f ChangeLog 2519
+MD5 44ff44c4acd143a859bba23a2eccd1e6 gcc-mips64-3.4.3-r1.ebuild 3611
+MD5 2685f15ddbacd2b6b6d6ba80192e4813 gcc-mips64-3.3.4.ebuild 3199
 MD5 efda60760635b5f29e31a8f730a73086 metadata.xml 364
+MD5 f3a1b668077c6486c542dcef1cdd9672 files/gcc-3.4.2-mips-ip28_cache_barriers.patch 12545
+MD5 2ca380cbcf0547fb5d2a671c1c0296de files/digest-gcc-mips64-3.4.3-r1 64
 MD5 af241dd07c46bc5b0c2d54eac803f1f3 files/digest-gcc-mips64-3.3.4 151
-MD5 2ca380cbcf0547fb5d2a671c1c0296de files/digest-gcc-mips64-3.4.3 64
 MD5 e411938ca2908079a2359fed5cb3b442 files/gcc-3.3.4-gentoo-branding.patch 874
diff --git a/sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers.patch b/sys-devel/gcc-mips64/files/gcc-3.4.2-mips-ip28_cache_barriers.patch
new file mode 100644 (file)
index 0000000..38b1832
--- /dev/null
@@ -0,0 +1,392 @@
+--- 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
++\f
++#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      Fri Nov 19 00:40:50 2004
+@@ -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);
+ \f
+ /* 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;
+ }
+ \f
+ 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,188 @@
+       symbol_queue_size = 0;
+     }
+ }
++
++
++#ifdef TARGET_IP28
++
++/* Check, whether `insn' is a possibly harmful store instruction, i.e.
++   a store which might cause damage, if speculatively executed. */
++
++static int /*inline*/
++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) */
++
++  if (body && GET_CODE (body) == SET)
++    {
++      rtx xexp = SET_DEST (body);
++      if (GET_CODE (xexp) == MEM)
++        {
++          /* Check for the most common stackpointer-addressing modes.
++             It's not worthwile to avoid a cache barrier also on the
++             remaining unfrequently used modes.  */
++          xexp = XEXP (xexp, 0);
++          switch (GET_CODE (xexp))
++            {
++            case REG:
++              if (REGNO (xexp) == STACK_POINTER_REGNUM)
++                return 0;
++              break;
++            case PLUS: case MINUS: /* always `SP + const' ? */
++              if (GET_CODE (XEXP (xexp, 0)) == REG
++                  && REGNO (XEXP (xexp, 0)) == STACK_POINTER_REGNUM)
++                return 0;
++              if (GET_CODE (XEXP (xexp, 1)) == REG
++                  && REGNO (XEXP (xexp, 1)) == STACK_POINTER_REGNUM)
++                return 0;
++            }
++          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)
++        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
++ */
index 19c838fff7a8efce1c5f8f750d7e0f7ed7e7f586..ff7eb250dc1f8538347b2ecae11698f3598bdb49 100644 (file)
@@ -1,6 +1,6 @@
-# Copyright 1999-2004 Gentoo Foundation
+# Copyright 1999-2005 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-mips64/gcc-mips64-3.3.4.ebuild,v 1.3 2004/12/09 09:09:31 kumba Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-mips64/gcc-mips64-3.3.4.ebuild,v 1.4 2005/01/09 19:14:57 kumba Exp $
 
 
 # Variables 
similarity index 92%
rename from sys-devel/gcc-mips64/gcc-mips64-3.4.3.ebuild
rename to sys-devel/gcc-mips64/gcc-mips64-3.4.3-r1.ebuild
index 2de44b1ba756cc382c23fe3a48aab323193ce780..d651862d95661697965547fc90a851961474515d 100644 (file)
@@ -1,6 +1,6 @@
-# Copyright 1999-2004 Gentoo Foundation
+# Copyright 1999-2005 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-mips64/gcc-mips64-3.4.3.ebuild,v 1.2 2004/12/09 09:09:31 kumba Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-devel/gcc-mips64/gcc-mips64-3.4.3-r1.ebuild,v 1.1 2005/01/09 19:14:57 kumba Exp $
 
 
 # Variables 
@@ -10,6 +10,7 @@ TMP_P="${P/-${MYARCH}/}"
 TMP_PN="${PN/-${MYARCH}/}"
 I="/usr"
 S="${WORKDIR}/${P}"
+IUSE="ip28"
 BRANCH_UPDATE=""
 
 DESCRIPTION="Mips64 Kernel Compiler (Experimental)"
@@ -54,6 +55,11 @@ src_unpack() {
                epatch ${WORKDIR}/${TMP_P}-branch-update-${BRANCH_UPDATE}.patch
        fi
 
+       # If on an IP28 box (set by profile), then add in cache barrier patch
+       if use ip28; then
+               epatch ${FILESDIR}/gcc-3.4.2-mips-ip28_cache_barriers.patch
+       fi
+
        # Make gcc's version info specific to Gentoo
        gcc_version_patch "(Gentoo Linux ${PVR})"
 }