aboutsummaryrefslogtreecommitdiff
path: root/libgcc/config/nios2
diff options
context:
space:
mode:
authorChung-Lin Tang <cltang@gcc.gnu.org>2013-12-31 07:05:35 +0000
committerChung-Lin Tang <cltang@gcc.gnu.org>2013-12-31 07:05:35 +0000
commite430824f28d68edd908a72677ba1b08a92e3e2ad (patch)
tree823787d209349f276f7125e117fa50abcb07c205 /libgcc/config/nios2
parentfd5b8c6572058c3153a610923b01d1a3f37a1f64 (diff)
downloadgcc-e430824f28d68edd908a72677ba1b08a92e3e2ad.zip
gcc-e430824f28d68edd908a72677ba1b08a92e3e2ad.tar.gz
gcc-e430824f28d68edd908a72677ba1b08a92e3e2ad.tar.bz2
Commit of nios2 port to trunk:
contrib/ 2013-12-31 Chung-Lin Tang <cltang@codesourcery.com> * config-list.mk: Add nios2-elf, nios2-linux-gnu. Corrected ordering of some configs. gcc/ 2013-12-31 Chung-Lin Tang <cltang@codesourcery.com> Sandra Loosemore <sandra@codesourcery.com> Based on patches from Altera Corporation * config.gcc (nios2-*-*): Add nios2 config targets. * configure.ac (TLS_SECTION_ASM_FLAG): Add nios2 case. ("$cpu_type"): Add nios2 as new cpu type. * configure: Regenerate. * config/nios2/nios2.c: New file. * config/nios2/nios2.h: New file. * config/nios2/nios2-opts.h: New file. * config/nios2/nios2-protos.h: New file. * config/nios2/elf.h: New file. * config/nios2/elf.opt: New file. * config/nios2/linux.h: New file. * config/nios2/nios2.opt: New file. * config/nios2/nios2.md: New file. * config/nios2/predicates.md: New file. * config/nios2/constraints.md: New file. * config/nios2/t-nios2: New file. * common/config/nios2/nios2-common.c: New file. * doc/invoke.texi (Nios II options): Document Nios II specific options. * doc/md.texi (Nios II family): Document Nios II specific constraints. * doc/extend.texi (Function Specific Option Pragmas): Document Nios II supported target pragma functionality. gcc/testsuite/ 2013-12-31 Sandra Loosemore <sandra@codesourcery.com> Chung-Lin Tang <cltang@codesourcery.com> Based on patches from Altera Corporation * gcc.dg/stack-usage-1.c (SIZE): Define case for __nios2__. * gcc.dg/20040813-1.c: Skip for nios2-*-*. * gcc.dg/20020312-2.c: Add __nios2__ case. * g++.dg/other/PR23205.C: Skip for nios2-*-*. * g++.dg/other/pr23205-2.C: Skip for nios2-*-*. * g++.dg/cpp0x/constexpr-rom.C: Skip for nios2-*-*. * g++.dg/cpp0x/alias-decl-debug-0.C: Skip for nios2-*-*. * g++.old-deja/g++.jason/thunk3.C: Skip for nios2-*-*. * lib/target-supports.exp (check_profiling_available): Check for nios2-*-elf. * gcc.c-torture/execute/pr47237.x:: Skip for nios2-*-*. * gcc.c-torture/execute/20101011-1.c: Skip for nios2-*-*. * gcc.c-torture/execute/builtins/lib/chk.c (memset): Place char-based memset loop before inline check, to prevent problems when called to initialize .bss. Update comments. * gcc.target/nios2/nios2.exp: New DejaGNU file. * gcc.target/nios2/nios2-custom-1.c: New test. * gcc.target/nios2/nios2-trap-insn.c: New test. * gcc.target/nios2/nios2-builtin-custom.c: New test. * gcc.target/nios2/nios2-builtin-io.c: New test. * gcc.target/nios2/nios2-stack-check-1.c: New test. * gcc.target/nios2/nios2-stack-check-2.c: New test. * gcc.target/nios2/nios2-rdctl.c: New test. * gcc.target/nios2/nios2-wrctl.c: New test. * gcc.target/nios2/nios2-wrctl-zero.c: New test. * gcc.target/nios2/nios2-wrctl-not-zero.c: New test. * gcc.target/nios2/nios2-rdwrctl-1.c: New test. * gcc.target/nios2/nios2-reg-constraints.c: New test. * gcc.target/nios2/nios2-ashlsi3-one_shift.c: New test. * gcc.target/nios2/nios2-mul-options-1.c: New test. * gcc.target/nios2/nios2-mul-options-2.c: New test. * gcc.target/nios2/nios2-mul-options-3.c: New test. * gcc.target/nios2/nios2-mul-options-4.c: New test. * gcc.target/nios2/nios2-nor.c: New test. * gcc.target/nios2/nios2-stxio.c: New test. * gcc.target/nios2/custom-fp-1.c: New test. * gcc.target/nios2/custom-fp-2.c: New test. * gcc.target/nios2/custom-fp-3.c: New test. * gcc.target/nios2/custom-fp-4.c: New test. * gcc.target/nios2/custom-fp-5.c: New test. * gcc.target/nios2/custom-fp-6.c: New test. * gcc.target/nios2/custom-fp-7.c: New test. * gcc.target/nios2/custom-fp-8.c: New test. * gcc.target/nios2/custom-fp-cmp-1.c: New test. * gcc.target/nios2/custom-fp-conversion.c: New test. * gcc.target/nios2/custom-fp-double.c: New test. * gcc.target/nios2/custom-fp-float.c: New test. * gcc.target/nios2/nios2-int-types.c: New test. * gcc.target/nios2/nios2-cache-1.c: New test. * gcc.target/nios2/nios2-cache-2.c: New test. libgcc/ 2013-12-31 Sandra Loosemore <sandra@codesourcery.com> Chung-Lin Tang <cltang@codesourcery.com> Based on patches from Altera Corporation * config.host (nios2-*-*,nios2-*-linux*): Add nios2 host cases. * config/nios2/lib2-nios2.h: New file. * config/nios2/lib2-divmod-hi.c: New file. * config/nios2/linux-unwind.h: New file. * config/nios2/lib2-divmod.c: New file. * config/nios2/linux-atomic.c: New file. * config/nios2/t-nios2: New file. * config/nios2/crti.asm: New file. * config/nios2/t-linux: New file. * config/nios2/lib2-divtable.c: New file. * config/nios2/lib2-mul.c: New file. * config/nios2/tramp.c: New file. * config/nios2/crtn.asm: New file. From-SVN: r206256
Diffstat (limited to 'libgcc/config/nios2')
-rw-r--r--libgcc/config/nios2/crti.S87
-rw-r--r--libgcc/config/nios2/crtn.S60
-rw-r--r--libgcc/config/nios2/lib2-divmod-hi.c117
-rw-r--r--libgcc/config/nios2/lib2-divmod.c117
-rw-r--r--libgcc/config/nios2/lib2-divtable.c60
-rw-r--r--libgcc/config/nios2/lib2-mul.c42
-rw-r--r--libgcc/config/nios2/lib2-nios2.h49
-rw-r--r--libgcc/config/nios2/linux-atomic.c286
-rw-r--r--libgcc/config/nios2/linux-unwind.h106
-rw-r--r--libgcc/config/nios2/sfp-machine.h78
-rw-r--r--libgcc/config/nios2/t-linux7
-rw-r--r--libgcc/config/nios2/t-nios25
-rw-r--r--libgcc/config/nios2/tramp.c61
13 files changed, 1075 insertions, 0 deletions
diff --git a/libgcc/config/nios2/crti.S b/libgcc/config/nios2/crti.S
new file mode 100644
index 0000000..23481b6
--- /dev/null
+++ b/libgcc/config/nios2/crti.S
@@ -0,0 +1,87 @@
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Jonah Graham (jgraham@altera.com).
+ Contributed by Mentor Graphics, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+
+/* 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
+#ifdef linux
+ nextpc r22
+1: movhi r2, %hiadj(_GLOBAL_OFFSET_TABLE_ - 1b)
+ addi r2, r2, %lo(_GLOBAL_OFFSET_TABLE_ - 1b)
+ add r22, r22, r2
+#endif
+
+
+ .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
+#ifdef linux
+ nextpc r22
+1: movhi r2, %hiadj(_GLOBAL_OFFSET_TABLE_ - 1b)
+ addi r2, r2, %lo(_GLOBAL_OFFSET_TABLE_ - 1b)
+ add r22, r22, r2
+#endif
+
diff --git a/libgcc/config/nios2/crtn.S b/libgcc/config/nios2/crtn.S
new file mode 100644
index 0000000..722c1c7
--- /dev/null
+++ b/libgcc/config/nios2/crtn.S
@@ -0,0 +1,60 @@
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Jonah Graham (jgraham@altera.com).
+ Contributed by Mentor Graphics, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+
+/* 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
+
diff --git a/libgcc/config/nios2/lib2-divmod-hi.c b/libgcc/config/nios2/lib2-divmod-hi.c
new file mode 100644
index 0000000..2745991
--- /dev/null
+++ b/libgcc/config/nios2/lib2-divmod-hi.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Altera and Mentor Graphics, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "lib2-nios2.h"
+
+/* 16-bit HI divide and modulo as used in Nios II. */
+
+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);
+}
+
diff --git a/libgcc/config/nios2/lib2-divmod.c b/libgcc/config/nios2/lib2-divmod.c
new file mode 100644
index 0000000..e5f9697
--- /dev/null
+++ b/libgcc/config/nios2/lib2-divmod.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Altera and Mentor Graphics, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "lib2-nios2.h"
+
+/* 32-bit SI divide and modulo as used in Nios II. */
+
+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);
+}
+
diff --git a/libgcc/config/nios2/lib2-divtable.c b/libgcc/config/nios2/lib2-divtable.c
new file mode 100644
index 0000000..4f6a230
--- /dev/null
+++ b/libgcc/config/nios2/lib2-divtable.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Altera and Mentor Graphics, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "lib2-nios2.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,
+};
+
diff --git a/libgcc/config/nios2/lib2-mul.c b/libgcc/config/nios2/lib2-mul.c
new file mode 100644
index 0000000..4c247fe
--- /dev/null
+++ b/libgcc/config/nios2/lib2-mul.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Altera and Mentor Graphics, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "lib2-nios2.h"
+
+/* 32-bit SI multiply for Nios II. */
+
+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;
+}
diff --git a/libgcc/config/nios2/lib2-nios2.h b/libgcc/config/nios2/lib2-nios2.h
new file mode 100644
index 0000000..a581aa5
--- /dev/null
+++ b/libgcc/config/nios2/lib2-nios2.h
@@ -0,0 +1,49 @@
+/* Integer arithmetic support for Altera Nios II.
+
+ Copyright (C) 2012-2013 Free Software Foundation, Inc.
+ Contributed by Altera and Mentor Graphics, Inc.
+
+ 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 3, 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef LIB2_NIOS2_H
+#define LIB2_NIOS2_H
+
+/* Types. */
+
+typedef char QItype __attribute__ ((mode (QI)));
+typedef unsigned char UQItype __attribute__ ((mode (QI)));
+typedef short HItype __attribute__ ((mode (HI)));
+typedef unsigned short UHItype __attribute__ ((mode (HI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+/* Exported functions. */
+extern SItype __divsi3 (SItype, SItype);
+extern SItype __modsi3 (SItype, SItype);
+extern SItype __udivsi3 (SItype, SItype);
+extern SItype __umodsi3 (SItype, SItype);
+extern HItype __divhi3 (HItype, HItype);
+extern HItype __modhi3 (HItype, HItype);
+extern UHItype __udivhi3 (UHItype, UHItype);
+extern UHItype __umodhi3 (UHItype, UHItype);
+extern SItype __mulsi3 (SItype, SItype);
+
+#endif /* LIB2_NIOS2_H */
diff --git a/libgcc/config/nios2/linux-atomic.c b/libgcc/config/nios2/linux-atomic.c
new file mode 100644
index 0000000..1fc91dd
--- /dev/null
+++ b/libgcc/config/nios2/linux-atomic.c
@@ -0,0 +1,286 @@
+/* Linux-specific atomic operations for Nios II Linux.
+ Copyright (C) 2008-2013 Free Software Foundation, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#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");
+ register int *r4 asm ("r4") = mem;
+ register int r5 asm ("r5") = oldval;
+ register int r6 asm ("r6") = newval;
+
+ /* Call the kernel provided fixed address cmpxchg helper routine. */
+ asm volatile ("movi %0, %4\n\t"
+ "callr %0\n"
+ : "=r" (r2)
+ : "r" (r4), "r" (r5), "r" (r6), "I" (0x00001004)
+ : "ra", "memory");
+ return r2;
+}
+
+#define HIDDEN __attribute__ ((visibility ("hidden")))
+
+#ifdef __nios2_little_endian__
+#define INVERT_MASK_1 0
+#define INVERT_MASK_2 0
+#else
+#define INVERT_MASK_1 24
+#define INVERT_MASK_2 16
+#endif
+
+#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, , +, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned 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, , +, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval)
+
+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval)
+SUBWORD_SYNC_OP (nand, ~, &, unsigned 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 (unsigned short, 2)
+SUBWORD_VAL_CAS (unsigned 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 (unsigned short, 2)
+SUBWORD_BOOL_CAS (unsigned 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 (unsigned short, 2)
+SUBWORD_TEST_AND_SET (unsigned char, 1)
+
+#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \
+ void HIDDEN \
+ __sync_lock_release_##WIDTH (TYPE *ptr) \
+ { \
+ /* All writes before this point must be seen before we release \
+ the lock itself. */ \
+ __builtin_sync (); \
+ *ptr = 0; \
+ }
+
+SYNC_LOCK_RELEASE (int, 4)
+SYNC_LOCK_RELEASE (short, 2)
+SYNC_LOCK_RELEASE (char, 1)
diff --git a/libgcc/config/nios2/linux-unwind.h b/libgcc/config/nios2/linux-unwind.h
new file mode 100644
index 0000000..e71f527
--- /dev/null
+++ b/libgcc/config/nios2/linux-unwind.h
@@ -0,0 +1,106 @@
+/* DWARF2 EH unwinding support for Nios II Linux.
+ Copyright (C) 2008-2013 Free Software Foundation, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#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.
+ The corresponding bits in the Linux kernel are in
+ arch/nios2/kernel/signal.c. */
+
+#include <signal.h>
+#include <asm/unistd.h>
+
+/* Exactly the same layout as the kernel structures, unique names. */
+struct nios2_mcontext {
+ int version;
+ int gregs[32];
+};
+
+struct nios2_ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct nios2_mcontext uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+#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;
+
+ /* The expected sequence of instructions is:
+ movi r2,(rt_sigreturn)
+ trap
+ Check for the trap first. */
+ if (pc[1] != 0x003b683a)
+ 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_rt_sigreturn << 6)))
+ {
+ struct rt_sigframe {
+ char retcode[12];
+ siginfo_t info;
+ struct nios2_ucontext uc;
+ } *rt_ = context->ra;
+ struct nios2_mcontext *regs = &rt_->uc.uc_mcontext;
+ int i;
+
+ /* MCONTEXT_VERSION is defined to 2 in the kernel. */
+ if (regs->version != 2)
+ return _URC_END_OF_STACK;
+
+ /* The CFA is the user's incoming stack pointer value. */
+ new_cfa = (_Unwind_Ptr)regs->gregs[28];
+ fs->regs.cfa_how = CFA_REG_OFFSET;
+ fs->regs.cfa_reg = STACK_POINTER_REGNUM;
+ fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
+
+ /* The sequential registers. */
+ for (i = 1; i < 24; i++)
+ NIOS2_REG (i, gregs[i-1]);
+
+ /* The random registers. The kernel stores these in a funny order
+ in the gregs array. */
+ NIOS2_REG (RA_REGNO, gregs[23]);
+ NIOS2_REG (FP_REGNO, gregs[24]);
+ NIOS2_REG (GP_REGNO, gregs[25]);
+ NIOS2_REG (EA_REGNO, gregs[27]);
+
+ fs->retaddr_column = EA_REGNO;
+ fs->signal_frame = 1;
+
+ return _URC_NO_REASON;
+ }
+#undef NIOS2_REG
+ return _URC_END_OF_STACK;
+}
+#endif
diff --git a/libgcc/config/nios2/sfp-machine.h b/libgcc/config/nios2/sfp-machine.h
new file mode 100644
index 0000000..f318567
--- /dev/null
+++ b/libgcc/config/nios2/sfp-machine.h
@@ -0,0 +1,78 @@
+/* Soft-FP definitions for Altera Nios II.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#define _FP_W_TYPE_SIZE 32
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+#define _FP_QNANNEGATEDP 0
+
+/* Someone please check this. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ else \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+#ifdef __nios2_little_endian__
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#else
+#define __BYTE_ORDER __BIG_ENDIAN
+#endif
+
+/* Define ALIASNAME as a strong alias for NAME. */
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
diff --git a/libgcc/config/nios2/t-linux b/libgcc/config/nios2/t-linux
new file mode 100644
index 0000000..1fa581e
--- /dev/null
+++ b/libgcc/config/nios2/t-linux
@@ -0,0 +1,7 @@
+# Soft-float functions go in glibc only, to facilitate the possible
+# future addition of exception and rounding mode support integrated
+# with <fenv.h>.
+
+LIB2FUNCS_EXCLUDE = _floatdidf _floatdisf _fixunsdfsi _fixunssfsi \
+ _fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi _floatundidf _floatundisf
+LIB2ADD += $(srcdir)/config/nios2/linux-atomic.c
diff --git a/libgcc/config/nios2/t-nios2 b/libgcc/config/nios2/t-nios2
new file mode 100644
index 0000000..320dedf
--- /dev/null
+++ b/libgcc/config/nios2/t-nios2
@@ -0,0 +1,5 @@
+LIB2ADD += $(srcdir)/config/nios2/lib2-divmod.c \
+ $(srcdir)/config/nios2/lib2-divmod-hi.c \
+ $(srcdir)/config/nios2/lib2-divtable.c \
+ $(srcdir)/config/nios2/lib2-mul.c \
+ $(srcdir)/config/nios2/tramp.c
diff --git a/libgcc/config/nios2/tramp.c b/libgcc/config/nios2/tramp.c
new file mode 100644
index 0000000..3d9d249
--- /dev/null
+++ b/libgcc/config/nios2/tramp.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Altera and Mentor Graphics, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Set up trampolines.
+ R12 is the static chain register.
+ R2 is AT, the assembler temporary.
+ The trampoline code looks like:
+ movhi r12,%hi(chain)
+ ori r12,%lo(chain)
+ movhi r2,%hi(fn)
+ ori r2,%lo(fn)
+ jmp r2
+*/
+
+#define SC_REGNO 12
+
+#define MOVHI(reg,imm16) \
+ (((reg) << 22) | ((imm16) << 6) | 0x34)
+#define ORI(reg,imm16) \
+ (((reg) << 27) | ((reg) << 22) | ((imm16) << 6) | 0x14)
+#define JMP(reg) \
+ (((reg) << 27) | (0x0d << 11) | 0x3a)
+
+void
+__trampoline_setup (unsigned int *addr, void *fnptr, void *chainptr)
+{
+ unsigned int fn = (unsigned int) fnptr;
+ unsigned int chain = (unsigned int) chainptr;
+ int i;
+
+ addr[0] = MOVHI (SC_REGNO, ((chain >> 16) & 0xffff));
+ addr[1] = ORI (SC_REGNO, (chain & 0xffff));
+ addr[2] = MOVHI (2, ((fn >> 16) & 0xffff));
+ addr[3] = ORI (2, (fn & 0xffff));
+ addr[4] = JMP (2);
+
+ /* Flush the caches.
+ See Example 9-4 in the Nios II Software Developer's Handbook. */
+ for (i = 0; i < 5; i++)
+ asm volatile ("flushd 0(%0); flushi %0" :: "r"(addr + i) : "memory");
+ asm volatile ("flushp" ::: "memory");
+}