mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-14 05:20:25 +08:00
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:
parent
69104d52dd
commit
d929e137f8
@ -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.
|
||||
|
@ -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"
|
||||
;;
|
||||
|
222
libgcc/config/or1k/lib1funcs.S
Normal file
222
libgcc/config/or1k/lib1funcs.S
Normal 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
|
87
libgcc/config/or1k/linux-unwind.h
Normal file
87
libgcc/config/or1k/linux-unwind.h
Normal 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
|
54
libgcc/config/or1k/sfp-machine.h
Normal file
54
libgcc/config/or1k/sfp-machine.h
Normal 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
22
libgcc/config/or1k/t-or1k
Normal 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
|
Loading…
x
Reference in New Issue
Block a user