[RFC,v1,10/16] RISC-V: The ABI implementation for the 32-bit

Message ID ed0eb363a3e0dd78a25ab3db4a08f9df20edf087.1561177967.git.alistair.francis@wdc.com
State New, archived
Headers

Commit Message

Alistair Francis June 22, 2019, 4:37 a.m. UTC
  From: Zong Li <zongbox@gmail.com>

This patch adds the ABI implementation about 32 bit version. It contains
the Linux-specific and RISC-V architecture code, I've collected here.

2018-11-29  Zong Li  <zong@andestech.com>

	* sysdeps/riscv/bits/wordsize.h: Supprt rv32.
	* sysdeps/riscv/nptl/bits/pthreadtypes-arch.h: Likewise.
	* sysdeps/riscv/sfp-machine.h: Likewise.
	* sysdeps/riscv/sys/asm.h: Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h: New file.
	* sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c: Likewise.
---
 ChangeLog                                     |  9 +++
 sysdeps/riscv/bits/wordsize.h                 |  4 +-
 sysdeps/riscv/nptl/bits/pthreadtypes-arch.h   | 25 ++++++-
 sysdeps/riscv/sfp-machine.h                   | 27 ++++++-
 sysdeps/riscv/sys/asm.h                       |  5 +-
 .../sysv/linux/riscv/rv32/jmp_buf-macros.h    | 53 ++++++++++++++
 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++
 7 files changed, 189 insertions(+), 4 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
  

Comments

Arnd Bergmann June 23, 2019, 7:41 p.m. UTC | #1
On Sat, Jun 22, 2019 at 6:47 AM Alistair Francis
<alistair.francis@wdc.com> wrote:

>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++

Why is this file architecture specific? It seems everything else just uses
#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
Is your code different from that version?

     Arnd
  
Alistair Francis June 23, 2019, 11:43 p.m. UTC | #2
On Sun, Jun 23, 2019 at 12:41 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Sat, Jun 22, 2019 at 6:47 AM Alistair Francis
> <alistair.francis@wdc.com> wrote:
>
> >  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++
>
> Why is this file architecture specific? It seems everything else just uses
> #include <sysdeps/unix/sysv/linux/i386/lockf64.c>
> Is your code different from that version?

I don't know, I didn't change or look too deeply into these patches.
I'll check when I'm at work tomorrow.

Alistair

>
>      Arnd
  
Palmer Dabbelt June 24, 2019, 2:49 a.m. UTC | #3
On Sun, 23 Jun 2019 12:41:20 PDT (-0700), Arnd Bergmann wrote:
> On Sat, Jun 22, 2019 at 6:47 AM Alistair Francis
> <alistair.francis@wdc.com> wrote:
>
>>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++
>
> Why is this file architecture specific? It seems everything else just uses
> #include <sysdeps/unix/sysv/linux/i386/lockf64.c>
> Is your code different from that version?

As part of the code review it was indicated that we shouldn't #include C files
but should instead duplicate them.  At the time it was exactly the same, we
should scrutinize any differences as that was months ago.
  
Arnd Bergmann June 24, 2019, 9:51 a.m. UTC | #4
On Mon, Jun 24, 2019 at 4:49 AM Palmer Dabbelt <palmer@sifive.com> wrote:
>
> On Sun, 23 Jun 2019 12:41:20 PDT (-0700), Arnd Bergmann wrote:
> > On Sat, Jun 22, 2019 at 6:47 AM Alistair Francis
> > <alistair.francis@wdc.com> wrote:
> >
> >>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++
> >
> > Why is this file architecture specific? It seems everything else just uses
> > #include <sysdeps/unix/sysv/linux/i386/lockf64.c>
> > Is your code different from that version?
>
> As part of the code review it was indicated that we shouldn't #include C files
> but should instead duplicate them.  At the time it was exactly the same, we
> should scrutinize any differences as that was months ago.

I would expect that you would want it to be consistent across architectures
as well: so either replace all the other #include versions with direct copies,
or move the file into a more generic location that avoids the #include if you
can't add another one any more.

      Arnd
  
