diff mbox

RISC-V: Don't built 64-bit multilibs on 32-bit targets

Message ID 20170429015927.22205-1-palmer@dabbelt.com
State New
Headers show

Commit Message

Palmer Dabbelt April 29, 2017, 1:59 a.m. UTC
We've been telling people that "riscv32-*" and "riscv64-*" are exactly
the same toolchain aside from defaults for "-march" and "-mabi", but it
appears we were lying.  As far as I can tell, binutils doesn't support
64-bit targets when it has been configured for a 32-bit target.  This
seems to be an upstream limitation that we can't fix in the RISC-V port.
This means that building the toolchain with "--with-arch=rv32i
--enable-multilib" will fail when building the 64-bit multilibs.

This patch adds two new multilib target fragments that don't add the
64-bit multilibs.  This fixes the build, but has the disadvantage of
making our 32-bit and 64-bit toolchains very different.

gcc/ChanegLog:

2017-04-28  Palmer Dabbelt  <palmer@dabbelt.com>

        * config/riscv/t-elf-multilib32: New file.
        * config/riscv/t-linux-multilib32: Likewise
        * config.gcc: Select between the 32-bit and 64-bit multilib
        configurations based on the target XLEN.
---
 gcc/ChangeLog                                      |  7 +++++++
 gcc/config.gcc                                     | 12 +++++++++--
 gcc/config/riscv/t-elf-multilib32                  | 22 ++++++++++++++++++++
 .../riscv/{t-elf-multilib => t-elf-multilib64}     |  0
 gcc/config/riscv/t-linux-multilib32                | 24 ++++++++++++++++++++++
 .../riscv/{t-linux-multilib => t-linux-multilib64} |  0
 6 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 gcc/config/riscv/t-elf-multilib32
 rename gcc/config/riscv/{t-elf-multilib => t-elf-multilib64} (100%)
 create mode 100644 gcc/config/riscv/t-linux-multilib32
 rename gcc/config/riscv/{t-linux-multilib => t-linux-multilib64} (100%)

Comments

Richard Biener April 29, 2017, 2:22 p.m. UTC | #1
On April 29, 2017 3:59:27 AM GMT+02:00, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>We've been telling people that "riscv32-*" and "riscv64-*" are exactly
>the same toolchain aside from defaults for "-march" and "-mabi", but it
>appears we were lying.  As far as I can tell, binutils doesn't support
>64-bit targets when it has been configured for a 32-bit target.  This
>seems to be an upstream limitation that we can't fix in the RISC-V
>port.
>This means that building the toolchain with "--with-arch=rv32i
>--enable-multilib" will fail when building the 64-bit multilibs.
>
>This patch adds two new multilib target fragments that don't add the
>64-bit multilibs.  This fixes the build, but has the disadvantage of
>making our 32-bit and 64-bit toolchains very different.

PowerPC for 32bit can use powerpc64 as target and enable 32bit code-gen by default at configure time.  Maybe this is an option for riscv as well.

Richard.

