Use C version of multi3 for RVE support.
authorKito Cheng <kito.cheng@gmail.com>
Wed, 13 Dec 2017 06:25:06 +0000 (06:25 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Wed, 13 Dec 2017 06:25:06 +0000 (22:25 -0800)
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

libgcc/ChangeLog
libgcc/config/riscv/multi3.S [deleted file]
libgcc/config/riscv/multi3.c [new file with mode: 0644]
libgcc/config/riscv/t-elf

index dd27fbb..b795621 100644 (file)
@@ -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 (file)
index a3b89c6..0000000
+++ /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 (file)
index 0000000..3606a5f
--- /dev/null
@@ -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;
+}
index 01d5eba..dbc8f85 100644 (file)
@@ -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 \