or1k: libgcc: initial support for openrisc

libgcc/ChangeLog:

2018-11-09  Stafford Horne  <shorne@gmail.com>
	    Richard Henderson  <rth@twiddle.net>

	* config.host: Add OpenRISC support.
	* config/or1k/*: New.


Co-Authored-By: Richard Henderson <rth@twiddle.net>

From-SVN: r265961
This commit is contained in:
Stafford Horne 2018-11-09 12:09:15 +00:00 committed by Stafford Horne
parent 69104d52dd
commit d929e137f8
6 changed files with 403 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2018-11-09 Stafford Horne <shorne@gmail.com>
Richard Henderson <rth@twiddle.net>
* config.host: Add OpenRISC support.
* config/or1k/*: New.
2018-11-08 Kito Cheng <kito@andestech.com>
* soft-fp/adddf3.c: Update from glibc.

View File

@ -165,6 +165,9 @@ nds32*-*)
nios2*-*-*)
cpu_type=nios2
;;
or1k*-*-*)
cpu_type=or1k
;;
powerpc*-*-*)
cpu_type=rs6000
;;
@ -1039,6 +1042,15 @@ nios2-*-*)
tmake_file="$tmake_file nios2/t-nios2 t-softfp-sfdf t-softfp-excl t-softfp"
extra_parts="$extra_parts crti.o crtn.o"
;;
or1k-*-linux*)
tmake_file="$tmake_file or1k/t-or1k"
tmake_file="$tmake_file t-softfp-sfdf t-softfp"
md_unwind_header=or1k/linux-unwind.h
;;
or1k-*-*)
tmake_file="$tmake_file or1k/t-or1k"
tmake_file="$tmake_file t-softfp-sfdf t-softfp"
;;
pdp11-*-*)
tmake_file="pdp11/t-pdp11 t-fdpbit"
;;

View File

@ -0,0 +1,222 @@
/* Copyright (C) 2018 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/>. */
#ifdef L__mulsi3
.balign 4
.globl __mulsi3
.type __mulsi3, @function
__mulsi3:
l.movhi r11, 0 /* initial r */
/* Given R = X * Y ... */
1: l.sfeq r4, r0 /* while (y != 0) */
l.bf 2f
l.andi r5, r4, 1 /* if (y & 1) ... */
l.add r12, r11, r3
l.sfne r5, r0
#if defined(__or1k_cmov__)
l.cmov r11, r12, r11 /* ... r += x. */
l.srli r4, r4, 1 /* y >>= 1 */
#else
l.bnf 3f
l.srli r4, r4, 1 /* y >>= 1 */
l.ori r11, r12, 0
3:
#endif
l.j 1b
l.add r3, r3, r3 /* x <<= 1 */
2: l.jr r9
l.nop
.size __mulsi3, . - __mulsi3
#endif
#if defined(L__udivsi3) || defined(L__umodsi3) \
|| defined(L__divsi3) || defined(L__modsi3)
.global __udivmodsi3_internal
.hidden __udivmodsi3_internal
.type __udivmodsi3_internal, @function
#endif
#ifdef L__udivsi3
.balign 4
.global __udivsi3
.type __udivsi3, @function
__udivsi3:
__udivmodsi3_internal:
/* Note that the other division routines assume that r13
is not clobbered by this routine, and use that as to
save a return address without creating a stack frame. */
l.sfeqi r4, 0 /* division by zero; return 0. */
l.ori r11, r0, 0 /* initial quotient */
l.bf 9f
l.ori r12, r3, 0 /* initial remainder */
/* Given X/Y, shift Y left until Y >= X. */
l.ori r6, r0, 1 /* mask = 1 */
1: l.sfltsi r4, 0 /* y has msb set */
l.bf 2f
l.sfltu r4, r12 /* y < x */
l.add r4, r4, r4 /* y <<= 1 */
l.bnf 1b
l.add r6, r6, r6 /* mask <<= 1 */
/* Shift Y back to the right again, subtracting from X. */
2: l.add r7, r11, r6 /* tmp1 = quot + mask */
3: l.srli r6, r6, 1 /* mask >>= 1 */
l.sub r8, r12, r4 /* tmp2 = x - y */
l.sfleu r4, r12 /* y <= x */
l.srli r4, r4, 1 /* y >>= 1 */
#if defined(__or1k_cmov__)
l.cmov r11, r7, r11 /* if (y <= x) quot = tmp1 */
l.cmov r12, r8, r12 /* if (y <= x) x = tmp2 */
#else
l.bnf 4f
l.nop
l.ori r11, r7, 0
l.ori r12, r8, 0
4:
#endif
l.sfne r6, r0 /* loop until mask == 0 */
l.bf 3b
l.add r7, r11, r6 /* delay fill from loop start */
9: l.jr r9
l.nop
.size __udivsi3, . - __udivsi3
.size __udivmodsi3_internal, . - __udivmodsi3_internal
#endif
#ifdef L__umodsi3
.balign 4
.global __umodsi3
.type __umodsi3, @function
.cfi_startproc
__umodsi3:
/* Know that __udivmodsi3_internal does not clobber r13. */
l.ori r13, r9, 0
.cfi_register 9, 13
l.jal __udivmodsi3_internal
l.nop
l.jr r13 /* return to saved lr */
l.ori r11, r12, 0 /* move remainder to rv */
.cfi_endproc
.size __umodsi3, . - __umodsi3
#endif
/* For signed division we do:
-x / y = x / -y = -(x / y)
-x % y = -(x % y)
x % -y = x % y
which has the property that (x/y)*y + (x%y) = x. */
#ifdef L__divsi3
.balign 4
.global __divsi3
.type __divsi3, @function
.cfi_startproc
__divsi3:
l.xor r6, r3, r4 /* need result negate? */
l.sflts r3, r0 /* abs(x) */
#if defined(__or1k_cmov__)
l.sub r5, r0, r3
l.cmov r3, r5, r3
#else
l.bnf 1f
l.sub r5, r0, r3
l.ori r3, r5, 0
1:
#endif
l.sflts r4, r0 /* abs(y) */
#if defined(__or1k_cmov__)
l.sub r5, r0, r4
l.cmov r4, r5, r4
#else
l.bnf 2f
l.sub r5, r0, r4
l.ori r4, r5, 0
2:
#endif
/* If the result will not require sign flip, tail call. */
l.sflts r6, r0
l.bnf __udivmodsi3_internal
l.ori r13, r9, 0 /* save lr */
/* Otherwise, know that __udivmodsi3_internal does not clobber r13.
Perform a normal call, then negate and return via saved lr. */
.cfi_register 9, 13
l.jal __udivmodsi3_internal
l.nop
l.jr r13
l.sub r11, r0, r11
.cfi_endproc
.size __divsi3, . - __divsi3
#endif
#ifdef L__modsi3
.balign 4
.global __modsi3
.type __modsi3, @function
.cfi_startproc
__modsi3:
l.sflts r4, r0 /* abs(y) */
#if defined(__or1k_cmov__)
l.sub r5, r0, r4
l.cmov r4, r5, r4
#else
l.bnf 2f
l.sub r5, r0, r4
l.ori r4, r5, 0
2:
#endif
l.sflts r3, r0 /* x negative? */
l.bf 1f
l.ori r13, r9, 0 /* save lr */
/* Know that __udivmodsi3_internal does not clobber r13. */
.cfi_register 9, 13
/* X positive; no negate of the result required. */
l.jal __udivmodsi3_internal
l.nop
l.jr r13 /* return to saved lr */
l.ori r11, r12, 0 /* move remainder to rv */
/* X negative; negate both X and the result. */
1: l.jal __udivmodsi3_internal
l.sub r3, r0, r3
l.jr r13 /* return to saved lr */
l.sub r11, r0, r12 /* negate remainder to rv */
.cfi_endproc
.size __modsi3, .- __modsi3
#endif