Adhemerval Zanella June 24, 2019, 11:58 a.m. UTC | #5
On 24/06/2019 06:51, Arnd Bergmann wrote:
> On Mon, Jun 24, 2019 at 4:49 AM Palmer Dabbelt <palmer@sifive.com> wrote:
>>
>> On Sun, 23 Jun 2019 12:41:20 PDT (-0700), Arnd Bergmann wrote:
>>> On Sat, Jun 22, 2019 at 6:47 AM Alistair Francis
>>> <alistair.francis@wdc.com> wrote:
>>>
>>>>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++
>>>
>>> Why is this file architecture specific? It seems everything else just uses
>>> #include <sysdeps/unix/sysv/linux/i386/lockf64.c>
>>> Is your code different from that version?
>>
>> As part of the code review it was indicated that we shouldn't #include C files
>> but should instead duplicate them.  At the time it was exactly the same, we
>> should scrutinize any differences as that was months ago.
> 
> I would expect that you would want it to be consistent across architectures
> as well: so either replace all the other #include versions with direct copies,
> or move the file into a more generic location that avoids the #include if you
> can't add another one any more.
> 
>       Arnd
> 

Since e442e40de5646e93bf31ace3e0c5159085a7259b glibc lock{64} is based on
fcntl{64}.  And sysdeps/unix/sysv/linux/fcntl{64}.c should already call
__NR_fcntl64 for the required cases.  So why do you need to add an arch
specific lock64 implementation here?
  
Alistair Francis June 24, 2019, 11:05 p.m. UTC | #6
On Mon, Jun 24, 2019 at 4:58 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 24/06/2019 06:51, Arnd Bergmann wrote:
> > On Mon, Jun 24, 2019 at 4:49 AM Palmer Dabbelt <palmer@sifive.com> wrote:
> >>
> >> On Sun, 23 Jun 2019 12:41:20 PDT (-0700), Arnd Bergmann wrote:
> >>> On Sat, Jun 22, 2019 at 6:47 AM Alistair Francis
> >>> <alistair.francis@wdc.com> wrote:
> >>>
> >>>>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++
> >>>
> >>> Why is this file architecture specific? It seems everything else just uses
> >>> #include <sysdeps/unix/sysv/linux/i386/lockf64.c>
> >>> Is your code different from that version?
> >>
> >> As part of the code review it was indicated that we shouldn't #include C files
> >> but should instead duplicate them.  At the time it was exactly the same, we
> >> should scrutinize any differences as that was months ago.
> >
> > I would expect that you would want it to be consistent across architectures
> > as well: so either replace all the other #include versions with direct copies,
> > or move the file into a more generic location that avoids the #include if you
> > can't add another one any more.
> >
> >       Arnd
> >
>
> Since e442e40de5646e93bf31ace3e0c5159085a7259b glibc lock{64} is based on
> fcntl{64}.  And sysdeps/unix/sysv/linux/fcntl{64}.c should already call
> __NR_fcntl64 for the required cases.  So why do you need to add an arch
> specific lock64 implementation here?

Yep, this isn't required any more, I have removed it.

Alistair
  
Palmer Dabbelt June 25, 2019, 3:37 a.m. UTC | #7
On Mon, 24 Jun 2019 02:51:25 PDT (-0700), Arnd Bergmann wrote:
> On Mon, Jun 24, 2019 at 4:49 AM Palmer Dabbelt <palmer@sifive.com> wrote:
>>
>> On Sun, 23 Jun 2019 12:41:20 PDT (-0700), Arnd Bergmann wrote:
>> > On Sat, Jun 22, 2019 at 6:47 AM Alistair Francis
>> > <alistair.francis@wdc.com> wrote:
>> >
>> >>  sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c  | 70 +++++++++++++++++++
>> >
>> > Why is this file architecture specific? It seems everything else just uses
>> > #include <sysdeps/unix/sysv/linux/i386/lockf64.c>
>> > Is your code different from that version?
>>
>> As part of the code review it was indicated that we shouldn't #include C files
>> but should instead duplicate them.  At the time it was exactly the same, we
>> should scrutinize any differences as that was months ago.
>
> I would expect that you would want it to be consistent across architectures
> as well: so either replace all the other #include versions with direct copies,
> or move the file into a more generic location that avoids the #include if you
> can't add another one any more.

Here's the original review, for context:
https://marc.info/?l=glibc-alpha&m=151407510809658&w=2 .  As far as I
understand it, the goal here was explicitly to avoid shared code.  I'd be happy
to change this tree wide if it's OK with everyone else, as I generally dislike
code duplication.
  

Patch