>gcc/ChanegLog:
>
>2017-04-28  Palmer Dabbelt  <palmer@dabbelt.com>
>
>        * config/riscv/t-elf-multilib32: New file.
>        * config/riscv/t-linux-multilib32: Likewise
>        * config.gcc: Select between the 32-bit and 64-bit multilib
>        configurations based on the target XLEN.
>---
> gcc/ChangeLog                                      |  7 +++++++
> gcc/config.gcc                                     | 12 +++++++++--
>gcc/config/riscv/t-elf-multilib32                  | 22
>++++++++++++++++++++
> .../riscv/{t-elf-multilib => t-elf-multilib64}     |  0
>gcc/config/riscv/t-linux-multilib32                | 24
>++++++++++++++++++++++
> .../riscv/{t-linux-multilib => t-linux-multilib64} |  0
> 6 files changed, 63 insertions(+), 2 deletions(-)
> create mode 100644 gcc/config/riscv/t-elf-multilib32
> rename gcc/config/riscv/{t-elf-multilib => t-elf-multilib64} (100%)
> create mode 100644 gcc/config/riscv/t-linux-multilib32
>rename gcc/config/riscv/{t-linux-multilib => t-linux-multilib64} (100%)
>
>diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>index 977517e..2ad14ae 100644
>--- a/gcc/ChangeLog
>+++ b/gcc/ChangeLog
>@@ -1,3 +1,10 @@
>+2017-04-28  Palmer Dabbelt  <palmer@dabbelt.com>
>+
>+	* config/riscv/t-elf-multilib32: New file.
>+	* config/riscv/t-linux-multilib32: Likewise
>+	* config.gcc: Select between the 32-bit and 64-bit multilib
>+	configurations based on the target XLEN.
>+
> 2017-04-28  Jan Hubicka  <hubicka@ucw.cz>
> 
> 	* ipa-cp.c (perform_estimation_of_a_value): Turn time to sreal.
>diff --git a/gcc/config.gcc b/gcc/config.gcc
>index b8bb4d6..4d142b4 100644
>--- a/gcc/config.gcc
>+++ b/gcc/config.gcc
>@@ -2018,10 +2018,14 @@ microblaze*-*-elf)
> 	tmake_file="${tmake_file} microblaze/t-microblaze"
>         ;;
> riscv*-*-linux*)
>+	case "${target}" in
>+	riscv32-*) riscv_xlen=32 ;;
>+	riscv64-*) riscv_xlen=64 ;;
>+	esac
>	tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}
>riscv/linux.h"
> 	case "x${enable_multilib}" in
> 	xno) ;;
>-	xyes) tmake_file="${tmake_file} riscv/t-linux-multilib" ;;
>+	xyes) tmake_file="${tmake_file} riscv/t-linux-multilib${riscv_xlen}"
>;;
> 	*) echo "Unknown value for enable_multilib"; exit 1
> 	esac
> 	tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux"
>@@ -2032,10 +2036,14 @@ riscv*-*-linux*)
> 	gcc_cv_initfini_array=yes
> 	;;
> riscv*-*-elf*)
>+	case "${target}" in
>+	riscv32-*) riscv_xlen=32 ;;
>+	riscv64-*) riscv_xlen=64 ;;
>+	esac
> 	tm_file="elfos.h newlib-stdint.h ${tm_file} riscv/elf.h"
> 	case "x${enable_multilib}" in
> 	xno) ;;
>-	xyes) tmake_file="${tmake_file} riscv/t-elf-multilib" ;;
>+	xyes) tmake_file="${tmake_file} riscv/t-elf-multilib${riscv_xlen}" ;;
> 	*) echo "Unknown value for enable_multilib"; exit 1
> 	esac
> 	tmake_file="${tmake_file} riscv/t-riscv"
>diff --git a/gcc/config/riscv/t-elf-multilib32
>b/gcc/config/riscv/t-elf-multilib32
>new file mode 100644
>index 0000000..1f2928c
>--- /dev/null
>+++ b/gcc/config/riscv/t-elf-multilib32
>@@ -0,0 +1,22 @@
>+# This file was generated by multilib-generator with the command:
>+#  ./multilib-generator rv32i-ilp32--c rv32im-ilp32--c rv32iac-ilp32--
>rv32imac-ilp32-- rv32imafc-ilp32f-rv32imafdc-
>+MULTILIB_OPTIONS =
>march=rv32i/march=rv32ic/march=rv32im/march=rv32imc/march=rv32iac/march=rv32imac/march=rv32imafc/march=rv32imafdc/march=rv32gc
>mabi=ilp32/mabi=ilp32f
>+MULTILIB_DIRNAMES = rv32i \
>+rv32ic \
>+rv32im \
>+rv32imc \
>+rv32iac \
>+rv32imac \
>+rv32imafc \
>+rv32imafdc \
>+rv32gc ilp32 \
>+ilp32f
>+MULTILIB_REQUIRED = march=rv32i/mabi=ilp32 \
>+march=rv32im/mabi=ilp32 \
>+march=rv32iac/mabi=ilp32 \
>+march=rv32imac/mabi=ilp32 \
>+march=rv32imafc/mabi=ilp32f
>+MULTILIB_REUSE = march.rv32i/mabi.ilp32=march.rv32ic/mabi.ilp32 \
>+march.rv32im/mabi.ilp32=march.rv32imc/mabi.ilp32 \
>+march.rv32imafc/mabi.ilp32f=march.rv32imafdc/mabi.ilp32f \
>+march.rv32imafc/mabi.ilp32f=march.rv32gc/mabi.ilp32f
>diff --git a/gcc/config/riscv/t-elf-multilib
>b/gcc/config/riscv/t-elf-multilib64
>similarity index 100%
>rename from gcc/config/riscv/t-elf-multilib
>rename to gcc/config/riscv/t-elf-multilib64
>diff --git a/gcc/config/riscv/t-linux-multilib32
>b/gcc/config/riscv/t-linux-multilib32
>new file mode 100644
>index 0000000..7b130c0
>--- /dev/null
>+++ b/gcc/config/riscv/t-linux-multilib32
>@@ -0,0 +1,24 @@
>+# This file was generated by multilib-generator with the command:
>+#  ./multilib-generator
>rv32imac-ilp32-rv32ima,rv32imaf,rv32imafd,rv32imafc,rv32imafdc-
>rv32imafdc-ilp32d-rv32imafd-
>+MULTILIB_OPTIONS =
>march=rv32imac/march=rv32ima/march=rv32imaf/march=rv32imafd/march=rv32imafc/march=rv32imafdc/march=rv32g/march=rv32gc
>mabi=ilp32/mabi=ilp32d
>+MULTILIB_DIRNAMES = rv32imac \
>+rv32ima \
>+rv32imaf \
>+rv32imafd \
>+rv32imafc \
>+rv32imafdc \
>+rv32g \
>+rv32gc ilp32 \
>+ilp32d
>+MULTILIB_REQUIRED = march=rv32imac/mabi=ilp32 \
>+march=rv32imafdc/mabi=ilp32d
>+MULTILIB_REUSE = march.rv32imac/mabi.ilp32=march.rv32ima/mabi.ilp32 \
>+march.rv32imac/mabi.ilp32=march.rv32imaf/mabi.ilp32 \
>+march.rv32imac/mabi.ilp32=march.rv32imafd/mabi.ilp32 \
>+march.rv32imac/mabi.ilp32=march.rv32imafc/mabi.ilp32 \
>+march.rv32imac/mabi.ilp32=march.rv32imafdc/mabi.ilp32 \
>+march.rv32imac/mabi.ilp32=march.rv32g/mabi.ilp32 \
>+march.rv32imac/mabi.ilp32=march.rv32gc/mabi.ilp32 \
>+march.rv32imafdc/mabi.ilp32d=march.rv32imafd/mabi.ilp32d \
>+march.rv32imafdc/mabi.ilp32d=march.rv32gc/mabi.ilp32d \
>+march.rv32imafdc/mabi.ilp32d=march.rv32g/mabi.ilp32d
>diff --git a/gcc/config/riscv/t-linux-multilib
>b/gcc/config/riscv/t-linux-multilib64
>similarity index 100%
>rename from gcc/config/riscv/t-linux-multilib
>rename to gcc/config/riscv/t-linux-multilib64
Joseph Myers April 30, 2017, 11:38 p.m. UTC | #2
On Sat, 29 Apr 2017, Richard Biener wrote:

