summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--recipes/gcc/gcc-4.1.2.inc6
-rw-r--r--recipes/gcc/gcc-4.1.2/gcc-config-nios2.patch41
-rw-r--r--recipes/gcc/gcc-4.1.2/gcc-nios2.patch11017
-rw-r--r--recipes/gcc/gcc-4.1.2/nios2-lib-flags.patch10
4 files changed, 11074 insertions, 0 deletions
diff --git a/recipes/gcc/gcc-4.1.2.inc b/recipes/gcc/gcc-4.1.2.inc
index e89a8de241..3b6cf30913 100644
--- a/recipes/gcc/gcc-4.1.2.inc
+++ b/recipes/gcc/gcc-4.1.2.inc
@@ -33,6 +33,12 @@ SRC_URI = "${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.bz2;name=archive \
SRC_URI_append_sh3 = " file://sh3-installfix-fixheaders.patch "
+SRC_URI_append_nios2 = " \
+ file://gcc-nios2.patch \
+ file://gcc-config-nios2.patch \
+ file://nios2-lib-flags.patch \
+ "
+
SRC_URI_avr32 = "http://www.angstrom-distribution.org/unstable/sources/gcc-4.1.2-atmel.1.1.0.tar.gz;name=atmel \
# file://100-uclibc-conf.patch \
# file://200-uclibc-locale.patch \
diff --git a/recipes/gcc/gcc-4.1.2/gcc-config-nios2.patch b/recipes/gcc/gcc-4.1.2/gcc-config-nios2.patch
new file mode 100644
index 0000000000..1cd5a955d3
--- /dev/null
+++ b/recipes/gcc/gcc-4.1.2/gcc-config-nios2.patch
@@ -0,0 +1,41 @@
+Index: gcc-4.1.2/config.sub
+===================================================================
+--- gcc-4.1.2.orig/config.sub 2010-05-27 15:30:45.069455792 +0200
++++ gcc-4.1.2/config.sub 2010-05-27 15:36:32.868205558 +0200
+@@ -267,6 +267,7 @@
+ | mn10200 | mn10300 \
+ | mt \
+ | msp430 \
++ | nios2 \
+ | ns16k | ns32k \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+@@ -349,6 +350,7 @@
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
++ | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+Index: gcc-4.1.2/gcc/config.gcc
+===================================================================
+--- gcc-4.1.2.orig/gcc/config.gcc 2010-05-27 15:30:45.039455207 +0200
++++ gcc-4.1.2/gcc/config.gcc 2010-05-27 15:33:26.249455379 +0200
+@@ -1597,6 +1597,16 @@
+ tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
+ tmake_file="${tmake_file} mt/t-mt"
+ ;;
++nios2-*-*)
++ tm_file="elfos.h ${tm_file}"
++ tmake_file="${tmake_file} nios2/t-nios2"
++ case ${target} in
++ nios2-*-linux*)
++ tm_file="${tm_file} linux.h nios2/linux.h"
++ tmake_file="${tmake_file} nios2/t-linux"
++ ;;
++ esac
++ ;;
+ ns32k-*-netbsdelf*)
+ echo "GCC does not yet support the ${target} target"; exit 1
+ ;;
diff --git a/recipes/gcc/gcc-4.1.2/gcc-nios2.patch b/recipes/gcc/gcc-4.1.2/gcc-nios2.patch
new file mode 100644
index 0000000000..80a46b7751
--- /dev/null
+++ b/recipes/gcc/gcc-4.1.2/gcc-nios2.patch
@@ -0,0 +1,11017 @@
+Index: gcc-4.1.2/gcc/config/nios2/crti.asm
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/crti.asm 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,97 @@
++/* NOT ASSIGNED TO FSF. COPYRIGHT ALTERA. */
++/*
++ Copyright (C) 2003
++ by Jonah Graham (jgraham@altera.com)
++
++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.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++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 this program; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.
++
++ As a special exception, if you link this library with files
++ compiled with GCC to produce an executable, this does not cause
++ the resulting executable to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License.
++
++
++This file just make a stack frame for the contents of the .fini and
++.init sections. Users may put any desired instructions in those
++sections.
++
++
++While technically any code can be put in the init and fini sections
++most stuff will not work other than stuff which obeys the call frame
++and ABI. All the call-preserved registers are saved, the call clobbered
++registers should have been saved by the code calling init and fini.
++
++See crtstuff.c for an example of code that inserts itself in the
++init and fini sections.
++
++See crt0.s for the code that calls init and fini.
++*/
++
++ .file "crti.asm"
++
++ .section ".init"
++ .align 2
++ .global _init
++_init:
++ addi sp, sp, -48
++ stw ra, 44(sp)
++ stw r23, 40(sp)
++ stw r22, 36(sp)
++ stw r21, 32(sp)
++ stw r20, 28(sp)
++ stw r19, 24(sp)
++ stw r18, 20(sp)
++ stw r17, 16(sp)
++ stw r16, 12(sp)
++ stw fp, 8(sp)
++ addi fp, sp, 8
++ nextpc r22
++1: movhi r2, %hiadj(_GLOBAL_OFFSET_TABLE_ - 1b)
++ addi r2, r2, %lo(_GLOBAL_OFFSET_TABLE_ - 1b)
++ add r22, r22, r2
++
++
++ .section ".fini"
++ .align 2
++ .global _fini
++_fini:
++ addi sp, sp, -48
++ stw ra, 44(sp)
++ stw r23, 40(sp)
++ stw r22, 36(sp)
++ stw r21, 32(sp)
++ stw r20, 28(sp)
++ stw r19, 24(sp)
++ stw r18, 20(sp)
++ stw r17, 16(sp)
++ stw r16, 12(sp)
++ stw fp, 8(sp)
++ addi fp, sp, 8
++ nextpc r22
++1: movhi r2, %hiadj(_GLOBAL_OFFSET_TABLE_ - 1b)
++ addi r2, r2, %lo(_GLOBAL_OFFSET_TABLE_ - 1b)
++ add r22, r22, r2
++
++
+Index: gcc-4.1.2/gcc/config/nios2/crtn.asm
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/crtn.asm 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,71 @@
++/* NOT ASSIGNED TO FSF. COPYRIGHT ALTERA. */
++/*
++ Copyright (C) 2003
++ by Jonah Graham (jgraham@altera.com)
++
++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.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++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 this program; see the file COPYING. If not, write to
++the Free Software Foundation, 59 Temple Place - Suite 330,
++Boston, MA 02111-1307, USA.
++
++ As a special exception, if you link this library with files
++ compiled with GCC to produce an executable, this does not cause
++ the resulting executable to be covered by the GNU General Public License.
++ This exception does not however invalidate any other reasons why
++ the executable file might be covered by the GNU General Public License.
++
++
++This file just makes sure that the .fini and .init sections do in
++fact return. Users may put any desired instructions in those sections.
++This file is the last thing linked into any executable.
++*/
++ .file "crtn.asm"
++
++
++
++ .section ".init"
++ ldw ra, 44(sp)
++ ldw r23, 40(sp)
++ ldw r22, 36(sp)
++ ldw r21, 32(sp)
++ ldw r20, 28(sp)
++ ldw r19, 24(sp)
++ ldw r18, 20(sp)
++ ldw r17, 16(sp)
++ ldw r16, 12(sp)
++ ldw fp, 8(sp)
++ addi sp, sp, 48
++ ret
++
++ .section ".fini"
++ ldw ra, 44(sp)
++ ldw r23, 40(sp)
++ ldw r22, 36(sp)
++ ldw r21, 32(sp)
++ ldw r20, 28(sp)
++ ldw r19, 24(sp)
++ ldw r18, 20(sp)
++ ldw r17, 16(sp)
++ ldw r16, 12(sp)
++ ldw fp, 8(sp)
++ addi sp, sp, 48
++ ret
++
+Index: gcc-4.1.2/gcc/config/nios2/lib2-divmod-hi.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/lib2-divmod-hi.c 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,133 @@
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++#undef gid_t
++#undef pid_t
++#undef rlim_t
++#undef ssize_t
++#undef uid_t
++#undef vfork
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#ifndef MIN_UNITS_PER_WORD
++#define MIN_UNITS_PER_WORD UNITS_PER_WORD
++#endif
++
++#include "libgcc2.h"
++
++extern HItype __modhi3 (HItype, HItype);
++extern HItype __divhi3 (HItype, HItype);
++extern UHItype __umodhi3 (UHItype, UHItype);
++extern UHItype __udivhi3 (UHItype, UHItype);
++
++static UHItype udivmodhi4(UHItype, UHItype, word_type);
++
++static UHItype
++udivmodhi4(UHItype num, UHItype den, word_type modwanted)
++{
++ UHItype bit = 1;
++ UHItype res = 0;
++
++ while (den < num && bit && !(den & (1L<<15)))
++ {
++ den <<=1;
++ bit <<=1;
++ }
++ while (bit)
++ {
++ if (num >= den)
++ {
++ num -= den;
++ res |= bit;
++ }
++ bit >>=1;
++ den >>=1;
++ }
++ if (modwanted) return num;
++ return res;
++}
++
++
++HItype
++__divhi3 (HItype a, HItype b)
++{
++ word_type neg = 0;
++ HItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = !neg;
++ }
++
++ if (b < 0)
++ {
++ b = -b;
++ neg = !neg;
++ }
++
++ res = udivmodhi4 (a, b, 0);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++HItype
++__modhi3 (HItype a, HItype b)
++{
++ word_type neg = 0;
++ HItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = 1;
++ }
++
++ if (b < 0)
++ b = -b;
++
++ res = udivmodhi4 (a, b, 1);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++UHItype
++__udivhi3 (UHItype a, UHItype b)
++{
++ return udivmodhi4 (a, b, 0);
++}
++
++
++UHItype
++__umodhi3 (UHItype a, UHItype b)
++{
++ return udivmodhi4 (a, b, 1);
++}
++
+Index: gcc-4.1.2/gcc/config/nios2/lib2-divmod.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/lib2-divmod.c 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,136 @@
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++#undef gid_t
++#undef pid_t
++#undef rlim_t
++#undef ssize_t
++#undef uid_t
++#undef vfork
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#ifndef MIN_UNITS_PER_WORD
++#define MIN_UNITS_PER_WORD UNITS_PER_WORD
++#endif
++
++#include "libgcc2.h"
++
++extern SItype __modsi3 (SItype, SItype);
++extern SItype __divsi3 (SItype, SItype);
++extern SItype __umodsi3 (SItype, SItype);
++extern SItype __udivsi3 (SItype, SItype);
++
++static USItype udivmodsi4(USItype, USItype, word_type);
++
++/* 16-bit SI divide and modulo as used in NIOS */
++
++
++static USItype
++udivmodsi4(USItype num, USItype den, word_type modwanted)
++{
++ USItype bit = 1;
++ USItype res = 0;
++
++ while (den < num && bit && !(den & (1L<<31)))
++ {
++ den <<=1;
++ bit <<=1;
++ }
++ while (bit)
++ {
++ if (num >= den)
++ {
++ num -= den;
++ res |= bit;
++ }
++ bit >>=1;
++ den >>=1;
++ }
++ if (modwanted) return num;
++ return res;
++}
++
++
++SItype
++__divsi3 (SItype a, SItype b)
++{
++ word_type neg = 0;
++ SItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = !neg;
++ }
++
++ if (b < 0)
++ {
++ b = -b;
++ neg = !neg;
++ }
++
++ res = udivmodsi4 (a, b, 0);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++SItype
++__modsi3 (SItype a, SItype b)
++{
++ word_type neg = 0;
++ SItype res;
++
++ if (a < 0)
++ {
++ a = -a;
++ neg = 1;
++ }
++
++ if (b < 0)
++ b = -b;
++
++ res = udivmodsi4 (a, b, 1);
++
++ if (neg)
++ res = -res;
++
++ return res;
++}
++
++
++SItype
++__udivsi3 (SItype a, SItype b)
++{
++ return udivmodsi4 (a, b, 0);
++}
++
++
++SItype
++__umodsi3 (SItype a, SItype b)
++{
++ return udivmodsi4 (a, b, 1);
++}
++
+Index: gcc-4.1.2/gcc/config/nios2/lib2-divtable.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/lib2-divtable.c 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,52 @@
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++#undef gid_t
++#undef pid_t
++#undef rlim_t
++#undef ssize_t
++#undef uid_t
++#undef vfork
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#include "libgcc2.h"
++
++UQItype __divsi3_table[] =
++{
++ 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7, 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
++ 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
++ 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7, 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
++ 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7, 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
++ 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7, 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
++ 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7, 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
++ 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7, 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
++ 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7, 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
++ 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7, 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
++ 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7, 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
++ 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7, 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
++ 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
++ 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7, 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
++ 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7, 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
++ 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7, 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
++ 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7, 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
++};
++
+Index: gcc-4.1.2/gcc/config/nios2/lib2-mul.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/lib2-mul.c 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,113 @@
++/* while we are debugging (ie compile outside of gcc build)
++ disable gcc specific headers */
++#ifndef DEBUG_MULSI3
++
++
++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
++ supposedly valid even though this is a "target" file. */
++#include "auto-host.h"
++#undef gid_t
++#undef pid_t
++#undef rlim_t
++#undef ssize_t
++#undef uid_t
++#undef vfork
++
++
++#include "tconfig.h"
++#include "tsystem.h"
++#include "coretypes.h"
++#include "tm.h"
++
++
++/* Don't use `fancy_abort' here even if config.h says to use it. */
++#ifdef abort
++#undef abort
++#endif
++
++
++#ifdef HAVE_GAS_HIDDEN
++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
++#else
++#define ATTRIBUTE_HIDDEN
++#endif
++
++#ifndef MIN_UNITS_PER_WORD
++#define MIN_UNITS_PER_WORD UNITS_PER_WORD
++#endif
++
++#include "libgcc2.h"
++
++#else
++#define SItype int
++#define USItype unsigned int
++#endif
++
++
++extern SItype __mulsi3 (SItype, SItype);
++
++SItype
++__mulsi3 (SItype a, SItype b)
++{
++ SItype res = 0;
++ USItype cnt = a;
++
++ while (cnt)
++ {
++ if (cnt & 1)
++ {
++ res += b;
++ }
++ b <<= 1;
++ cnt >>= 1;
++ }
++
++ return res;
++}
++/*
++TODO: Choose best alternative implementation.
++
++SItype
++__divsi3 (SItype a, SItype b)
++{
++ SItype res = 0;
++ USItype cnt = 0;
++
++ while (cnt < 32)
++ {
++ if (a & (1L << cnt))
++ {
++ res += b;
++ }
++ b <<= 1;
++ cnt++;
++ }
++
++ return res;
++}
++*/
++
++
++#ifdef DEBUG_MULSI3
++
++int
++main ()
++{
++ int i, j;
++ int error = 0;
++
++ for (i = -1000; i < 1000; i++)
++ for (j = -1000; j < 1000; j++)
++ {
++ int expect = i * j;
++ int actual = A__divsi3 (i, j);
++ if (expect != actual)
++ {
++ printf ("error: %d * %d = %d not %d\n", i, j, expect, actual);
++ error = 1;
++ }
++ }
++
++ return error;
++}
++#endif
+Index: gcc-4.1.2/gcc/config/nios2/linux-atomic.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/linux-atomic.c 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,302 @@
++/* Linux-specific atomic operations for Nios II Linux.
++ Copyright (C) 2008 Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC 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.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file into combinations with other programs,
++and to distribute those combinations without any restriction coming
++from the use of this file. (The General Public License restrictions
++do apply in other respects; for example, they cover modification of
++the file, and distribution when not linked into a combine
++executable.)
++
++GCC 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. */
++
++#include <asm/unistd.h>
++#define EFAULT 14
++#define EBUSY 16
++#define ENOSYS 38
++
++/* We implement byte, short and int versions of each atomic operation
++ using the kernel helper defined below. There is no support for
++ 64-bit operations yet. */
++
++/* Crash a userspace program with SIGSEV. */
++#define ABORT_INSTRUCTION asm ("stw zero, 0(zero)")
++
++/* Kernel helper for compare-and-exchange a 32-bit value. */
++static inline long
++__kernel_cmpxchg (int oldval, int newval, int *mem)
++{
++ register int r2 asm ("r2") = __NR_nios2cmpxchg;
++ register unsigned long lws_mem asm("r4") = (unsigned long) (mem);
++ register int lws_old asm("r5") = oldval;
++ register int lws_new asm("r6") = newval;
++ register int err asm ("r7");
++ asm volatile ("trap"
++ : "=r" (r2), "=r" (err)
++ : "r" (r2), "r" (lws_mem), "r" (lws_old), "r" (lws_new)
++ : "r1", "r3", "r8", "r9", "r10", "r11", "r12", "r13", "r14",
++ "r15", "r29", "memory");
++
++ /* If the kernel LWS call succeeded (err == 0), r2 contains the old value
++ from memory. If this value is equal to OLDVAL, the new value was written
++ to memory. If not, return EBUSY. */
++ if (__builtin_expect (err, 0))
++ {
++ if(__builtin_expect (r2 == EFAULT || r2 == ENOSYS,0))
++ ABORT_INSTRUCTION;
++ }
++ else
++ {
++ if (__builtin_expect (r2 != oldval, 0))
++ r2 = EBUSY;
++ else
++ r2 = 0;
++ }
++
++ return r2;
++}
++
++#define HIDDEN __attribute__ ((visibility ("hidden")))
++
++/* Big endian masks */
++#define INVERT_MASK_1 24
++#define INVERT_MASK_2 16
++
++#define MASK_1 0xffu
++#define MASK_2 0xffffu
++
++#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \
++ int HIDDEN \
++ __sync_fetch_and_##OP##_4 (int *ptr, int val) \
++ { \
++ int failure, tmp; \
++ \
++ do { \
++ tmp = *ptr; \
++ failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \
++ } while (failure != 0); \
++ \
++ return tmp; \
++ }
++
++FETCH_AND_OP_WORD (add, , +)
++FETCH_AND_OP_WORD (sub, , -)
++FETCH_AND_OP_WORD (or, , |)
++FETCH_AND_OP_WORD (and, , &)
++FETCH_AND_OP_WORD (xor, , ^)
++FETCH_AND_OP_WORD (nand, ~, &)
++
++#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH
++#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH
++
++/* Implement both __sync_<op>_and_fetch and __sync_fetch_and_<op> for
++ subword-sized quantities. */
++
++#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \
++ TYPE HIDDEN \
++ NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \
++ { \
++ int *wordptr = (int *) ((unsigned long) ptr & ~3); \
++ unsigned int mask, shift, oldval, newval; \
++ int failure; \
++ \
++ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
++ mask = MASK_##WIDTH << shift; \
++ \
++ do { \
++ oldval = *wordptr; \
++ newval = ((PFX_OP ((oldval & mask) >> shift) \
++ INF_OP (unsigned int) val) << shift) & mask; \
++ newval |= oldval & ~mask; \
++ failure = __kernel_cmpxchg (oldval, newval, wordptr); \
++ } while (failure != 0); \
++ \
++ return (RETURN & mask) >> shift; \
++ }
++
++SUBWORD_SYNC_OP (add, , +, short, 2, oldval)
++SUBWORD_SYNC_OP (sub, , -, short, 2, oldval)
++SUBWORD_SYNC_OP (or, , |, short, 2, oldval)
++SUBWORD_SYNC_OP (and, , &, short, 2, oldval)
++SUBWORD_SYNC_OP (xor, , ^, short, 2, oldval)
++SUBWORD_SYNC_OP (nand, ~, &, short, 2, oldval)
++
++SUBWORD_SYNC_OP (add, , +, char, 1, oldval)
++SUBWORD_SYNC_OP (sub, , -, char, 1, oldval)
++SUBWORD_SYNC_OP (or, , |, char, 1, oldval)
++SUBWORD_SYNC_OP (and, , &, char, 1, oldval)
++SUBWORD_SYNC_OP (xor, , ^, char, 1, oldval)
++SUBWORD_SYNC_OP (nand, ~, &, char, 1, oldval)
++
++#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \
++ int HIDDEN \
++ __sync_##OP##_and_fetch_4 (int *ptr, int val) \
++ { \
++ int tmp, failure; \
++ \
++ do { \
++ tmp = *ptr; \
++ failure = __kernel_cmpxchg (tmp, PFX_OP tmp INF_OP val, ptr); \
++ } while (failure != 0); \
++ \
++ return PFX_OP tmp INF_OP val; \
++ }
++
++OP_AND_FETCH_WORD (add, , +)
++OP_AND_FETCH_WORD (sub, , -)
++OP_AND_FETCH_WORD (or, , |)
++OP_AND_FETCH_WORD (and, , &)
++OP_AND_FETCH_WORD (xor, , ^)
++OP_AND_FETCH_WORD (nand, ~, &)
++
++SUBWORD_SYNC_OP (add, , +, short, 2, newval)
++SUBWORD_SYNC_OP (sub, , -, short, 2, newval)
++SUBWORD_SYNC_OP (or, , |, short, 2, newval)
++SUBWORD_SYNC_OP (and, , &, short, 2, newval)
++SUBWORD_SYNC_OP (xor, , ^, short, 2, newval)
++SUBWORD_SYNC_OP (nand, ~, &, short, 2, newval)
++
++SUBWORD_SYNC_OP (add, , +, char, 1, newval)
++SUBWORD_SYNC_OP (sub, , -, char, 1, newval)
++SUBWORD_SYNC_OP (or, , |, char, 1, newval)
++SUBWORD_SYNC_OP (and, , &, char, 1, newval)
++SUBWORD_SYNC_OP (xor, , ^, char, 1, newval)
++SUBWORD_SYNC_OP (nand, ~, &, char, 1, newval)
++
++int HIDDEN
++__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
++{
++ int actual_oldval, fail;
++
++ while (1)
++ {
++ actual_oldval = *ptr;
++
++ if (oldval != actual_oldval)
++ return actual_oldval;
++
++ fail = __kernel_cmpxchg (actual_oldval, newval, ptr);
++
++ if (!fail)
++ return oldval;
++ }
++}
++
++#define SUBWORD_VAL_CAS(TYPE, WIDTH) \
++ TYPE HIDDEN \
++ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
++ TYPE newval) \
++ { \
++ int *wordptr = (int *)((unsigned long) ptr & ~3), fail; \
++ unsigned int mask, shift, actual_oldval, actual_newval; \
++ \
++ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
++ mask = MASK_##WIDTH << shift; \
++ \
++ while (1) \
++ { \
++ actual_oldval = *wordptr; \
++ \
++ if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \
++ return (actual_oldval & mask) >> shift; \
++ \
++ actual_newval = (actual_oldval & ~mask) \
++ | (((unsigned int) newval << shift) & mask); \
++ \
++ fail = __kernel_cmpxchg (actual_oldval, actual_newval, \
++ wordptr); \
++ \
++ if (!fail) \
++ return oldval; \
++ } \
++ }
++
++SUBWORD_VAL_CAS (short, 2)
++SUBWORD_VAL_CAS (char, 1)
++
++typedef unsigned char bool;
++
++bool HIDDEN
++__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
++{
++ int failure = __kernel_cmpxchg (oldval, newval, ptr);
++ return (failure == 0);
++}
++
++#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \
++ bool HIDDEN \
++ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
++ TYPE newval) \
++ { \
++ TYPE actual_oldval \
++ = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \
++ return (oldval == actual_oldval); \
++ }
++
++SUBWORD_BOOL_CAS (short, 2)
++SUBWORD_BOOL_CAS (char, 1)
++
++int HIDDEN
++__sync_lock_test_and_set_4 (int *ptr, int val)
++{
++ int failure, oldval;
++
++ do {
++ oldval = *ptr;
++ failure = __kernel_cmpxchg (oldval, val, ptr);
++ } while (failure != 0);
++
++ return oldval;
++}
++
++#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \
++ TYPE HIDDEN \
++ __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \
++ { \
++ int failure; \
++ unsigned int oldval, newval, shift, mask; \
++ int *wordptr = (int *) ((unsigned long) ptr & ~3); \
++ \
++ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \
++ mask = MASK_##WIDTH << shift; \
++ \
++ do { \
++ oldval = *wordptr; \
++ newval = (oldval & ~mask) \
++ | (((unsigned int) val << shift) & mask); \
++ failure = __kernel_cmpxchg (oldval, newval, wordptr); \
++ } while (failure != 0); \
++ \
++ return (oldval & mask) >> shift; \
++ }
++
++SUBWORD_TEST_AND_SET (short, 2)
++SUBWORD_TEST_AND_SET (char, 1)
++
++#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \
++ void HIDDEN \
++ __sync_lock_release_##WIDTH (TYPE *ptr) \
++ { \
++ *ptr = 0; \
++ }
++
++SYNC_LOCK_RELEASE (int, 4)
++SYNC_LOCK_RELEASE (short, 2)
++SYNC_LOCK_RELEASE (char, 1)
+Index: gcc-4.1.2/gcc/config/nios2/linux-unwind.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/config/nios2/linux-unwind.h 2010-06-30 08:50:26.000000000 +0200
+@@ -0,0 +1,166 @@
++/* DWARF2 EH unwinding support for NIOS2 Linux.
++ Copyright (C) 2008 Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC 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.
++
++In addition to the permissions in the GNU General Public License, the
++Free Software Foundation gives you unlimited permission to link the
++compiled version of this file with other programs, and to distribute
++those programs without any restriction coming from the use of this
++file. (The General Public License restrictions do apply in other
++respects; for example, they cover modification of the file, and
++distribution when not linked into another program.)
++
++GCC 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. */
++
++#ifndef inhibit_libc
++
++/* Do code reading to identify a signal frame, and set the frame
++ state data appropriately. See unwind-dw2.c for the structs. */
++
++#include <signal.h>
++#include <asm/unistd.h>
++
++/* Unfortunately the kernel headers define the wrong shape of the
++ register file, so we define our own version here. This problem has
++ been reported. */
++
++struct nios2_mcontext
++{
++ int version; /* 2 */
++ unsigned seq_regs[23]; /* regs 1..23 */
++ unsigned ra; /* Return address, r31 */
++ unsigned fp; /* Frame pointer, r28 */
++ unsigned gp; /* Global pointer, r26 */
++ unsigned pad1;
++ unsigned ea; /* Exception return address (pc) */
++ unsigned sp; /* Stack pointer, r27 */
++ unsigned pad2;
++ /* Note r24, r25, r29, r30 are reserved registers */
++};
++
++/* The kernel's definition of this structure also doesn't match
++ reality. Again, this has been reported. */
++
++struct nios2_ucontext {
++ unsigned long uc_flags;
++ unsigned pad1;
++ void *uc_link;
++ stack_t uc_stack;
++ struct siginfo info;
++ struct nios2_mcontext uc_mcontext;
++};
++
++#define MD_FALLBACK_FRAME_STATE_FOR nios2_fallback_frame_state
++
++static _Unwind_Reason_Code
++nios2_fallback_frame_state (struct _Unwind_Context *context,
++ _Unwind_FrameState *fs)
++{
++ u_int32_t *pc = (u_int32_t *) context->ra;
++ _Unwind_Ptr new_cfa;
++ int i;
++
++ /* movi r2,(sigreturn/rt_sigreturn)
++ trap */
++ if (pc[1] != 0x003b683a) /* trap */
++ return _URC_END_OF_STACK;
++
++#define NIOS2_REG(NUM,NAME) \
++ (fs->regs.reg[NUM].how = REG_SAVED_OFFSET, \
++ fs->regs.reg[NUM].loc.offset = (_Unwind_Ptr)&regs->NAME - new_cfa)
++
++ if (pc[0] == (0x00800004 | (__NR_sigreturn << 6)))
++ {
++ struct sigframe {
++ u_int32_t trampoline[2];
++ u_int32_t pad1;
++ u_int32_t pad2;
++ struct sigcontext ctx;
++ } *rt_ = context->ra;
++ struct pt_regs *regs = &rt_->ctx.regs;
++
++ /* The CFA is the user's incoming stack pointer value. */
++ new_cfa = (_Unwind_Ptr)regs->sp;
++ fs->cfa_how = CFA_REG_OFFSET;
++ fs->cfa_reg = STACK_POINTER_REGNUM;
++ fs->cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
++
++ /* Regs 1..15 */
++ NIOS2_REG (1, r1);
++ NIOS2_REG (2, r2);
++ NIOS2_REG (3, r3);
++ NIOS2_REG (4, r4);
++ NIOS2_REG (5, r5);
++ NIOS2_REG (6, r6);
++ NIOS2_REG (7, r7);
++ NIOS2_REG (8, r8);
++ NIOS2_REG (9, r9);
++ NIOS2_REG (10, r10);
++ NIOS2_REG (11, r11);
++ NIOS2_REG (12, r12);
++ NIOS2_REG (13, r13);
++ NIOS2_REG (14, r14);
++ NIOS2_REG (15, r15);
++
++ /* Regs 16..23 are not saved here. They are callee saved or
++ special. */
++
++ /* The random registers. */
++ NIOS2_REG (RA_REGNO, ra);
++ NIOS2_REG (FP_REGNO, fp);
++ NIOS2_REG (GP_REGNO, gp);
++ NIOS2_REG (SIGNAL_UNWIND_RETURN_COLUMN, ea);
++
++ fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;
++
++ return _URC_NO_REASON;
++ }
++ else if (pc[0] == (0x00800004 | (__NR_rt_sigreturn << 6)))
++ {
++ struct sigframe {
++ u_int32_t trampoline[2];
++ struct nios2_ucontext sigctx;
++ } *rt_ = context->ra;
++ struct nios2_mcontext *regs = &rt_->sigctx.uc_mcontext;
++
++ if (regs->version != 2)
++ return _URC_END_OF_STACK;
++
++ /* The CFA is the user's incoming stack pointer value. */
++ new_cfa = (_