diff --git a/ChangeLog b/ChangeLog
index 73d07ab159..2ee614e093 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,15 @@ 
 	* sysdeps/unix/sysv/linux/riscv/ldconfig.h (LD_SO_ABI): Support rv32.
 	* sysdeps/unix/sysv/linux/riscv/dl-cache.h (add_system_dir): Add
 	libraries path for rv32.
+	* sysdeps/unix/sysv/linux/riscv/ldconfig.h (LD_SO_ABI): Support rv32.
+	* sysdeps/unix/sysv/linux/riscv/dl-cache.h (add_system_dir): Add
+	libraries path for rv32.
+	* sysdeps/riscv/bits/wordsize.h: Supprt rv32.
+	* sysdeps/riscv/nptl/bits/pthreadtypes-arch.h: Likewise.
+	* sysdeps/riscv/sfp-machine.h: Likewise.
+	* sysdeps/riscv/sys/asm.h: Likewise.
+	* sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h: New file.
+	* sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c: Likewise.
 
 2019-06-20  Dmitry V. Levin  <ldv@altlinux.org>
 	    Florian Weimer  <fweimer@redhat.com>
diff --git a/sysdeps/riscv/bits/wordsize.h b/sysdeps/riscv/bits/wordsize.h
index 0b8cd8fefd..f10be0144c 100644
--- a/sysdeps/riscv/bits/wordsize.h
+++ b/sysdeps/riscv/bits/wordsize.h
@@ -25,5 +25,7 @@ 
 #if __riscv_xlen == 64
 # define __WORDSIZE_TIME64_COMPAT32 1
 #else
-# error "rv32i-based targets are not supported"
+# define __WORDSIZE_TIME64_COMPAT32 0
+# define __WORDSIZE32_SIZE_ULONG    0
+# define __WORDSIZE32_PTRDIFF_LONG  0
 #endif
diff --git a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
index e3fecc3208..4b08f7c692 100644
--- a/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
+++ b/sysdeps/riscv/nptl/bits/pthreadtypes-arch.h
@@ -32,7 +32,15 @@ 
 # define __SIZEOF_PTHREAD_BARRIER_T 		32
 # define __SIZEOF_PTHREAD_BARRIERATTR_T 	 4
 #else
-# error "rv32i-based systems are not supported"
+# define __SIZEOF_PTHREAD_ATTR_T 		32
+# define __SIZEOF_PTHREAD_MUTEX_T 		32
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 		 4
+# define __SIZEOF_PTHREAD_COND_T 		48
+# define __SIZEOF_PTHREAD_CONDATTR_T 		 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 		48
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 		 8
+# define __SIZEOF_PTHREAD_BARRIER_T 		20
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 	 4
 #endif
 
 #define __PTHREAD_COMPAT_PADDING_MID
@@ -56,11 +64,26 @@  struct __pthread_rwlock_arch_t
   unsigned int __writers_futex;
   unsigned int __pad3;
   unsigned int __pad4;
+#if __riscv_xlen == 64
   int __cur_writer;
   int __shared;
   unsigned long int __pad1;
   unsigned long int __pad2;
   unsigned int __flags;
+#else
+# if __BYTE_ORDER == __BIG_ENDIAN
+  unsigned char __pad1;
+  unsigned char __pad2;
+  unsigned char __shared;
+  unsigned char __flags;
+# else
+  unsigned char __flags;
+  unsigned char __shared;
+  unsigned char __pad1;
+  unsigned char __pad2;
+# endif
+  int __cur_writer;
+#endif
 };
 
 #define __PTHREAD_RWLOCK_ELISION_EXTRA 		0
diff --git a/sysdeps/riscv/sfp-machine.h b/sysdeps/riscv/sfp-machine.h
index fa0b8fa41a..98e1f84370 100644
--- a/sysdeps/riscv/sfp-machine.h
+++ b/sysdeps/riscv/sfp-machine.h
@@ -22,7 +22,32 @@ 
 
 #if __riscv_xlen == 32
 