> On April 29, 2017 3:59:27 AM GMT+02:00, Palmer Dabbelt <palmer@dabbelt.com> wrote:
> >We've been telling people that "riscv32-*" and "riscv64-*" are exactly
> >the same toolchain aside from defaults for "-march" and "-mabi", but it
> >appears we were lying.  As far as I can tell, binutils doesn't support
> >64-bit targets when it has been configured for a 32-bit target.  This
> >seems to be an upstream limitation that we can't fix in the RISC-V
> >port.
> >This means that building the toolchain with "--with-arch=rv32i
> >--enable-multilib" will fail when building the 64-bit multilibs.
> >
> >This patch adds two new multilib target fragments that don't add the
> >64-bit multilibs.  This fixes the build, but has the disadvantage of
> >making our 32-bit and 64-bit toolchains very different.
> 
> PowerPC for 32bit can use powerpc64 as target and enable 32bit code-gen 
> by default at configure time.  Maybe this is an option for riscv as 
> well.

Specifically, in such cases the GCC configure option is 
--enable-target=all to enable 64-bit multilibs for a default-32-bit 
target, and the binutils/GDB configure option is --enable-64-bit-bfd.  But 
you can also make a binutils/GDB target include 64-bit support 
unconditionally without requiring --enable-64-bit-bfd.
Palmer Dabbelt May 1, 2017, 12:09 a.m. UTC | #3
On Sun, 30 Apr 2017 16:38:35 PDT (-0700), joseph@codesourcery.com wrote:
> On Sat, 29 Apr 2017, Richard Biener wrote:
>> On April 29, 2017 3:59:27 AM GMT+02:00, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>> >We've been telling people that "riscv32-*" and "riscv64-*" are exactly
>> >the same toolchain aside from defaults for "-march" and "-mabi", but it
>> >appears we were lying.  As far as I can tell, binutils doesn't support
>> >64-bit targets when it has been configured for a 32-bit target.  This
>> >seems to be an upstream limitation that we can't fix in the RISC-V
>> >port.
>> >This means that building the toolchain with "--with-arch=rv32i
>> >--enable-multilib" will fail when building the 64-bit multilibs.
>> >
>> >This patch adds two new multilib target fragments that don't add the
>> >64-bit multilibs.  This fixes the build, but has the disadvantage of
>> >making our 32-bit and 64-bit toolchains very different.
>>
>> PowerPC for 32bit can use powerpc64 as target and enable 32bit code-gen
>> by default at configure time.  Maybe this is an option for riscv as
>> well.

