diff options
author | cltang <cltang@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-31 07:05:35 +0000 |
---|---|---|
committer | cltang <cltang@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-31 07:05:35 +0000 |
commit | de65406d2e2c1bca110b9193527c0870d9882b86 (patch) | |
tree | 823787d209349f276f7125e117fa50abcb07c205 /libgcc | |
parent | 67b0eaca86935ccfefb5482499e00033fdf08203 (diff) | |
download | gcc-de65406d2e2c1bca110b9193527c0870d9882b86.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206256 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 18 | ||||
-rw-r--r-- | libgcc/config.host | 12 | ||||
-rw-r--r-- | libgcc/config/nios2/crti.S | 87 | ||||
-rw-r--r-- | libgcc/config/nios2/crtn.S | 60 | ||||
-rw-r--r-- | libgcc/config/nios2/lib2-divmod-hi.c | 117 | ||||
-rw-r--r-- | libgcc/config/nios2/lib2-divmod.c | 117 | ||||
-rw-r--r-- | libgcc/config/nios2/lib2-divtable.c | 60 | ||||
-rw-r--r-- | libgcc/config/nios2/lib2-mul.c | 42 | ||||
-rw-r--r-- | libgcc/config/nios2/lib2-nios2.h | 49 | ||||
-rw-r--r-- | libgcc/config/nios2/linux-atomic.c | 286 | ||||
-rw-r--r-- | libgcc/config/nios2/linux-unwind.h | 106 | ||||
-rw-r--r-- | libgcc/config/nios2/sfp-machine.h | 78 | ||||
-rw-r--r-- | libgcc/config/nios2/t-linux | 7 | ||||
-rw-r--r-- | libgcc/config/nios2/t-nios2 | 5 | ||||
-rw-r--r-- | libgcc/config/nios2/tramp.c | 61 |
15 files changed, 1105 insertions, 0 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 1488dec5f90..1b015f2bc78 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,21 @@ +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. + 2013-12-26 Uros Bizjak <ubizjak@gmail.com> * config/i386/cpuinfo.c (enum vendor_signatures): Remove. diff --git a/libgcc/config.host b/libgcc/config.host index 75a17e34fd9..6aa986e4e46 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -146,6 +146,9 @@ mips*-*-*) nds32*-*) cpu_type=nds32 ;; +nios2*-*-*) + cpu_type=nios2 + ;; powerpc*-*-*) cpu_type=rs6000 ;; @@ -880,6 +883,15 @@ nds32*-elf*) ;; esac ;; +nios2-*-linux*) + tmake_file="$tmake_file nios2/t-nios2 nios2/t-linux t-libgcc-pic t-slibgcc-libgcc" + extra_parts="$extra_parts crti.o crtn.o" + md_unwind_header=nios2/linux-unwind.h + ;; +nios2-*-*) + tmake_file="$tmake_file nios2/t-nios2 t-softfp-sfdf t-softfp-excl t-softfp" + extra_parts="$extra_parts crti.o crtn.o" + ;; pdp11-*-*) tmake_file="pdp11/t-pdp11 t-fdpbit" ;; diff --git a/libgcc/config/nios2/crti.S b/libgcc/config/nios2/crti.S new file mode 100644 index 00000000000..23481b68833 --- /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 00000000000..722c1c7108c --- /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 00000000000..27459915bf1 --- /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 00000000000..e5f9697808d --- /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 00000000000..4f6a230a92b --- /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 00000000000..4c247fe0d0d --- /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 00000000000..a581aa5de67 --- /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 00000000000..1fc91dd82b1 --- /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 00000000000..e71f52769fc --- /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 00000000000..f3185678353 --- /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 00000000000..1fa581e28d8 --- /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 00000000000..320dedfe826 --- /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 00000000000..3d9d2496e79 --- /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"); +} |