-# error "rv32i-based targets are not supported"
+# 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_MUL_MEAT_DW_S(R, X, Y)					\
+  _FP_MUL_MEAT_DW_1_wide (_FP_WFRACBITS_S, R, X, Y, umul_ppmm)
+# define _FP_MUL_MEAT_DW_D(R, X, Y)					\
+  _FP_MUL_MEAT_DW_2_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
+# define _FP_MUL_MEAT_DW_Q(R, X, Y)					\
+  _FP_MUL_MEAT_DW_4_wide (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
+
+# define _FP_DIV_MEAT_S(R, X, Y)	_FP_DIV_MEAT_1_udiv_norm (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
+# define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+# define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
 
 #else
 
diff --git a/sysdeps/riscv/sys/asm.h b/sysdeps/riscv/sys/asm.h
index b8f90a44ce..7ea34afd6d 100644
--- a/sysdeps/riscv/sys/asm.h
+++ b/sysdeps/riscv/sys/asm.h
@@ -26,7 +26,10 @@ 
 # 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
 #else
 # error __riscv_xlen must equal 32 or 64
 #endif
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
new file mode 100644
index 0000000000..e0042b9f01
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/jmp_buf-macros.h
@@ -0,0 +1,53 @@ 
+/* jump buffer constants for RISC-V
+   Copyright (C) 2017-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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Produced by this program:
+
+   #include <stdio.h>
+   #include <unistd.h>
+   #include <setjmp.h>
+   #include <stddef.h>
+
+   int main (int argc, char **argv)
+   {
+       printf ("#define JMP_BUF_SIZE %d\n", sizeof (jmp_buf));
+       printf ("#define JMP_BUF_ALIGN %d\n", __alignof__ (jmp_buf));
+       printf ("#define SIGJMP_BUF_SIZE %d\n", sizeof (sigjmp_buf));
+       printf ("#define SIGJMP_BUF_ALIGN %d\n", __alignof__ (sigjmp_buf));
+       printf ("#define MASK_WAS_SAVED_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __mask_was_saved));
+       printf ("#define SAVED_MASK_OFFSET %d\n", offsetof (struct __jmp_buf_tag, __saved_mask));
+   } */
+
+#if defined __riscv_float_abi_soft
+# define JMP_BUF_SIZE 188
+# define JMP_BUF_ALIGN 4
+# define SIGJMP_BUF_SIZE 188
+# define SIGJMP_BUF_ALIGN 4
+# define MASK_WAS_SAVED_OFFSET 56
+# define SAVED_MASK_OFFSET 60
+#elif defined __riscv_float_abi_double
+# define JMP_BUF_SIZE 288
+# define JMP_BUF_ALIGN 8
+# define SIGJMP_BUF_SIZE 288
+# define SIGJMP_BUF_ALIGN 8
+# define MASK_WAS_SAVED_OFFSET 152
+# define SAVED_MASK_OFFSET 156
+#else
+# error "Unknown RISC-V floating-point ABI"
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c b/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
new file mode 100644
index 0000000000..8a17c13cbe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
@@ -0,0 +1,70 @@ 
+/* Copyright (C) 1994-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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sysdep.h>
+
+/* lockf is a simplified interface to fcntl's locking facilities.  */
+
+int
+lockf64 (int fd, int cmd, off64_t len64)
+{
+  struct flock64 fl64;
+  int cmd64;
+  int result;
+
+  memset ((char *) &fl64, '\0', sizeof (fl64));
+  fl64.l_whence = SEEK_CUR;
+  fl64.l_start = 0;
+  fl64.l_len = len64;
+
+  switch (cmd)
+    {
+    case F_TEST:
+      /* Test the lock: return 0 if FD is unlocked or locked by this process;
+	 return -1, set errno to EACCES, if another process holds the lock.  */
+      fl64.l_type = F_RDLCK;
+      INTERNAL_SYSCALL_DECL (err);
+      result = INTERNAL_SYSCALL (fcntl64, err, 3, fd, F_GETLK64, &fl64);
+      if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
+	return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result,
+									  err));
+      if (fl64.l_type == F_UNLCK || fl64.l_pid == __getpid ())
+        return 0;
+      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EACCES);
+    case F_ULOCK:
+      fl64.l_type = F_UNLCK;
+      cmd64 = F_SETLK64;
+      break;
+    case F_LOCK:
+      fl64.l_type = F_WRLCK;
+      cmd64 = F_SETLKW64;
+      break;
+    case F_TLOCK:
+      fl64.l_type = F_WRLCK;
+      cmd64 = F_SETLK64;
+      break;
+
+    default:
+      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+    }
+  return INLINE_SYSCALL (fcntl64, 3, fd, cmd64, &fl64);
+}