I think we already support this as well: you can build RISC-V with
"--target=riscv64-*" and "--with-isa=rv32g" which would build the 64-bit
toolchain that defaults to a 32-bit target.

We can (and pretty much always do, which is why this bug went unnoticed)
generate 32-bit objects using our 64-bit toolchain.  The bug here is that a LD
that's built with "--target=riscv32*" can't handle 64-bit ELFs

> Specifically, in such cases the GCC configure option is
> --enable-target=all to enable 64-bit multilibs for a default-32-bit
> target, and the binutils/GDB configure option is --enable-64-bit-bfd.  But
> you can also make a binutils/GDB target include 64-bit support
> unconditionally without requiring --enable-64-bit-bfd.

Do you happen to know how to do that (enable 64-bit BFDs in a 32-bit binutils
build)?  I'd prefer to have the riscv32 and riscv64 ports the same if possible,
but poked around a bit and couldn't find a way to do it.

If you just know some other port does this then I can probably figure it out
from there.  I'd hoped that submitting this patch would lead to someone telling
me a better way to do it :).
Joseph Myers May 1, 2017, 10:54 a.m. UTC | #4
On Mon, 1 May 2017, Palmer Dabbelt wrote:

> > Specifically, in such cases the GCC configure option is
> > --enable-target=all to enable 64-bit multilibs for a default-32-bit
> > target, and the binutils/GDB configure option is --enable-64-bit-bfd.  But
> > you can also make a binutils/GDB target include 64-bit support
> > unconditionally without requiring --enable-64-bit-bfd.
> 
> Do you happen to know how to do that (enable 64-bit BFDs in a 32-bit binutils
> build)?  I'd prefer to have the riscv32 and riscv64 ports the same if possible,
> but poked around a bit and couldn't find a way to do it.

