From patchwork Sun Apr 8 07:02:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?5q+b5pmX?= X-Patchwork-Id: 896005 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-91468-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=c-sky.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="vFubWZ+k"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40Jkvq1wnxz9ryG for ; Sun, 8 Apr 2018 17:04:55 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; q=dns; s=default; b=FsBdVhjM tKOKMCxHxW1uPP/PY6vlfu/GHJDisVoL1xzxPbSAPzM82LMSA2FOUUY+SMO3bkAi 1WZf1R8oWCISgFNWME6adkjkduHOCFjMfHMx3WF9/wj43oyYrRNOk0dp8y2WTvap 90jGINjZP2QgUwbE0pixf0O5VekmNutBqAk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; s=default; bh=aZRXZuLdMdoArB DESeh2tMw1BAg=; b=vFubWZ+k9SSlDMxoJjmdW5Tk26iwsKlnt197b1N26/seVM 2mTf8c4dJ6I3k+F1Qgn0Stkl2UgOu6idl768qDW89kLaRUxmNMKYhyewgORovIgm uCa2GjX8Rd40HP6ydWjEjEfnJ+++jktZUbmuvYP++wf1Bb03c80rrfl33G0+A= Received: (qmail 122718 invoked by alias); 8 Apr 2018 07:03:55 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 122472 invoked by uid 89); 8 Apr 2018 07:03:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy=1400, Standards, judge, bez X-HELO: smtp2200-217.mail.aliyun.com X-Alimail-AntiSpam: AC=CONTINUE; BC=0.07444093|-1; CH=green; FP=0|0|0|0|0|-1|-1|-1; HT=e02c03291; MF=han_mao@c-sky.com; NM=1; PH=DS; RN=4; RT=4; SR=0; TI=SMTPD_---.Bc2W8ek_1523171009; From: Mao Han To: libc-alpha@sourceware.org Cc: Mao Han , c-sky_gcc_upstream@c-sky.com, gnu-csky@mentor.com Subject: [RFC PATCH V2 01/10] C-SKY: ABI related code Date: Sun, 8 Apr 2018 15:02:24 +0800 Message-Id: In-Reply-To: References: In-Reply-To: References: Codes in this patch contains lots of C-SKY ABI related code. They are written accroding to the registers assgnments, relocations, assemblly described in C-SKY CPU ABI Standards and C-SKY CPU manual. This does not contain any linux related code. * sysdeps/csky/__longjmp.S: New file * sysdeps/csky/backtrace.c: New file * sysdeps/csky/bits/endian.h: New file * sysdeps/csky/bits/setjmp.h: New file * sysdeps/csky/bsd-_setjmp.S: New file * sysdeps/csky/bsd-setjmp.S: New file * sysdeps/csky/dl-trampoline.S: New file * sysdeps/csky/gccframe.h: New file * sysdeps/csky/jmpbuf-unwind.h: New file * sysdeps/csky/setjmp.S: New file * sysdeps/csky/tls-macros.h: New file * sysdeps/csky/crti.S: New file * sysdeps/csky/crtn.S: New file * sysdeps/csky/csky-mcount.S: New file * sysdeps/csky/abort-instr.h: New file * sysdeps/unix/csky/abiv2_sysdep.S: New file * sysdeps/unix/csky/sysdep.S: New file * sysdeps/unix/csky/sysdep.h: New file * sysdeps/csky/start.S: New file * sysdeps/csky/strcmp.S: New file * sysdeps/csky/strcpy.S: New file * sysdeps/csky/memcpy.S: New file * sysdeps/csky/macro.S: New file * sysdeps/csky/memusage.h: New file * sysdeps/csky/machine-gmon.h: New file * sysdeps/csky/bits/link.h: New file * sysdeps/csky/sys/ucontext.h: New file * sysdeps/csky/sysdep.h: New file --- sysdeps/csky/__longjmp.S | 74 ++++++++ sysdeps/csky/abort-instr.h | 2 + sysdeps/csky/backtrace.c | 128 +++++++++++++ sysdeps/csky/bits/endian.h | 10 + sysdeps/csky/bits/link.h | 54 ++++++ sysdeps/csky/bits/setjmp.h | 34 ++++ sysdeps/csky/bsd-_setjmp.S | 1 + sysdeps/csky/bsd-setjmp.S | 1 + sysdeps/csky/crti.S | 96 ++++++++++ sysdeps/csky/crtn.S | 50 +++++ sysdeps/csky/csky-mcount.S | 87 +++++++++ sysdeps/csky/dl-trampoline.S | 88 +++++++++ sysdeps/csky/gccframe.h | 21 ++ sysdeps/csky/jmpbuf-unwind.h | 47 +++++ sysdeps/csky/machine-gmon.h | 32 ++++ sysdeps/csky/macro.S | 30 +++ sysdeps/csky/memcpy.S | 400 +++++++++++++++++++++++++++++++++++++++ sysdeps/csky/memusage.h | 20 ++ sysdeps/csky/setjmp.S | 113 +++++++++++ sysdeps/csky/start.S | 133 +++++++++++++ sysdeps/csky/strcmp.S | 336 ++++++++++++++++++++++++++++++++ sysdeps/csky/strcpy.S | 273 ++++++++++++++++++++++++++ sysdeps/csky/sys/ucontext.h | 116 ++++++++++++ sysdeps/csky/sysdep.h | 45 +++++ sysdeps/csky/tls-macros.h | 106 +++++++++++ sysdeps/unix/csky/abiv2_sysdep.S | 63 ++++++ sysdeps/unix/csky/sysdep.S | 74 ++++++++ sysdeps/unix/csky/sysdep.h | 26 +++ 28 files changed, 2460 insertions(+) create mode 100644 sysdeps/csky/__longjmp.S create mode 100644 sysdeps/csky/abort-instr.h create mode 100644 sysdeps/csky/backtrace.c create mode 100644 sysdeps/csky/bits/endian.h create mode 100644 sysdeps/csky/bits/link.h create mode 100644 sysdeps/csky/bits/setjmp.h create mode 100644 sysdeps/csky/bsd-_setjmp.S create mode 100644 sysdeps/csky/bsd-setjmp.S create mode 100644 sysdeps/csky/crti.S create mode 100644 sysdeps/csky/crtn.S create mode 100644 sysdeps/csky/csky-mcount.S create mode 100644 sysdeps/csky/dl-trampoline.S create mode 100644 sysdeps/csky/gccframe.h create mode 100644 sysdeps/csky/jmpbuf-unwind.h create mode 100644 sysdeps/csky/machine-gmon.h create mode 100644 sysdeps/csky/macro.S create mode 100644 sysdeps/csky/memcpy.S create mode 100644 sysdeps/csky/memusage.h create mode 100644 sysdeps/csky/setjmp.S create mode 100644 sysdeps/csky/start.S create mode 100644 sysdeps/csky/strcmp.S create mode 100644 sysdeps/csky/strcpy.S create mode 100644 sysdeps/csky/sys/ucontext.h create mode 100644 sysdeps/csky/sysdep.h create mode 100644 sysdeps/csky/tls-macros.h create mode 100644 sysdeps/unix/csky/abiv2_sysdep.S create mode 100644 sysdeps/unix/csky/sysdep.S create mode 100644 sysdeps/unix/csky/sysdep.h diff --git a/sysdeps/csky/__longjmp.S b/sysdeps/csky/__longjmp.S new file mode 100644 index 0000000..ee32cc0 --- /dev/null +++ b/sysdeps/csky/__longjmp.S @@ -0,0 +1,74 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +ENTRY(__longjmp) + mov a2, a0 + mov a0, a1 /* get the return value in place */ + cmpnei a0, 0 + bt have_return + movi a0, 1 /* can't let setjmp() return zero! */ +have_return: +#ifdef CHECK_SP + ldw r10, (a2, 0) /* jmpbuf's sp */ +#ifdef PTR_MANGLE + PTR_DEMANGLE(r10, r10, a3) +#endif + CHECK_SP(r10) +#endif +#ifdef __CSKYABIV2__ + ldw sp, (a2, 0) + ldw lr, (a2, 4) + ldw r4, (a2, 8) + ldw r5, (a2, 12) + ldw r6, (a2, 16) + ldw r7, (a2, 20) + ldw r8, (a2, 24) + ldw r9, (a2, 28) + ldw r10, (a2, 32) + ldw r11, (a2, 36) + ldw r16, (a2, 40) + ldw r17, (a2, 44) + ldw r26, (a2, 48) + ldw r27, (a2, 52) + ldw r28, (a2, 56) + ldw r29, (a2, 60) + ldw r30, (a2, 64) + ldw r31, (a2, 68) + addi a2, 72 +#else + ldw sp, (a2, 0) + ldw lr, (a2, 4) + ldw r8, (a2, 8) + ldw r9, (a2, 12) + ldw r10, (a2, 16) + ldw r11, (a2, 20) + ldw r12, (a2, 24) + ldw r13, (a2, 28) + ldw r14, (a2, 32) + addi a2, 32 + addi a2, 4 +#endif + +#ifdef PTR_MANGLE + PTR_DEMANGLE(sp, sp, a3) + PTR_DEMANGLE2(lr, lr, a3) +#endif + jmp lr + +END(__longjmp) diff --git a/sysdeps/csky/abort-instr.h b/sysdeps/csky/abort-instr.h new file mode 100644 index 0000000..27a3536 --- /dev/null +++ b/sysdeps/csky/abort-instr.h @@ -0,0 +1,2 @@ +/* An instruction which should crash any program is a breakpoint. */ +#define ABORT_INSTRUCTION asm ("bkpt") diff --git a/sysdeps/csky/backtrace.c b/sysdeps/csky/backtrace.c new file mode 100644 index 0000000..9a6f36c --- /dev/null +++ b/sysdeps/csky/backtrace.c @@ -0,0 +1,128 @@ +/* Return backtrace of current program state. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include +#include +#include + +struct trace_arg +{ + void **array; + _Unwind_Word cfa; + int cnt; + int size; +}; + +#ifdef SHARED +static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); +static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *); +static _Unwind_Word (*unwind_getcfa) (struct _Unwind_Context *); +static void *libgcc_handle; + +/* Dummy version in case libgcc_s does not contain the real code. */ +static _Unwind_Word +dummy_getcfa (struct _Unwind_Context *ctx __attribute__ ((unused))) +{ + return 0; +} + + +static void +init (void) +{ + libgcc_handle = __libc_dlopen ("libgcc_s.so.1"); + + if (libgcc_handle == NULL) + return; + + unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace"); + unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP"); + if (unwind_getip == NULL) + unwind_backtrace = NULL; + unwind_getcfa = (__libc_dlsym (libgcc_handle, "_Unwind_GetCFA") + ?: dummy_getcfa); +} +#else +# define unwind_backtrace _Unwind_Backtrace +# define unwind_getip _Unwind_GetIP +# define unwind_getcfa _Unwind_GetCFA +#endif + +static _Unwind_Reason_Code +backtrace_helper (struct _Unwind_Context *ctx, void *a) +{ + struct trace_arg *arg = a; + + /* We are first called with address in the __backtrace function. + Skip it. */ + if (arg->cnt != -1) + { + arg->array[arg->cnt] = (void *) unwind_getip (ctx); + + /* Check whether we make any progress. */ + _Unwind_Word cfa = unwind_getcfa (ctx); + + if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt] + && cfa == arg->cfa) + return _URC_END_OF_STACK; + arg->cfa = cfa; + } + if (++arg->cnt == arg->size) + return _URC_END_OF_STACK; + return _URC_NO_REASON; +} + +int +__backtrace (void **array, int size) +{ + struct trace_arg arg = { .array = array, .cfa = 0, .size = size, .cnt = -1 }; +#ifdef SHARED + __libc_once_define (static, once); + + __libc_once (once, init); + if (unwind_backtrace == NULL) + return 0; +#endif + + if (size >= 1) + unwind_backtrace (backtrace_helper, &arg); + + /* _Unwind_Backtrace seems to put NULL address above + _start. Fix it up here. */ + if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL) + --arg.cnt; + return arg.cnt != -1 ? arg.cnt : 0; +} +weak_alias (__backtrace, backtrace) +libc_hidden_def (__backtrace) + + +#ifdef SHARED +/* Free all resources if necessary. */ +libc_freeres_fn (free_mem) +{ + unwind_backtrace = NULL; + if (libgcc_handle != NULL) + { + __libc_dlclose (libgcc_handle); + libgcc_handle = NULL; + } +} +#endif diff --git a/sysdeps/csky/bits/endian.h b/sysdeps/csky/bits/endian.h new file mode 100644 index 0000000..cc66abb --- /dev/null +++ b/sysdeps/csky/bits/endian.h @@ -0,0 +1,10 @@ +#ifndef _ENDIAN_H +# error "Never use directly; include instead." +#endif + +/* CSKY can be either big or little endian. */ +#ifdef __CSKYBE__ +# define __BYTE_ORDER __BIG_ENDIAN +#else +# define __BYTE_ORDER __LITTLE_ENDIAN +#endif diff --git a/sysdeps/csky/bits/link.h b/sysdeps/csky/bits/link.h new file mode 100644 index 0000000..87121ca --- /dev/null +++ b/sysdeps/csky/bits/link.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _LINK_H +# error "Never include directly; use instead." +#endif + +/* Registers for entry into PLT on CSKY. */ +typedef struct La_csky_regs + { + uint32_t lr_reg[4]; + uint32_t lr_sp; + uint32_t lr_lr; + } La_csky_regs; + +/* Return values for calls from PLT on CSKY. */ +typedef struct La_csky_retval + { + /* Up to four integer registers can be used for a return value. */ + uint32_t lrv_reg[4]; + uint32_t lrv_v0; + } La_csky_retval; + +__BEGIN_DECLS + +extern Elf32_Addr la_csky_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_csky_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_csky_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_csky_regs *__inregs, + La_csky_retval *__outregs, + const char *__symname); + +__END_DECLS diff --git a/sysdeps/csky/bits/setjmp.h b/sysdeps/csky/bits/setjmp.h new file mode 100644 index 0000000..e5f71a6 --- /dev/null +++ b/sysdeps/csky/bits/setjmp.h @@ -0,0 +1,34 @@ +/* Define the machine-dependent type `jmp_buf'. C-SKY version + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _CSKY_BITS_SETJMP_H +#define _CSKY_BITS_SETJMP_H 1 + +typedef struct __jmp_buf_str + { + /* Stack pointer. */ + int __sp; + int __lr; + /* The actual core defines which registers should be saved. The + buffer contains 32 words, keep space for future growth. + Callee-saved registers: + r4 ~ r11, r16 ~ r17, r26 ~r31 for abiv2; r8 ~ r14 for abiv1. */ + int __regs[32]; + } __jmp_buf[1]; + +#endif diff --git a/sysdeps/csky/bsd-_setjmp.S b/sysdeps/csky/bsd-_setjmp.S new file mode 100644 index 0000000..4e6a2da --- /dev/null +++ b/sysdeps/csky/bsd-_setjmp.S @@ -0,0 +1 @@ +/* _setjmp is in setjmp.S */ diff --git a/sysdeps/csky/bsd-setjmp.S b/sysdeps/csky/bsd-setjmp.S new file mode 100644 index 0000000..1da848d --- /dev/null +++ b/sysdeps/csky/bsd-setjmp.S @@ -0,0 +1 @@ +/* setjmp is in setjmp.S */ diff --git a/sysdeps/csky/crti.S b/sysdeps/csky/crti.S new file mode 100644 index 0000000..163eccd --- /dev/null +++ b/sysdeps/csky/crti.S @@ -0,0 +1,96 @@ +/* Special .init and .fini section support for C-SKY. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* crti.S puts a function prologue at the beginning of the .init and + .fini sections and defines global symbols for those addresses, so + they can be called as functions. The symbols _init and _fini are + magic and cause the linker to emit DT_INIT and DT_FINI. */ + +#include +#include + +#ifndef PREINIT_FUNCTION +# define PREINIT_FUNCTION __gmon_start__ +#endif + +#ifndef PREINIT_FUNCTION_WEAK +# define PREINIT_FUNCTION_WEAK 1 +#endif + +#if PREINIT_FUNCTION_WEAK + weak_extern (PREINIT_FUNCTION) +#else + .hidden PREINIT_FUNCTION +#endif + + .section .init,"ax",@progbits + .align 4 + .globl _init + .type _init, @function +_init: + subi sp, 8 + stw lr, (sp, 0) + stw gb, (sp, 4) + bsr .Lgetpc +.Lgetpc: + lrw gb, .Lgetpc@GOTPC + add gb, lr +#if PREINIT_FUNCTION_WEAK + lrw a2, PREINIT_FUNCTION@GOT + addu a2, gb + ldw a2, (a2) + cmpnei a2, 0 + bf 1f + jsr a2 +1: +#else + jsri PREINIT_FUNCTION +#endif /* PREINIT_FUNCTION_WEAK */ + br 2f + .literals + .align 4 +2: + + .section .fini,"ax",@progbits + .align 4 + .globl _fini + .type _fini, @function +_fini: + subi sp,8 + stw lr, (sp, 0) + br 2f + .literals + .align 4 +2: diff --git a/sysdeps/csky/crtn.S b/sysdeps/csky/crtn.S new file mode 100644 index 0000000..c7d5fbe --- /dev/null +++ b/sysdeps/csky/crtn.S @@ -0,0 +1,50 @@ +/* Special .init and .fini section support for C-SKY. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +/* crtn.S puts function epilogues in the .init and .fini sections + corresponding to the prologues in crti.S. */ + + .section .init,"ax",@progbits + ldw lr, (sp, 0) + ldw gb, (sp, 4) + addi sp, 8 + rts + + .section .fini,"ax",@progbits + ldw lr, (sp, 0) + addi sp,8 + rts diff --git a/sysdeps/csky/csky-mcount.S b/sysdeps/csky/csky-mcount.S new file mode 100644 index 0000000..22fda58 --- /dev/null +++ b/sysdeps/csky/csky-mcount.S @@ -0,0 +1,87 @@ +/* Implementation of profiling support. C-SKY version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* Don't call mcount when calling mcount... */ +#undef PROF + +#include + +/* Use an assembly stub with a special ABI. The calling lr has been + pushed to the stack (which will be misaligned). We should preserve + all registers except ip and pop a word off the stack. + + NOTE: This assumes mcount_internal does not clobber any non-core + (coprocessor) registers. Currently this is true, but may require + additional attention in the future. + + The calling sequence looks something like: +func: + push lr + jbsr __gnu_mount_nc + +*/ + +ENTRY(_mcount) +#ifdef __CSKYABIV2__ + subi sp,20 + stw a0,(sp, 0) + stw a1,(sp, 4) + stw a2,(sp, 8) + stw a3,(sp, 12) + stw lr,(sp, 16) + mov a1, lr + ldw a0, (sp, 20) + jbsr __mcount_internal + ldw a0,(sp, 0) + ldw a1,(sp, 4) + ldw a2,(sp, 8) + ldw a3,(sp, 12) + ldw t1,(sp, 16) + ldw lr,(sp, 20) + addi sp,24 + jmp t1 +#else + subi sp,28 + stw a0,(sp, 0) + stw a1,(sp, 4) + stw a2,(sp, 8) + stw a3,(sp, 12) + stw a4,(sp, 16) + stw a5,(sp, 20) + stw lr,(sp, 24) + mov a1, lr + ldw a0, (sp, 28) + jbsr __mcount_internal + ldw a0,(sp, 0) + ldw a1,(sp, 4) + ldw a2,(sp, 8) + ldw a3,(sp, 12) + ldw a4,(sp, 16) + ldw a5,(sp, 20) + ldw r1,(sp, 24) + ldw lr,(sp, 28) + addi sp,32 + jmp r1 +#endif + +END(_mcount) + +/* The canonical name for the function is `_mcount' in both C and asm, + but some old asm code might assume it's `mcount'. */ +#undef mcount +weak_alias (_mcount, mcount) diff --git a/sysdeps/csky/dl-trampoline.S b/sysdeps/csky/dl-trampoline.S new file mode 100644 index 0000000..e02d90a --- /dev/null +++ b/sysdeps/csky/dl-trampoline.S @@ -0,0 +1,88 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* This function is not called directly. It is jumped when attempting to use a + symbol that has not yet been resolved. + + .plt*: + subi r0, 32 + stw r2, (r0, 0) + stw r3, (r0, 4) + lrw r3, #offset + ldw r2, (gb, 8) + jmp r2 + */ + +.import _dl_fixup + +.text +.globl _dl_runtime_resolve +.type _dl_runtime_resolve,@function + +_dl_runtime_resolve: +#if !defined(__CSKYABIV2__) + stw r4, (r0, 8) + stw r5, (r0, 12) + stw r6, (r0, 16) + stw r7, (r0, 20) + stw r15,(r0, 24) + # load the ID of this module + ldw r2, (gb, 4) + mov r6, r3 + addu r6, r6 + addu r3, r6 + lsli r3, 2 + # r2 = id, r3 = offset(do it in plt*) + # get global offset table address_ + bsr .L2 +.L2: + lrw r7, .L2@GOTPC + add r7, r15 + # get the address of function (_dl_fixup) in got table + lrw r6, _dl_fixup@GOT + add r6, r7 + ldw r5, (r6, 0) + jsr r5 + # Return from _dl_fixup, the address of function is in r2 + mov r1, r2 + # Restore the registers + ldw r2, (r0, 0) + ldw r3, (r0, 4) + ldw r4, (r0, 8) + ldw r5, (r0, 12) + ldw r6, (r0, 16) + ldw r7, (r0, 20) + ldw r15,(r0, 24) + # Restore the r0, because r0 is subtracted in PLT table + addi r0, 32 + # The address of function is in r1, call the function without saving pc + jmp r1 +#else /* __CSKYABIV2__ */ + subi sp, 20 + stm a0-a3, (sp) + stw lr, (sp, 16) + # a0 = id, a1 = offset(do it in plt*) + ldw a0, (gb, 4) + movi a1, 12 + mult a1, t1 + bsr _dl_fixup + mov t0, a0 + ldw lr, (sp, 16) + ldm a0-a3, (sp) + addi sp, 20 + jmp t0 +#endif /* __CSKYABIV2__ */ diff --git a/sysdeps/csky/gccframe.h b/sysdeps/csky/gccframe.h new file mode 100644 index 0000000..9451101 --- /dev/null +++ b/sysdeps/csky/gccframe.h @@ -0,0 +1,21 @@ +/* Definition of object in frame unwind info. C-SKY version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define FIRST_PSEUDO_REGISTER 71 + +#include diff --git a/sysdeps/csky/jmpbuf-unwind.h b/sysdeps/csky/jmpbuf-unwind.h new file mode 100644 index 0000000..30b92d0 --- /dev/null +++ b/sysdeps/csky/jmpbuf-unwind.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include +#include +#include + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ + ((void *) (address) < (void *) demangle ((jmpbuf)[0].__sp)) + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, \ + (void *) (_Unwind_Ptr) _Unwind_GetCFA (_context), \ + _adj) + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf regs) +{ + uintptr_t sp = (uintptr_t) regs[0].__sp; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (sp); +#endif + return sp; +} + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + +/* We use the normal longjmp for unwinding. */ +#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/sysdeps/csky/machine-gmon.h b/sysdeps/csky/machine-gmon.h new file mode 100644 index 0000000..1a81ef5 --- /dev/null +++ b/sysdeps/csky/machine-gmon.h @@ -0,0 +1,32 @@ +/* Machine-dependent definitions for profiling support. CSKY version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +/* GCC for the CSKY cannot compile __builtin_return_address(N) for N != 0, + so we must use an assembly stub. */ + +/* We must not pollute the global namespace. */ +#define mcount_internal __mcount_internal + +extern void mcount_internal (u_long frompc, u_long selfpc); +#define _MCOUNT_DECL(frompc, selfpc) \ + void mcount_internal (u_long frompc, u_long selfpc) + +/* Define MCOUNT as empty since we have the implementation in another file. */ +#define MCOUNT diff --git a/sysdeps/csky/macro.S b/sysdeps/csky/macro.S new file mode 100644 index 0000000..c0f05ff --- /dev/null +++ b/sysdeps/csky/macro.S @@ -0,0 +1,30 @@ +/* Macro defiation for string/mem operations on different cpu types + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +.macro M_BEZ rx, label + bez \rx, \label +.endm + +.macro M_BNEZ rx, label + bnez \rx, \label +.endm + +.macro M_BNE rx, ry, label + cmpne \rx, \ry + bt \label +.endm diff --git a/sysdeps/csky/memcpy.S b/sysdeps/csky/memcpy.S new file mode 100644 index 0000000..9106423 --- /dev/null +++ b/sysdeps/csky/memcpy.S @@ -0,0 +1,400 @@ +/* The assembly function for memcpy. C-SKY version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +.macro GET_FRONT_BITS rx ry +#ifdef __cskyLE__ + lsr \rx, \ry +#else + lsl \rx, \ry +#endif +.endm + +.macro GET_AFTER_BITS rx ry +#ifdef __cskyLE__ + lsl \rx, \ry +#else + lsr \rx, \ry +#endif +.endm + +ENTRY(memcpy) +#ifndef __CSKYABIV2__ + /* If len less than 4 bytes */ + mov r7, r2 + cmplti r4, 4 + jbt .L_copy_by_byte + + /* If dest is not 4 bytes aligned */ + mov r6, r2 + andi r6, 3 + cmpnei r6, 0 + jbt .L_dest_not_aligned + .L0: + mov r6, r3 + andi r6, 3 + cmpnei r6, 0 + /* If dest is aligned, but src is not aligned */ + jbt .L_dest_aligned_but_src_not_aligned + + /* If dest and src are all aligned and len less than 16 bytes */ + cmplti r4, 16 + jbt .L_aligned_and_len_less_16bytes + + /* src and dst are all aligned, and len > 16 bytes */ + subi sp, 8 + stw r8, (sp, 0) + stw r9, (sp, 4) +.L_aligned_and_len_larger_16bytes: + ldw r1, (r3, 0) + ldw r5, (r3, 4) + ldw r8, (r3, 8) + ldw r9, (r3, 12) + stw r1, (r7, 0) + stw r5, (r7, 4) + stw r8, (r7, 8) + stw r9, (r7, 12) + subi r4, 16 + addi r3, 16 + addi r7, 16 + cmplti r4, 16 + jbf .L_aligned_and_len_larger_16bytes + ldw r8, (sp, 0) + ldw r9, (sp, 4) + addi sp, 8 + +.L_aligned_and_len_less_16bytes: + cmplti r4, 4 + jbt .L_copy_by_byte + ldw r1, (r3, 0) + stw r1, (r7, 0) + subi r4, 4 + addi r3, 4 + addi r7, 4 + jbr .L_aligned_and_len_less_16bytes + + /* len less than 4 bytes */ +.L_copy_by_byte: + cmpnei r4, 0 + jbf .L_return + ldb r1, (r3, 0) + stb r1, (r7, 0) + subi r4, 1 + addi r3, 1 + addi r7, 1 + jbr .L_copy_by_byte + +.L_return: + rts + + /* If dest is not aligned, we copy some bytes to make dest align. + Then we should judge whether src is aligned. */ + + /* consider overlapped case */ +.L_dest_not_aligned: + mov r5, r3 + rsub r5, r5, r7 + abs r5, r5 + cmplt r5, r4 + jbt .L_copy_by_byte + + /* Makes the dest align. */ +.L1: + ldb r1, (r3, 0) + stb r1, (r7, 0) + addi r6, 1 + subi r4, 1 + addi r3, 1 + addi r7, 1 + cmpnei r6, 4 + jbt .L1 + cmplti r4, 4 + jbt .L_copy_by_byte + /* Judge whether the src is aligned. */ + jbf .L0 + + /* consider overlapped case */ +.L_dest_aligned_but_src_not_aligned: + mov r5, r3 + rsub r5, r5, r7 + abs r5, r5 + cmplt r5, r4 + jbt .L_copy_by_byte + + bclri r3, 0 + bclri r3, 1 + ldw r1, (r3, 0) + addi r3, 4 + + subi sp, 16 + stw r11, (sp,0) + stw r12, (sp,4) + stw r13, (sp,8) + movi r5, 8 + /* r6 is used to store tne misaligned bits */ + mult r5, r6 + mov r12, r5 + rsubi r5, 31 + addi r5, 1 + mov r13, r5 + + cmplti r4, 16 + jbt .L_not_aligned_and_len_less_16bytes + + stw r8, (sp, 12) + subi sp, 8 + stw r9, (sp, 0) + stw r10, (sp, 4) +.L_not_aligned_and_len_larger_16bytes: + ldw r5, (r3, 0) + ldw r11, (r3, 4) + ldw r8, (r3, 8) + ldw r9, (r3, 12) + + /* little or big endian? */ + GET_FRONT_BITS r1 r12 + mov r10, r5 + GET_AFTER_BITS r5 r13 + or r5, r1 + + GET_FRONT_BITS r10 r12 + mov r1, r11 + GET_AFTER_BITS r11 r13 + or r11, r10 + + GET_FRONT_BITS r1 r12 + mov r10, r8 + GET_AFTER_BITS r8 r13 + or r8, r1 + + GET_FRONT_BITS r10 r12 + mov r1, r9 + GET_AFTER_BITS r9 r13 + or r9, r10 + + stw r5, (r7, 0) + stw r11, (r7, 4) + stw r8, (r7, 8) + stw r9, (r7, 12) + subi r4, 16 + addi r3, 16 + addi r7, 16 + cmplti r4, 16 + jbf .L_not_aligned_and_len_larger_16bytes + ldw r9, (sp, 0) + ldw r10, (sp, 4) + addi sp, 8 + ldw r8, (sp,12) + +.L_not_aligned_and_len_less_16bytes: + cmplti r4, 4 + jbf .L2 + /* r6 is used to stored the misaligned bits */ + rsubi r6, 4 + /* initial the position */ + subu r3, r6 + ldw r11, (sp, 0) + ldw r12, (sp, 4) + ldw r13, (sp, 8) + addi sp, 16 + jbr .L_copy_by_byte + .L2: + ldw r5, (r3, 0) + GET_FRONT_BITS r1 r12 + mov r11, r1 + mov r1, r5 + GET_AFTER_BITS r5 r13 + or r5, r11 + stw r5, (r7, 0) + subi r4, 4 + addi r3, 4 + addi r7, 4 + jbr .L_not_aligned_and_len_less_16bytes + +#else /* __CSKYABIV2__ */ + /* If len less than 4 bytes */ + mov r3, r0 + cmplti r2, 4 + jbt .L_copy_by_byte + + mov r12, r0 + andi r12, 3 + /* If dest is not 4 bytes aligned */ + bnez r12, .L_dest_not_aligned +.L0: + /* If dest is aligned, but src is not aligned */ + mov r12, r1 + andi r12, 3 + bnez r12, .L_dest_aligned_but_src_not_aligned + + /* dest and src are all aligned */ + cmplti r2, 16 + /* If len less than 16 bytes */ + jbt .L_aligned_and_len_less_16bytes + + /* src and dst are all aligned, and len > 16 bytes */ +.L_aligned_and_len_larger_16bytes: + ldw r18, (r1, 0) + ldw r19, (r1, 4) + ldw r20, (r1, 8) + ldw r21, (r1, 12) + stw r18, (r3, 0) + stw r19, (r3, 4) + stw r20, (r3, 8) + stw r21, (r3, 12) + subi r2, 16 + addi r1, 16 + addi r3, 16 + cmplti r2, 16 + jbf .L_aligned_and_len_larger_16bytes + +.L_aligned_and_len_less_16bytes: + cmplti r2, 4 + jbt .L_copy_by_byte + ldw r18, (r1, 0) + stw r18, (r3, 0) + subi r2, 4 + addi r1, 4 + addi r3, 4 + jbr .L_aligned_and_len_less_16bytes + + /* len less than 4 bytes */ +.L_copy_by_byte: + cmpnei r2, 0 + jbf .L_return + ldb r18, (r1, 0) + stb r18, (r3, 0) + subi r2, 1 + addi r1, 1 + addi r3, 1 + jbr .L_copy_by_byte + +.L_return: + rts + + /* If dest is not aligned, just copying some bytes makes the dest align. + After that, we judge whether the src is aligned. */ + + /* consider overlapped case */ +.L_dest_not_aligned: + rsub r13, r1, r3 + abs r13, r13 + cmplt r13, r2 + jbt .L_copy_by_byte + +.L1: + /* makes the dest align. */ + ldb r18, (r1, 0) + stb r18, (r3, 0) + addi r12, 1 + subi r2, 1 + addi r1, 1 + addi r3, 1 + cmpnei r12, 4 + jbt .L1 + cmplti r2, 4 + jbt .L_copy_by_byte + /* judge whether the src is aligned. */ + jbf .L0 + + /* consider overlapped case */ +.L_dest_aligned_but_src_not_aligned: + rsub r13, r1, r3 + abs r13, r13 + cmplt r13, r2 + jbt .L_copy_by_byte + + bclri r1, 0 + bclri r1, 1 + ldw r18, (r1, 0) + addi r1, 4 + + /* r12 is used to store the misaligned bits */ + movi r13, 8 + mult r13, r12 + mov r24, r13 + rsubi r13, 32 + mov r25, r13 + + cmplti r2, 16 + jbt .L_not_aligned_and_len_less_16bytes + +.L_not_aligned_and_len_larger_16bytes: + ldw r20, (r1, 0) + ldw r21, (r1, 4) + ldw r22, (r1, 8) + ldw r23, (r1, 12) + + /* little or big endian? */ + GET_FRONT_BITS r18 r24 + mov r19, r20 + GET_AFTER_BITS r20 r25 + or r20, r18 + + GET_FRONT_BITS r19 r24 + mov r18, r21 + GET_AFTER_BITS r21 r13 + or r21, r19 + + GET_FRONT_BITS r18 r24 + mov r19, r22 + GET_AFTER_BITS r22 r25 + or r22, r18 + + GET_FRONT_BITS r19 r24 + mov r18, r23 + GET_AFTER_BITS r23 r25 + or r23, r19 + + stw r20, (r3, 0) + stw r21, (r3, 4) + stw r22, (r3, 8) + stw r23, (r3, 12) + subi r2, 16 + addi r1, 16 + addi r3, 16 + cmplti r2, 16 + jbf .L_not_aligned_and_len_larger_16bytes + + .L_not_aligned_and_len_less_16bytes: + cmplti r2, 4 + jbf .L2 + /* r12 is used to stored the misaligned bits */ + rsubi r12, 4 + /* initial the position */ + subu r1, r12 + jbr .L_copy_by_byte + .L2: + ldw r21, (r1, 0) + GET_FRONT_BITS r18 r24 + mov r19, r18 + mov r18, r21 + GET_AFTER_BITS r21 r25 + or r21, r19 + stw r21, (r3, 0) + subi r2, 4 + addi r1, 4 + addi r3, 4 + jbr .L_not_aligned_and_len_less_16bytes + +# endif +END(memcpy) + +libc_hidden_builtin_def(memcpy) +.weak memcpy diff --git a/sysdeps/csky/memusage.h b/sysdeps/csky/memusage.h new file mode 100644 index 0000000..5d29e59 --- /dev/null +++ b/sysdeps/csky/memusage.h @@ -0,0 +1,20 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; }) + +#include diff --git a/sysdeps/csky/setjmp.S b/sysdeps/csky/setjmp.S new file mode 100644 index 0000000..ed5e27e --- /dev/null +++ b/sysdeps/csky/setjmp.S @@ -0,0 +1,113 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include + +ENTRY(setjmp) + movi a1, 1 + br __sigsetjmp +END(setjmp) + +ENTRY(_setjmp) + movi a1, 0 + br __sigsetjmp +END(_setjmp) + +libc_hidden_def (_setjmp) + +ENTRY(__sigsetjmp) + mov a2, a0 + /* Save registers */ + +#ifdef __CSKYABIV2__ +#ifdef PTR_MANGLE + PTR_MANGLE(t0, sp, a3) + stw t0, (a2, 0) + PTR_MANGLE2(t0, lr, a3) + stw t0, (a2, 4) +#else + stw sp, (a2, 0) + stw lr, (a2, 4) +#endif + stw r4, (a2, 8) + stw r5, (a2, 12) + stw r6, (a2, 16) + stw r7, (a2, 20) + stw r8, (a2, 24) + stw r9, (a2, 28) + stw r10, (a2, 32) + stw r11, (a2, 36) + stw r16, (a2, 40) + stw r17, (a2, 44) + stw r26, (a2, 48) + stw r27, (a2, 52) + stw r28, (a2, 56) + stw r29, (a2, 60) + stw r30, (a2, 64) + stw r31, (a2, 68) + addi a2, 72 +#else +#ifdef PTR_MANGLE + mov r6, sp + PTR_MANGLE(r6, r6, a3) + stw r6, (a2, 0) + mov r6, lr + PTR_MANGLE2(r6, r6, a3) + stw r6, (a2, 4) +#else + stw sp, (a2, 0) + stw lr, (a2, 4) +#endif + stw r8, (a2, 8) + stw r9, (a2, 12) + stw r10, (a2, 16) + stw r11, (a2, 20) + stw r12, (a2, 24) + stw r13, (a2, 28) + stw r14, (a2, 32) + addi a2, 32 + addi a2, 4 +#endif + +#ifdef __PIC__ +# ifdef __CSKYABIV2__ + grs t1, .Lgetpc +.Lgetpc: + lrw t0, .Lgetpc@GOTPC + addu t1, t0 + lrw a2, __sigjmp_save@PLT + ldr.w a2, (t1, a2 << 0) + jmp a2 +# else + mov a3, lr + bsr .Lgetpc +.Lgetpc: + lrw r7, .Lgetpc@GOTPC + addu r7, lr + lrw a2, __sigjmp_save@PLT + addu r7, a2 + ldw r7, (r7) + mov lr, a3 + jmp r7 +# endif /* !__CSKYABIV2__ */ +#else + jmpi __sigjmp_save +#endif /* !__PIC__ */ + +END(__sigsetjmp) + +hidden_def (__sigsetjmp) diff --git a/sysdeps/csky/start.S b/sysdeps/csky/start.S new file mode 100644 index 0000000..f592c22 --- /dev/null +++ b/sysdeps/csky/start.S @@ -0,0 +1,133 @@ +/* Startup code compliant to the ELF C-SKY ABI. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* We need to call: + __libc_start_main (int (*main) (int, char **, char **), int argc, + char **argv, void (*init) (void), void (*fini) (void), + void (*rtld_fini) (void), void *stack_end) +*/ + +#include + +.text + .globl _start + .type _start,@function +_start: + /* Clear the frame pointer and link register since this is the outermost frame. */ + movi lr, 0 + /* Pop argc off the stack and save a pointer to argv */ + ldw a1, (sp, 0) /* __libc_start_main(arg1): argc */ + addi sp, 4 + mov a2, sp /* __libc_start_main(arg1): argv */ + + subi sp, 4 + /* Push stack limit */ + stw a2, (sp, 0) +#ifdef __CSKYABIV2__ + /* Push rtld_fini */ + subi sp, 4 + stw a0, (sp, 0) +#else + mov r7, a0 +#endif + +#ifdef SHARED + subi sp,8 + stw lr,(sp,0) + stw gb,(sp,4) + bsr .Lgetpc +.Lgetpc: + lrw gb, .Lgetpc@GOTPC + addu gb, lr + lrw a3, __libc_csu_fini@GOT + addu a3, gb + ldw a3, (a3) +# ifdef __CSKYABIV2__ + subi sp, 4 + stw a3, (sp,0) +# else + mov a4, a3 +# endif /* !__CSKYABIV2__ */ + lrw a3, __libc_csu_init@GOT + addu a3, gb + ldw a3,(a3,0) +# ifdef __CSKYABIV2__ + lrw t0, main@GOT + addu t0, gb + ldw a0,(t0,0) + lrw t1,__libc_start_main@PLT + addu t1, gb + ldw t1, (t1, 0) + jsr t1 +# else + lrw a0, main@GOT + addu a0, gb + ldw a0,(a0,0) + lrw r13,__libc_start_main@PLT + addu r13, gb + ldw r13, (r13, 0) + jsr r13 +# endif /* !__CSKYABIV2__ */ + ldw lr,(sp,0) + ldw gb,(sp,4) + addi sp, 8 +#else /* !SHARED */ +# ifdef __CSKYABIV2__ + /* Fetch address of __libc_csu_fini */ + lrw a0, __libc_csu_fini + /* Push __libc_csu_fini */ + subi sp,4 + stw a0, (sp,0) +# else + lrw a4, __libc_csu_fini +# endif /* !__CSKYABIV2__ */ + /* Set up the other arguments in registers */ + lrw a0, main + lrw a3, __libc_csu_init + /* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */ + /* Let the libc call main and exit with its return code. */ + jsri __libc_start_main +#endif /* !SHARED */ + + /* should never get here....*/ + jsri abort + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/sysdeps/csky/strcmp.S b/sysdeps/csky/strcmp.S new file mode 100644 index 0000000..9bfe32f --- /dev/null +++ b/sysdeps/csky/strcmp.S @@ -0,0 +1,336 @@ +/* The assembly function for string compare. C-SKY version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include "macro.S" + +ENTRY(strcmp) +#ifndef __CSKYABIV2__ + mov r6, r2 + + or r2, r3 + andi r2, 0x3 + cmpnei r2, 0x0 /* d or s is aligned ?*/ + bt 4f /* if not aligned, goto 4f*/ + 1: /* if aligned, load word each time.*/ + ldw r2, (r6, 0) + ldw r7, (r3, 0) + cmpne r2, r7 + bt 1f /* if d[i] != s[i], goto 1f */ + tstnbz r2 /* if d[i] == s[i], check if d or s is at the end. */ + bf 3f /* if at the end, goto 3f (finish comparing) */ + + ldw r2, (r6, 4) + ldw r7, (r3, 4) + cmpne r2, r7 + bt 1f + tstnbz r2 + bf 3f + + ldw r2, (r6, 8) + ldw r7, (r3, 8) + cmpne r2, r7 + bt 1f + tstnbz r2 + bf 3f + + ldw r2, (r6, 12) + ldw r7, (r3, 12) + cmpne r2, r7 + bt 1f + tstnbz r2 + bf 3f + + ldw r2, (r6, 16) + ldw r7, (r3, 16) + cmpne r2, r7 + bt 1f + tstnbz r2 + bf 3f + + ldw r2, (r6, 20) + ldw r7, (r3, 20) + cmpne r2, r7 + bt 1f + tstnbz r2 + bf 3f + + ldw r2, (r6, 24) + ldw r7, (r3, 24) + cmpne r2, r7 + bt 1f + tstnbz r2 + bf 3f + + ldw r2, (r6, 28) + ldw r7, (r3, 28) + cmpne r2, r7 + bt 1f + tstnbz r2 + bf 3f + + addi r6, 32 + addi r3, 32 + br 1b + +#ifdef __CSKYBE__ + /* d[i] != s[i] in word, so we check byte 0 ? */ +1: + xtrb0 r1, r2 + mov r4, r1 + xtrb0 r1, r7 + cmpne r4, r1 + bt 2f + cmpnei r4, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb1 r1, r2 + mov r4, r1 + xtrb1 r1, r7 + cmpne r4, r1 + bt 2f + cmpnei r4, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb2 r1, r2 + mov r4, r1 + xtrb2 r1, r7 + cmpne r4, r1 + bt 2f + cmpnei r4, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb3 r1, r2 + mov r4, r1 + xtrb3 r1, r7 + +#else /* little endian */ + /* d[i] != s[i] in word, so we check byte 0 ? */ +1: + xtrb3 r1, r2 + mov r4, r1 + xtrb3 r1, r7 + cmpne r4, r1 + bt 2f + cmpnei r4, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb2 r1, r2 + mov r4, r1 + xtrb2 r1, r7 + cmpne r4, r1 + bt 2f + cmpnei r4, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb1 r1, r2 + mov r4, r1 + xtrb1 r1, r7 + cmpne r4, r1 + bt 2f + cmpnei r4, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb0 r1, r2 + mov r4, r1 + xtrb0 r1, r7 + +#endif + /* get the result when d[i] != s[i] */ +2: + subu r4, r1 + mov r2, r4 + jmp r15 + + /* return when d[i] == s[i] */ +3: + subu r2, r7 + jmp r15 + + /* cmp when d or s is not aligned */ +4: + ldb r2, (r6,0) + ldb r7, (r3, 0) + cmpne r2, r7 + bt 3b + addi r3, 1 + addi r6, 1 + cmpnei r2, 0 + bt 4b + jmp r15 +# else /* __CSKYABIV2__ */ + mov a3, a0 + + or a0, a1 + andi a0, 0x3 + M_BNEZ a0, 4f + 1: + /* if aligned, load word each time. */ + ldw a0, (a3, 0) + ldw t0, (a1, 0) + /* if d[i] != s[i], goto 1f */ + M_BNE a0, t0, 1f + /* if d[i] == s[i], check if d or s is at the end. */ + tstnbz a0 + /* if at the end, goto 3f (finish comparing) */ + bf 3f +#if defined ( __ck802__ ) + addi a3, 4 + addi a1, 4 +#else + ldw a0, (a3, 4) + ldw t0, (a1, 4) + M_BNE a0, t0, 1f + tstnbz a0 + bf 3f + + ldw a0, (a3, 8) + ldw t0, (a1, 8) + M_BNE a0, t0, 1f + tstnbz a0 + bf 3f + + ldw a0, (a3, 12) + ldw t0, (a1, 12) + M_BNE a0, t0, 1f + tstnbz a0 + bf 3f + + ldw a0, (a3, 16) + ldw t0, (a1, 16) + M_BNE a0, t0, 1f + tstnbz a0 + bf 3f + + ldw a0, (a3, 20) + ldw t0, (a1, 20) + M_BNE a0, t0, 1f + tstnbz a0 + bf 3f + + ldw a0, (a3, 24) + ldw t0, (a1, 24) + M_BNE a0, t0, 1f + tstnbz a0 + bf 3f + + ldw a0, (a3, 28) + ldw t0, (a1, 28) + M_BNE a0, t0, 1f + tstnbz a0 + bf 3f + + addi a3, 32 + addi a1, 32 +#endif + br 1b + +# ifdef __CSKYBE__ + /* d[i] != s[i] in word, so we check byte 0 ? */ +1: + xtrb0 t1, a0 + mov a2, t1 + xtrb0 t1, t0 + M_BNE a2, t1, 2f + cmpnei a2, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb1 t1, a0 + mov a2, t1 + xtrb1 t1, t0 + M_BNE a2, t1, 2f + cmpnei a2, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb2 t1, a0 + mov a2, t1 + xtrb2 t1, t0 + M_BNE a2, t1, 2f + cmpnei a2, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb3 t1, a0 + mov a2, t1 + xtrb3 t1, t0 + +# else /* !__CSKYBE__ */ + /* d[i] != s[i] in word, so we check byte 0 ? */ +1: + xtrb3 t1, a0 + mov a2, t1 + xtrb3 t1, t0 + M_BNE a2, t1, 2f + cmpnei a2, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb2 t1, a0 + mov a2, t1 + xtrb2 t1, t0 + M_BNE a2, t1, 2f + cmpnei a2, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb1 t1, a0 + mov a2, t1 + xtrb1 t1, t0 + M_BNE a2, t1, 2f + cmpnei a2, 0 + bf 2f + + /* d[i] != s[i] in word, so we check byte 1 ? */ + xtrb0 t1, a0 + mov a2, t1 + xtrb0 t1, t0 + +# endif /* !__CSKYBE__ */ + /* get the result when d[i] != s[i] */ +2: + subu a2, t1 + mov a0, a2 + jmp r15 + + /* return when d[i] == s[i] */ +3: + subu a0, t0 + jmp r15 + + /* cmp when d or s is not aligned */ +4: + ldb a0, (a3,0) + ldb t0, (a1, 0) + M_BNE a0, t0, 3b + addi a1, 1 + addi a3, 1 + M_BNEZ a0, 4b + jmp r15 +#endif /* __CSKYABIV2__ */ +END(strcmp) + +libc_hidden_def(strcmp) +.weak strcmp diff --git a/sysdeps/csky/strcpy.S b/sysdeps/csky/strcpy.S new file mode 100644 index 0000000..e757aeb --- /dev/null +++ b/sysdeps/csky/strcpy.S @@ -0,0 +1,273 @@ +/* The assembly function for string copy. C-SKY version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include "macro.S" + +ENTRY(strcpy) +#ifndef __CSKYABIV2__ + mov r6, r2 + mov r7, r3 + or r7, r6 + andi r7, 3 + cmpnei r7, 0 + bf 2f +1: + ldb r5, (r3) + stb r5, (r6) + addi r3, 1 + addi r6, 1 + cmpnei r5, 0 + bt 1b +1: + jmp r15 + +2: + ldw r5, (r3) + tstnbz r5 + bf 10f + stw r5, (r6) + + ldw r5, (r3, 4) + tstnbz r5 + bf 3f + stw r5, (r6, 4) + + ldw r5, (r3, 8) + tstnbz r5 + bf 4f + stw r5, (r6, 8) + + ldw r5, (r3, 12) + tstnbz r5 + bf 5f + stw r5, (r6, 12) + + ldw r5, (r3, 16) + tstnbz r5 + bf 6f + stw r5, (r6, 16) + + ldw r5, (r3, 20) + tstnbz r5 + bf 7f + stw r5, (r6, 20) + + ldw r5, (r3, 24) + tstnbz r5 + bf 8f + stw r5, (r6, 24) + + ldw r5, (r3, 28) + tstnbz r5 + bf 9f + stw r5, (r6, 28) + + addi r6, 32 + addi r3, 32 + br 2b + +3: + addi r6, 4 + br 10f + +4: + addi r6, 8 + br 10f + +5: + addi r6, 12 + br 10f + +6: + addi r6, 16 + br 10f + +7: + addi r6, 20 + br 10f + +8: + addi r6, 24 + br 10f + +9: + addi r6, 28 + +10: +# ifdef __CSKYBE__ + xtrb0 r1, r5 + stb r1, (r6) + cmpnei r1, 0 + bf 5f + xtrb1 r1, r5 + stb r1, (r6, 1) + cmpnei r1, 0 + bf 5f + xtrb2 r1, r5 + stb r1, (r6, 2 ) + cmpnei r1, 0 + bf 5f + stw r5, (r6) + +# else /* !__CSKYBE__ */ + xtrb3 r1, r5 + stb r1, (r6) + cmpnei r1, 0 + bf 5f + xtrb2 r1, r5 + stb r1, (r6, 1) + cmpnei r1, 0 + bf 5f + xtrb1 r1, r5 + stb r1, (r6, 2) + cmpnei r1, 0 + bf 5f + stw r5, (r6) +# endif /* !__CSKYBE__ */ +5: + jmp r15 +#else /* __CSKYABIV2__ */ + mov a3, a0 + or a2, a1, a3 + andi t0, a2, 3 + M_BEZ t0, 2f + mov t0, a1 +1: + ld.b a2, (t0) + stb a2, (a3) + addi t0, t0, 1 + addi a3, a3, 1 + M_BNEZ a2, 1b + + jmp r15 + +2: +# if defined (__ck802__) + ldw a2, (a1) + tstnbz a2 + bf 11f + stw a2, (a3) + addi a3, 4 + addi a1, 4 + br 2b +# else /* !__ck802__ */ + ldw a2, (a1) + tstnbz a2 + bf 11f + stw a2, (a3) + + ldw a2, (a1, 4) + tstnbz a2 + bf 4f + stw a2, (a3, 4) + + ldw a2, (a1, 8) + tstnbz a2 + bf 5f + stw a2, (a3, 8) + + ldw a2, (a1, 12) + tstnbz a2 + bf 6f + stw a2, (a3, 12) + + ldw a2, (a1, 16) + tstnbz a2 + bf 7f + stw a2, (a3, 16) + + ldw a2, (a1, 20) + tstnbz a2 + bf 8f + stw a2, (a3, 20) + + ldw a2, (a1, 24) + tstnbz a2 + bf 9f + stw a2, (a3, 24) + + ldw a2, (a1, 28) + tstnbz a2 + bf 10f + stw a2, (a3, 28) + + addi a3, 32 + addi a1, 32 + br 2b + + +4: + addi a3, 4 + br 11f + +5: + addi a3, 8 + br 11f + +6: + addi a3, 12 + br 11f + +7: + addi a3, 16 + br 11f + +8: + addi a3, 20 + br 11f + +9: + addi a3, 24 + br 11f + +10: + addi a3, 28 +# endif /* !__ck802__ */ +11: +# ifdef __CSKYBE__ + xtrb0 t0, a2 + st.b t0, (a3) + M_BEZ t0, 5f + xtrb1 t0, a2 + st.b t0, (a3, 1) + M_BEZ t0, 5f + xtrb2 t0, a2 + st.b t0, (a3, 2 ) + M_BEZ t0, 5f + stw a2, (a3) +# else + xtrb3 t0, a2 + st.b t0, (a3) + M_BEZ t0, 5f + xtrb2 t0, a2 + st.b t0, (a3, 1) + M_BEZ t0, 5f + xtrb1 t0, a2 + st.b t0, (a3, 2) + M_BEZ t0, 5f + stw a2, (a3) +# endif /* !__CSKYBE__ */ +5: + jmp r15 + +#endif /* !__CSKYABIV2__ */ +END(strcpy) + +libc_hidden_def(strcpy) +.weak strcpy diff --git a/sysdeps/csky/sys/ucontext.h b/sysdeps/csky/sys/ucontext.h new file mode 100644 index 0000000..fd06308 --- /dev/null +++ b/sysdeps/csky/sys/ucontext.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +/* System V/ckcore ABI compliant context switching support. */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include +#include + +#include +#include + +/* Type for general register. */ +typedef int greg_t; + +/* Number of general registers. */ +#if (__CSKY__ == 2) +#define NGREG 34 +#else +#define NGREG 18 +#endif + +/* Container for all general registers. */ +typedef greg_t gregset_t[NGREG]; + +/* Number of each register is the `gregset_t' array. */ +enum +{ + R_R0 = 0, +#define R_R0 R_R0 + R_R1 = 1, +#define R_R1 R_R1 + R_R2 = 2, +#define R_R2 R_R2 + R_R3 = 3, +#define R_R3 R_R3 + R_R4 = 4, +#define R_R4 R_R4 + R_R5 = 5, +#define R_R5 R_R5 + R_R6 = 6, +#define R_R6 R_R6 + R_R7 = 7, +#define R8R7 R_R7 + R_R8 = 8, +#define R_R8 R_R8 + R_R9 = 9, +#define R_R9 R_R9 + R_R10 = 10, +#define R_R10 R_R10 + R_R11 = 11, +#define R_R11 R_R11 + R_R12 = 12, +#define R_R12 R_R12 + R_R13 = 13, +#define R_R13 R_R13 + R_R14 = 14, +#define R_R14 R_R14 + R_R15 = 15, +#define R_R15 R_R15 +#if (__CSKY__ == 2) + R_SR = 32, +#define R_SR R_SR + R_PC = 33, +#define R_PC R_PC +#else + R_SR = 16, +#define R_SR R_SR + R_PC = 17, +#define R_PC R_PC +#endif +}; + +/* Structure to describe FPU registers. */ +typedef struct fpregset +{ + unsigned long fesr; /* fpu exception status reg */ + unsigned long fsr; /* fpu status reg, nothing in CPU_CSKYV2 */ + unsigned long fp[32]; /* fpu general regs */ +} fpregset_t; + +/* Context to describe whole processor state. */ +typedef struct +{ + gregset_t gregs; + fpregset_t fpregs; +} mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext +{ + unsigned long int uc_flags; + struct ucontext *uc_link; + __sigset_t uc_sigmask; + stack_t uc_stack; + mcontext_t uc_mcontext; /* struct sigcontext */ + long int uc_filler[201]; +} ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/sysdeps/csky/sysdep.h b/sysdeps/csky/sysdep.h new file mode 100644 index 0000000..527fc57 --- /dev/null +++ b/sysdeps/csky/sysdep.h @@ -0,0 +1,45 @@ +/* Assembler macros for C-SKY. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +#ifndef __CSKYABIV2__ +# define CSKY_ABIV1 +#else +# define CSKY_ABIV2 +#endif + +#ifdef __ASSEMBLER__ + +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +/* Define an entry point visible from C. */ +#define ENTRY(name) \ + .globl name; \ + .type name,@function; \ + .align 4; \ + name##:; \ + cfi_startproc; \ + +#undef END +#define END(name) \ + cfi_endproc; \ + ASM_SIZE_DIRECTIVE(name) + +#endif diff --git a/sysdeps/csky/tls-macros.h b/sysdeps/csky/tls-macros.h new file mode 100644 index 0000000..3e9976b --- /dev/null +++ b/sysdeps/csky/tls-macros.h @@ -0,0 +1,106 @@ +/* Macros for accessing thread-local storage. C-SKY version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifdef __CSKYABIV2__ +# define TLS_LE(x) \ + ({ int *__result; \ + extern void * __read_tp (void); \ + void *tp = __read_tp (); \ + __asm__ ("lrw %0, " #x "@TPOFF; " \ + "add %0, %1, %0; " \ + : "=&r" (__result) : "r" (tp)); \ + __result; }) + +# define TLS_IE(x) \ + ({ int *__result; \ + extern void * __read_tp (void); \ + void *tp = __read_tp (); \ + __asm__ ("grs a1, 1f;" \ + "1: lrw %0, " #x "@GOTTPOFF;" \ + "ldr.w %0, (a1, %0 << 0);" \ + "add %0, %1, %0; " \ + : "=&r" (__result): "r" (tp) : "a1" ); \ + __result; }) + +# define TLS_LD(x) \ + ({ char *__result; \ + int __offset; \ + extern void *__tls_get_addr (void *); \ + __asm__ ("grs a1, 1f;" \ + "1: lrw %0, " #x "@TLSLDM32;" \ + "add %0, a1, %0; " \ + : "=r" (__result) : : "a1"); \ + __result = (char *)__tls_get_addr (__result); \ + __asm__ ("lrw %0, " #x "@TLSLDO32; " \ + : "=r" (__offset)); \ + (int *) (__result + __offset); }) + +# define TLS_GD(x) \ + ({ int *__result; \ + extern void *__tls_get_addr (void *); \ + __asm__ ("grs a1, 1f;" \ + "1: lrw %0, " #x "@TLSGD32; " \ + "add %0, a1, %0; " \ + : "=r" (__result) : : "a1" ); \ + (int *)__tls_get_addr (__result); }) + +#else +# define TLS_LE(x) \ + ({ int *__result; \ + extern void * __read_tp (void); \ + void *tp = __read_tp (); \ + __asm__ ("lrw %0, " #x "@TPOFF\n\t " \ + "add %0, %1\n\t" \ + : "=&r" (__result) : "r" (tp)); \ + __result; }) + +# define TLS_IE(x) \ + ({ int *__result; \ + extern void * __read_tp (void); \ + void *tp = __read_tp (); \ + __asm__ ("bsr 1f\n\t" \ + "1: lrw %0, " #x "@GOTTPOFF\n\t" \ + "add %0, r15\n\t" \ + "ldw %0, (%0, 0)\n\t" \ + "add %0, %1\n\t" \ + : "=&r" (__result): "r" (tp) : "r15" ); \ + __result; }) + +# define TLS_LD(x) \ + ({ char *__result; \ + int __offset; \ + extern void *__tls_get_addr (void *); \ + __asm__ ("bsr 1f\n\t" \ + "1: lrw %0, " #x "@TLSLDM32\n\t" \ + "add %0, r15\n\t" \ + : "=r" (__result) : : "r15"); \ + __result = (char *)__tls_get_addr (__result); \ + __asm__ ("lrw %0, " #x "@TLSLDO32\n\t " \ + : "=r" (__offset)); \ + (int *) (__result + __offset); }) + +# define TLS_GD(x) \ + ({ int *__result; \ + extern void *__tls_get_addr (void *); \ + __asm__ ("bsr 1f;" \ + "1: lrw %0, " #x "@TLSGD32\n\t " \ + "add %0, r15\n\t" \ + : "=r" (__result) : : "r15" ); \ + (int *)__tls_get_addr (__result); }) + +#endif diff --git a/sysdeps/unix/csky/abiv2_sysdep.S b/sysdeps/unix/csky/abiv2_sysdep.S new file mode 100644 index 0000000..33cc2e8 --- /dev/null +++ b/sysdeps/unix/csky/abiv2_sysdep.S @@ -0,0 +1,63 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#define _ERRNO_H +#include +#include + +#if !IS_IN (rtld) +#include /* Defines RTLD_PRIVATE_ERRNO. */ +#endif + +#include + +#undef syscall_error +__syscall_error: +#if !IS_IN (rtld) + mov a1, a0 + csky_read_tp + + grs t1, .Lgetpc1 +.Lgetpc1: + lrw t0, errno@gottpoff + add t1, t1, t0 + ldw t1, (t1) + add t1, a0 + stw a1, (t1) + bmaski a0, 0 + jsr r15 +#elif RTLD_PRIVATE_ERRNO +#ifdef __PIC__ + grs t1, .Lgetpc2 +.Lgetpc2: + lrw t0, .Lgetpc2@GOTPC + addu t1, t1, t0 + lrw t0, rtld_errno@PLT + ldr.w t0, (t1, t0 << 0) +#else + lrw t0, rtld_errno +#endif + stw a0, (t0) + bmaski a0, 0 + jsr r15 +#else +#error "Unsupported non-TLS case" +#endif + +#undef __syscall_error +END (__syscall_error) diff --git a/sysdeps/unix/csky/sysdep.S b/sysdeps/unix/csky/sysdep.S new file mode 100644 index 0000000..520bf59 --- /dev/null +++ b/sysdeps/unix/csky/sysdep.S @@ -0,0 +1,74 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifdef __CSKYABIV2__ +#include "abiv2_sysdep.S" +#else + +#include +#define _ERRNO_H +#include +#include + +#if IS_IN (rtld) +#include /* Defines RTLD_PRIVATE_ERRNO. */ +#endif + +#include + +#undef syscall_error +__syscall_error: +#if !IS_IN (rtld) +#ifdef __PIC__ + mov r7, r15 + mov r1, r2 + csky_read_tp + + bsr .Lgetpc1 +.Lgetpc1: + lrw r5, errno@gottpoff + add r5, r15 + ldw r5, (r5) + add r5, r2 + stw r1, (r5) + bmaski r2, 0 + jsr r7 +#endif +#elif RTLD_PRIVATE_ERRNO +#ifdef __PIC__ + mov r7, r15 + bsr .Lgetpc2 +.Lgetpc2: + lrw r6, .Lgetpc2@GOTPC + addu r6, r15 + lrw r5, rtld_errno@PLT + addu r5, r6 + ldw r5, (r5) +#else + lrw r5, rtld_errno +#endif + stw r2, (r5) + bmaski r2, 0 + jsr r7 +#else +#error "Unsupported non-TLS case" +#endif + +#undef __syscall_error +END (__syscall_error) + +#endif /* __CSKYABIV2__*/ diff --git a/sysdeps/unix/csky/sysdep.h b/sysdeps/unix/csky/sysdep.h new file mode 100644 index 0000000..fb13f3d --- /dev/null +++ b/sysdeps/unix/csky/sysdep.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include +#include + +#ifdef __ASSEMBLER__ + +#define ret \ + jmp r15; + +#endif