View File

@ -0,0 +1,87 @@
/* DWARF2 EH unwinding support for OpenRISC Linux.
Copyright (C) 2018 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 3, or (at your option)
any later version.
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.
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. */
#include <signal.h>
#include <sys/ucontext.h>
#define MD_FALLBACK_FRAME_STATE_FOR or1k_fallback_frame_state
static _Unwind_Reason_Code
or1k_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned int *pc = context->ra;
struct rt_sigframe {
siginfo_t info;
ucontext_t uc;
} *rt;
struct sigcontext *sc;
long new_cfa;
int i;
if (pc[0] != 0xa960008b /* l.ori r11, r0, NR_rt_sigreturn */
|| pc[1] != 0x20000001) /* l.sys 1 */
return _URC_END_OF_STACK;
if (context->cfa == 0)
return _URC_END_OF_STACK;
rt = context->cfa;
sc = &rt->uc.uc_mcontext;
new_cfa = sc->regs.gpr[1];
fs->regs.cfa_how = CFA_REG_OFFSET;
fs->regs.cfa_reg = 1;
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
for (i = 2; i < 32; ++i)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset = (long) &sc->regs.gpr[i] - new_cfa;
}
fs->regs.reg[32].how = REG_SAVED_OFFSET;
fs->regs.reg[32].loc.offset = (long)&sc->regs.pc - new_cfa;
fs->retaddr_column = 32;
fs->signal_frame = 1;
return _URC_NO_REASON;
}
#define MD_FROB_UPDATE_CONTEXT or1k_frob_update_context
/* Fix up for signal handlers that don't have S flag set. */
static void
or1k_frob_update_context (struct _Unwind_Context *context,
_Unwind_FrameState *fs ATTRIBUTE_UNUSED)
{
unsigned int *pc = context->ra;
if (pc[0] == 0xa960008b /* l.ori r11, r0, NR_rt_sigreturn */
&& pc[1] == 0x20000001) /* l.sys 1 */
_Unwind_SetSignalFrame (context, 1);
}
#endif

View File

@ -0,0 +1,54 @@
#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
#define __BYTE_ORDER __BIG_ENDIAN
#define _FP_TININESS_AFTER_ROUNDING 0
/* 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)));

22
libgcc/config/or1k/t-or1k Normal file
View File

@ -0,0 +1,22 @@
# Libgcc Makefile fragment for OpenRISC
# Copyright (C) 2018 Free Software Foundation, Inc.
# Contributed by Stafford Horne.
#
# 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 3, or (at your
# option) any later version.
#
# 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 COPYING3. If not see
# <http://www.gnu.org/licenses/>.
LIB1ASMSRC = or1k/lib1funcs.S
LIB1ASMFUNCS = __mulsi3 __udivsi3 __divsi3 __umodsi3 __modsi3