Well, certainly you should add riscv_elf64_vec to targ_selvecs in 
config.bfd for the riscv32-*-* case.  Generally, check all the configure 
fragments used for riscv* to make sure they include both 32-bit and 64-bit 
support.
Palmer Dabbelt May 1, 2017, 8:41 p.m. UTC | #5
On Mon, 01 May 2017 03:54:49 PDT (-0700), joseph@codesourcery.com wrote:
> On Mon, 1 May 2017, Palmer Dabbelt wrote:
>
>> > Specifically, in such cases the GCC configure option is
>> > --enable-target=all to enable 64-bit multilibs for a default-32-bit
>> > target, and the binutils/GDB configure option is --enable-64-bit-bfd.  But
>> > you can also make a binutils/GDB target include 64-bit support
>> > unconditionally without requiring --enable-64-bit-bfd.
>>
>> Do you happen to know how to do that (enable 64-bit BFDs in a 32-bit binutils
>> build)?  I'd prefer to have the riscv32 and riscv64 ports the same if possible,
>> but poked around a bit and couldn't find a way to do it.
>
> Well, certainly you should add riscv_elf64_vec to targ_selvecs in
> config.bfd for the riscv32-*-* case.  Generally, check all the configure
> fragments used for riscv* to make sure they include both 32-bit and 64-bit
> support.

Thanks, I think that was all I was missing.  I've submitted a binutils patch,
so let's consider this matter closed in GCC land.
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 977517e..2ad14ae 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@ 
+2017-04-28  Palmer Dabbelt  <palmer@dabbelt.com>
+
+	* config/riscv/t-elf-multilib32: New file.
+	* config/riscv/t-linux-multilib32: Likewise
+	* config.gcc: Select between the 32-bit and 64-bit multilib
+	configurations based on the target XLEN.
+
 2017-04-28  Jan Hubicka  <hubicka@ucw.cz>
 
 	* ipa-cp.c (perform_estimation_of_a_value): Turn time to sreal.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index b8bb4d6..4d142b4 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2018,10 +2018,14 @@  microblaze*-*-elf)
 	tmake_file="${tmake_file} microblaze/t-microblaze"
         ;;
 riscv*-*-linux*)
+	case "${target}" in
+	riscv32-*) riscv_xlen=32 ;;
+	riscv64-*) riscv_xlen=64 ;;
+	esac
 	tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} riscv/linux.h"
 	case "x${enable_multilib}" in
 	xno) ;;
-	xyes) tmake_file="${tmake_file} riscv/t-linux-multilib" ;;
+	xyes) tmake_file="${tmake_file} riscv/t-linux-multilib${riscv_xlen}" ;;
 	*) echo "Unknown value for enable_multilib"; exit 1
 	esac
 	tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux"
@@ -2032,10 +2036,14 @@  riscv*-*-linux*)
 	gcc_cv_initfini_array=yes
 	;;
 riscv*-*-elf*)
+	case "${target}" in
+	riscv32-*) riscv_xlen=32 ;;
+	riscv64-*) riscv_xlen=64 ;;
+	esac
 	tm_file="elfos.h newlib-stdint.h ${tm_file} riscv/elf.h"
 	case "x${enable_multilib}" in
 	xno) ;;
-	xyes) tmake_file="${tmake_file} riscv/t-elf-multilib" ;;
+	xyes) tmake_file="${tmake_file} riscv/t-elf-multilib${riscv_xlen}" ;;
 	*) echo "Unknown value for enable_multilib"; exit 1
 	esac
 	tmake_file="${tmake_file} riscv/t-riscv"
