diff options
Diffstat (limited to 'libc/sysdeps/linux/riscv64')
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/atomic.h | 170 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/uClibc_page.h | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/wordsize.h | 3 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/cache.c | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/clone.S | 8 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/crt1.S | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/jmpbuf-unwind.h | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/setjmp.S | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/sys/asm.h | 6 |
10 files changed, 196 insertions, 17 deletions
diff --git a/libc/sysdeps/linux/riscv64/bits/atomic.h b/libc/sysdeps/linux/riscv64/bits/atomic.h new file mode 100644 index 000000000..8bf6abfac --- /dev/null +++ b/libc/sysdeps/linux/riscv64/bits/atomic.h @@ -0,0 +1,170 @@ +/* Copyright (C) 2003-2017 Free Software Foundation, Inc. + + 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 + <http://www.gnu.org/licenses/>. */ + +#ifndef _RISCV64_ATOMIC_MACHINE_H +#define _RISCV64_ATOMIC_MACHINE_H 1 + +#define typeof __typeof__ + +#include <stdint.h> +#include <sysdep.h> + +typedef int8_t atomic8_t; +typedef int16_t atomic16_t; +typedef int32_t atomic32_t; +typedef int64_t atomic64_t; + +typedef uint8_t uatomic8_t; +typedef uint16_t uatomic16_t; +typedef uint32_t uatomic32_t; +typedef uint64_t uatomic64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 1 + +/* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ + +# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + + +/* Compare and exchange with "acquire" semantics, ie barrier after. */ + +# define atomic_compare_and_exchange_bool_acq(mem, new, old) \ + __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +# define atomic_compare_and_exchange_val_acq(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +/* Compare and exchange with "release" semantics, ie barrier before. */ + +# define atomic_compare_and_exchange_val_rel(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_RELEASE) + + +/* Atomic exchange (without compare). */ + +# define __arch_exchange_8_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_16_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_32_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_64_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define atomic_exchange_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE) + +# define atomic_exchange_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE) + + +/* Atomically add value and return the previous (unincremented) value. */ + +# define __arch_exchange_and_add_8_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_16_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_32_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_64_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define atomic_exchange_and_add_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_ACQUIRE) + +# define atomic_exchange_and_add_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_RELEASE) + +/* Barrier macro. */ +#define atomic_full_barrier() __sync_synchronize() + +#endif diff --git a/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h b/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h index 3b8361442..63b17770d 100644 --- a/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h @@ -5,7 +5,7 @@ #ifndef _BITS_UCLIBC_ARCH_FEATURES_H #define _BITS_UCLIBC_ARCH_FEATURES_H -#undef __UCLIBC_ABORT_INSTRUCTION__ +#define __UCLIBC_ABORT_INSTRUCTION__ "unimp" /* can your target use syscall6() for mmap ? */ #define __UCLIBC_MMAP_HAS_6_ARGS__ @@ -13,7 +13,7 @@ /* does your target use statx */ #undef __UCLIBC_HAVE_STATX__ -#define __UCLIBC_SYSCALL_ALIGN_64BIT__ +#undef __UCLIBC_SYSCALL_ALIGN_64BIT__ /* does your target have a broken create_module() ? */ #define __UCLIBC_BROKEN_CREATE_MODULE__ diff --git a/libc/sysdeps/linux/riscv64/bits/uClibc_page.h b/libc/sysdeps/linux/riscv64/bits/uClibc_page.h index 4792d370f..7282638ba 100644 --- a/libc/sysdeps/linux/riscv64/bits/uClibc_page.h +++ b/libc/sysdeps/linux/riscv64/bits/uClibc_page.h @@ -21,7 +21,7 @@ #define _UCLIBC_PAGE_H /* PAGE_SHIFT determines the page size -- in this case 4096 */ -#define PAGE_SHIFT 13 +#define PAGE_SHIFT 12 #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) diff --git a/libc/sysdeps/linux/riscv64/bits/wordsize.h b/libc/sysdeps/linux/riscv64/bits/wordsize.h index 67a16ba62..1fc649aad 100644 --- a/libc/sysdeps/linux/riscv64/bits/wordsize.h +++ b/libc/sysdeps/linux/riscv64/bits/wordsize.h @@ -25,5 +25,6 @@ #if __riscv_xlen == 64 # define __WORDSIZE_TIME64_COMPAT32 1 #else -# error "rv32i-based targets are not supported" +# define __WORDSIZE_TIME64_COMPAT32 1 +// # warning "rv32i-based targets are experimental" #endif diff --git a/libc/sysdeps/linux/riscv64/cache.c b/libc/sysdeps/linux/riscv64/cache.c index 216b333f3..aa99a2a0d 100644 --- a/libc/sysdeps/linux/riscv64/cache.c +++ b/libc/sysdeps/linux/riscv64/cache.c @@ -19,6 +19,10 @@ #include <atomic.h> #include <sys/syscall.h> +#ifndef __NR_riscv_flush_icache +#define __NR_riscv_flush_icache 259 +#endif + typedef int (*func_type) (void *, void *, unsigned long int); static int diff --git a/libc/sysdeps/linux/riscv64/clone.S b/libc/sysdeps/linux/riscv64/clone.S index f7684c88d..315de2ac8 100644 --- a/libc/sysdeps/linux/riscv64/clone.S +++ b/libc/sysdeps/linux/riscv64/clone.S @@ -29,6 +29,9 @@ .text LEAF (clone) + /* Align stack to a 128-bit boundary as per RISC-V ABI. */ + andi a1,a1,ALMASK + /* Sanity check arguments. */ beqz a0,L (invalid) /* No NULL function pointers. */ beqz a1,L (invalid) /* No NULL stack pointers. */ @@ -57,7 +60,7 @@ L (invalid): li a0, -EINVAL /* Something bad happened -- no child created. */ L (error): - j __syscall_error + tail __syscall_error END (clone) /* Load up the arguments to the function. Put this block of code in @@ -66,6 +69,9 @@ L (error): ENTRY (__thread_start) L (thread_start): + .cfi_label .Ldummy + cfi_undefined (ra) + /* Restore the arg for user's function. */ REG_L a1,0(sp) /* Function pointer. */ REG_L a0,SZREG(sp) /* Argument pointer. */ diff --git a/libc/sysdeps/linux/riscv64/crt1.S b/libc/sysdeps/linux/riscv64/crt1.S index 15aa0763c..5e33046d4 100644 --- a/libc/sysdeps/linux/riscv64/crt1.S +++ b/libc/sysdeps/linux/riscv64/crt1.S @@ -45,9 +45,6 @@ .globl _start .type _start,%function - .weak _init - .weak _fini - _start: call .Lload_gp mv a5, a0 /* rtld_fini. */ @@ -55,9 +52,9 @@ _start: la a0, main REG_L a1, 0(sp) /* argc. */ addi a2, sp, SZREG /* argv. */ + mv a3, zero + mv a4, zero andi sp, sp, ALMASK /* Align stack. */ - lla a3, _init - lla a4, _fini mv a6, sp /* stack_end. */ tail __uClibc_main@plt diff --git a/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h b/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h index 2e5f37f10..fb5d65ddd 100644 --- a/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h @@ -23,8 +23,8 @@ /* 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_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) ((jmpbuf)[0].__sp)) #define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) @@ -33,9 +33,6 @@ static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) { uintptr_t sp = regs[0].__sp; -#ifdef PTR_DEMANGLE - PTR_DEMANGLE (sp); -#endif return sp; } diff --git a/libc/sysdeps/linux/riscv64/setjmp.S b/libc/sysdeps/linux/riscv64/setjmp.S index 4cdb8e9c3..100a0bd78 100644 --- a/libc/sysdeps/linux/riscv64/setjmp.S +++ b/libc/sysdeps/linux/riscv64/setjmp.S @@ -20,7 +20,7 @@ ENTRY (_setjmp) li a1, 0 - j __sigsetjmp + j HIDDEN_JUMPTARGET (__sigsetjmp) END (_setjmp) ENTRY (setjmp) li a1, 1 diff --git a/libc/sysdeps/linux/riscv64/sys/asm.h b/libc/sysdeps/linux/riscv64/sys/asm.h index ddb84b683..3c94c9a70 100644 --- a/libc/sysdeps/linux/riscv64/sys/asm.h +++ b/libc/sysdeps/linux/riscv64/sys/asm.h @@ -26,7 +26,11 @@ # define REG_S sd # define REG_L ld #elif __riscv_xlen == 32 -# error "rv32i-based targets are not supported" +# define PTRLOG 2 +# define SZREG 4 +# define REG_S sw +# define REG_L lw +// # warning "rv32i-based targets are experimental" #else # error __riscv_xlen must equal 32 or 64 #endif |