aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@gmail.com>2017-12-13 06:25:06 +0000
committerJim Wilson <wilson@gcc.gnu.org>2017-12-12 22:25:06 -0800
commitb8d7e076ed0cf5fde5f5d875e4145d63317a6180 (patch)
treef456399ff4a729c9702a67f54499856a3869b3cd /libgcc
parent9e921ddb437b0ce607d234caa08423addef5ff2e (diff)
downloadgcc-b8d7e076ed0cf5fde5f5d875e4145d63317a6180.zip
gcc-b8d7e076ed0cf5fde5f5d875e4145d63317a6180.tar.gz
gcc-b8d7e076ed0cf5fde5f5d875e4145d63317a6180.tar.bz2
Use C version of multi3 for RVE support.
libgcc/ * config/riscv/t-elf: Use multi3.c instead of multi3.S. * config/riscv/multi3.c: New file. * config/riscv/multi3.S: Remove. From-SVN: r255598
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog6
-rw-r--r--libgcc/config/riscv/multi3.S90
-rw-r--r--libgcc/config/riscv/multi3.c86
-rw-r--r--libgcc/config/riscv/t-elf2
4 files changed, 93 insertions, 91 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index dd27fbb..b795621 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-12 Kito Cheng <kito.cheng@gmail.com>
+
+ * config/riscv/t-elf: Use multi3.c instead of multi3.S.
+ * config/riscv/multi3.c: New file.
+ * config/riscv/multi3.S: Remove.
+
2017-12-08 Jim Wilson <jimw@sifive.com>
* config/riscv/div.S: Use FUNC_* macros.
diff --git a/libgcc/config/riscv/multi3.S b/libgcc/config/riscv/multi3.S
deleted file mode 100644
index a3b89c6..0000000
--- a/libgcc/config/riscv/multi3.S
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Integer multiplication routines for RISC-V.
-
- Copyright (C) 2016-2017 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-Under Section 7 of GPL version 3, you are granted additional
-permissions described in the GCC Runtime Library Exception, version
-3.1, as published by the Free Software Foundation.
-
-You should have received a copy of the GNU General Public License and
-a copy of the GCC Runtime Library Exception along with this program;
-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-<http://www.gnu.org/licenses/>. */
-
-#include "riscv-asm.h"
-
- .text
- .align 2
-
-#if __riscv_xlen == 32
-/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */
-# define __multi3 __muldi3
-#endif
-
-FUNC_BEGIN (__multi3)
-
-#if __riscv_xlen == 32
-/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */
-# define __muldi3 __mulsi3
-#endif
-
-/* We rely on the fact that __muldi3 doesn't clobber the t-registers. */
-
- mv t0, ra
- mv t5, a0
- mv a0, a1
- mv t6, a3
- mv a1, t5
- mv a4, a2
- li a5, 0
- li t2, 0
- li t4, 0
-.L1:
- add a6, t2, a1
- andi t3, a4, 1
- slli a7, a5, 1
- slti t1, a1, 0
- srli a4, a4, 1
- add a5, t4, a5
- beqz t3, .L2
- sltu t3, a6, t2
- mv t2, a6
- add t4, t3, a5
-.L2:
- slli a1, a1, 1
- or a5, t1, a7
- bnez a4, .L1
- beqz a0, .L3
- mv a1, a2
- call __muldi3
- add t4, t4, a0
-.L3:
- beqz t6, .L4
- mv a1, t6
- mv a0, t5
- call __muldi3
- add t4, t4, a0
-.L4:
- mv a0, t2
- mv a1, t4
- jr t0
-
-#if __riscv_xlen == 32
-/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */
-# undef __muldi3
-#endif
-
-FUNC_END (__multi3)
-
diff --git a/libgcc/config/riscv/multi3.c b/libgcc/config/riscv/multi3.c
new file mode 100644
index 0000000..3606a5f
--- /dev/null
+++ b/libgcc/config/riscv/multi3.c
@@ -0,0 +1,86 @@
+/* Multiplication two double word integers for RISC-V.
+
+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "libgcc_tm.h"
+#define LIBGCC2_UNITS_PER_WORD (__riscv_xlen / 8)
+
+#include "libgcc2.h"
+
+#if __riscv_xlen == 32
+/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */
+# define __multi3 __muldi3
+#endif
+
+DWtype
+__multi3 (DWtype u, DWtype v)
+{
+ const DWunion uu = {.ll = u};
+ const DWunion vv = {.ll = v};
+ DWunion w;
+ UWtype u_low = uu.s.low;
+ UWtype v_low = vv.s.low;
+ UWtype u_low_msb;
+ UWtype w_low = 0;
+ UWtype new_w_low;
+ UWtype w_high = 0;
+ UWtype w_high_tmp = 0;
+ UWtype w_high_tmp2x;
+ UWtype carry;
+
+ /* Calculate low half part of u and v, and get a UDWtype result just like
+ what __umulsidi3 do. */
+ do
+ {
+ new_w_low = w_low + u_low;
+ w_high_tmp2x = w_high_tmp << 1;
+ w_high_tmp += w_high;
+ if (v_low & 1)
+ {
+ carry = new_w_low < w_low;
+ w_low = new_w_low;
+ w_high = carry + w_high_tmp;
+ }
+ u_low_msb = (u_low >> ((sizeof (UWtype) * 8) - 1));
+ v_low >>= 1;
+ u_low <<= 1;
+ w_high_tmp = u_low_msb | w_high_tmp2x;
+ }
+ while (v_low);
+
+ w.s.low = w_low;
+ w.s.high = w_high;
+
+ if (uu.s.high)
+ w.s.high = w.s.high + __muluw3(vv.s.low, uu.s.high);
+
+ if (vv.s.high)
+ w.s.high += __muluw3(uu.s.low, vv.s.high);
+
+ return w.ll;
+}
diff --git a/libgcc/config/riscv/t-elf b/libgcc/config/riscv/t-elf
index 01d5eba..dbc8f85 100644
--- a/libgcc/config/riscv/t-elf
+++ b/libgcc/config/riscv/t-elf
@@ -1,6 +1,6 @@
LIB2ADD += $(srcdir)/config/riscv/save-restore.S \
$(srcdir)/config/riscv/muldi3.S \
- $(srcdir)/config/riscv/multi3.S \
+ $(srcdir)/config/riscv/multi3.c \
$(srcdir)/config/riscv/div.S \
$(srcdir)/config/riscv/atomic.c \