diff --git a/gcc/config/riscv/t-elf-multilib32 b/gcc/config/riscv/t-elf-multilib32
new file mode 100644
index 0000000..1f2928c
--- /dev/null
+++ b/gcc/config/riscv/t-elf-multilib32
@@ -0,0 +1,22 @@ 
+# This file was generated by multilib-generator with the command:
+#  ./multilib-generator rv32i-ilp32--c rv32im-ilp32--c rv32iac-ilp32-- rv32imac-ilp32-- rv32imafc-ilp32f-rv32imafdc-
+MULTILIB_OPTIONS = march=rv32i/march=rv32ic/march=rv32im/march=rv32imc/march=rv32iac/march=rv32imac/march=rv32imafc/march=rv32imafdc/march=rv32gc mabi=ilp32/mabi=ilp32f
+MULTILIB_DIRNAMES = rv32i \
+rv32ic \
+rv32im \
+rv32imc \
+rv32iac \
+rv32imac \
+rv32imafc \
+rv32imafdc \
+rv32gc ilp32 \
+ilp32f
+MULTILIB_REQUIRED = march=rv32i/mabi=ilp32 \
+march=rv32im/mabi=ilp32 \
+march=rv32iac/mabi=ilp32 \
+march=rv32imac/mabi=ilp32 \
+march=rv32imafc/mabi=ilp32f
+MULTILIB_REUSE = march.rv32i/mabi.ilp32=march.rv32ic/mabi.ilp32 \
+march.rv32im/mabi.ilp32=march.rv32imc/mabi.ilp32 \
+march.rv32imafc/mabi.ilp32f=march.rv32imafdc/mabi.ilp32f \
+march.rv32imafc/mabi.ilp32f=march.rv32gc/mabi.ilp32f
diff --git a/gcc/config/riscv/t-elf-multilib b/gcc/config/riscv/t-elf-multilib64
similarity index 100%
rename from gcc/config/riscv/t-elf-multilib
rename to gcc/config/riscv/t-elf-multilib64
diff --git a/gcc/config/riscv/t-linux-multilib32 b/gcc/config/riscv/t-linux-multilib32
new file mode 100644
index 0000000..7b130c0
--- /dev/null
+++ b/gcc/config/riscv/t-linux-multilib32
@@ -0,0 +1,24 @@ 
+# This file was generated by multilib-generator with the command:
+#  ./multilib-generator rv32imac-ilp32-rv32ima,rv32imaf,rv32imafd,rv32imafc,rv32imafdc- rv32imafdc-ilp32d-rv32imafd-
+MULTILIB_OPTIONS = march=rv32imac/march=rv32ima/march=rv32imaf/march=rv32imafd/march=rv32imafc/march=rv32imafdc/march=rv32g/march=rv32gc mabi=ilp32/mabi=ilp32d
+MULTILIB_DIRNAMES = rv32imac \
+rv32ima \
+rv32imaf \
+rv32imafd \
+rv32imafc \
+rv32imafdc \
+rv32g \
+rv32gc ilp32 \
+ilp32d
+MULTILIB_REQUIRED = march=rv32imac/mabi=ilp32 \
+march=rv32imafdc/mabi=ilp32d
+MULTILIB_REUSE = march.rv32imac/mabi.ilp32=march.rv32ima/mabi.ilp32 \
+march.rv32imac/mabi.ilp32=march.rv32imaf/mabi.ilp32 \
+march.rv32imac/mabi.ilp32=march.rv32imafd/mabi.ilp32 \
+march.rv32imac/mabi.ilp32=march.rv32imafc/mabi.ilp32 \
+march.rv32imac/mabi.ilp32=march.rv32imafdc/mabi.ilp32 \
+march.rv32imac/mabi.ilp32=march.rv32g/mabi.ilp32 \
+march.rv32imac/mabi.ilp32=march.rv32gc/mabi.ilp32 \
+march.rv32imafdc/mabi.ilp32d=march.rv32imafd/mabi.ilp32d \
+march.rv32imafdc/mabi.ilp32d=march.rv32gc/mabi.ilp32d \
+march.rv32imafdc/mabi.ilp32d=march.rv32g/mabi.ilp32d
diff --git a/gcc/config/riscv/t-linux-multilib b/gcc/config/riscv/t-linux-multilib64
similarity index 100%
rename from gcc/config/riscv/t-linux-multilib
rename to gcc/config/riscv/t-linux-multilib64