riscvarchive / riscv-gcc

GNU General Public License v2.0
358 stars 275 forks source link

why is there no march for rv64imafd in multilib ? what are the side effects on generating on in t-elf-multilib ? #150

Closed ghost closed 5 years ago

ghost commented 5 years ago

Dear experts,

We have an hardware architecture "rv64imafd". I tried the riscv-non-gcc to compile bare metal programs for this program. I coudnt succeed. Eventually I found out there is no multilib support for march=rv64imafd mabi=lp64d combination. I thought of generating the below file with the abv combination. https://github.com/riscv/riscv-gcc/blob/riscv-next/gcc/config/riscv/t-elf-multilib

Before doing that, is there any reasons to leave this combination out. Incase I make a change, what are the side effects it ll have in the gnu toolchain ?

jim-wilson commented 5 years ago

There are potentially an infinite number of missing combinations for arch/abi because this is an open ISA that already has a large number of official independent extensions defined, with many more expected to be added. If we start adding more arch/abi combinations, where do we stop? And who makes the decision as to what is included and what isn't?

The more multilibs we have, the more time it takes to build the toolchain, and the more disk space is required to hold the build and install trees, and the more time it takes to verify it. The last one being a significant problem, as it takes longer to verify the toolchain than to build it. This applies to everyone that builds a toolchain. If riscv-gnu-toolchain is supposed to be an easy way for an undergrad student to get started, then we shouldn't have defaults that make it difficult for someone like that to build a toolchain.

Note that gcc is upstream, and no patches will be accepted here unless they are already upstream first. Likewise for most other riscv github trees nowadays that have an upstream tree.

My working assumptions here are that the list of arch/abi combinations we have before I started doing riscv-gcc work is the official list not to be changed, and anyone who wants a different set of multilibs can add their own list for their own target. I expect that most companies already have their own multilib lists for the target that they support. We can also have OS specific multilib lists, rtems already has one.

You can find the patch I wrote to add extra multilibs to the SiFive compiler in the extra-multilib-patches branch of the sifive/riscv-gnu-toolchain tree.

ilg-ul commented 5 years ago

... I tried the riscv-none-gcc to compile bare metal programs for this program. ... I found out there is no multilib support for march=rv64imafd mabi=lp64d combination.

riscv-none-gcc supports all multilibs supported by the SiFive toolchain, which also does not support rv64imafd.

jim-wilson commented 5 years ago

The current SiFive toolchains do support double float with rv32 and single float with rv64. We added multilibs for those. As our portfolio expands, we will add more multilibs to cover what we are shipping.

ilg-ul commented 5 years ago

Thank you for the update. For the next riscv-none-gcc release I'll check your configuration. Can you point to the repo with the new configuration?

jim-wilson commented 5 years ago

The sifive branch in sifive/riscv-gnu-toolchain.

Or if you just are curious about the new multilibs, see the extra-multilibs-patches branch I already mentioned above.

ilg-ul commented 5 years ago

Ok, thank you, Jim.

ilg-ul commented 5 years ago

What I don't understand is how it was possible for the rv64imafd architecture to pass all tests till now, knowing that this combination is not supported by the toolchain?

The problem occured only when trying to build some C++ projects, and the message was 'ld: cannot find -lstdc++'.

I did not try, but is it possible for the toolchain to pass the link for plain C programs? If so, how is this possible?

jim-wilson commented 5 years ago

What I don't understand is how it was possible for the rv64imafd architecture to pass all tests till now, knowing that this combination is not supported by the toolchain?

​rv64imafdc/lp64d was always supported. It is rv64imafc/lp64f that is not supported by default.

The problem occured only when trying to build some C++ projects, and the message was 'ld: cannot find -lstdc++'. I did not try, but is it possible for the toolchain to pass the link for plain C programs? If so, how is this possible?

Use g++ instead of gcc to link. g++ always passes -lstdc++ to the linker.

Or you can add an explicit -lstdc++ option when using gcc. The extra -lstdc++ option can be put in a specs file if you are using one. You could also edit the default specs file to add the option. You could also put it in an environment variable, but I generally recommend against that, as it is too easy to forget that you set some weird environment variable that changes gcc behavior, and then we get bug reports we can't reproduce.

If you want to edit the default specs file, use "gcc -dumpspecs > specs" to create an explicit specs file, as it is built-in by default. Edit the *lib: line to add -lstdc++ somewhere reasonable. Then copy the specs file into the gcc install tree. I think the same dir as cc1 is the right place to put it. Next time you run gcc it will use the specs file in the install tree instead of the default built-in specs. If you choose to do this, you probably need some testing to make sure you don't accidentally break the default specs file.

ilg-ul commented 5 years ago

Use g++ instead of gcc to link

g++ was used.

What I don't understand is how it was possible for the rv64imafd architecture to pass all tests till now, knowing that this combination is not supported by the toolchain?

​> rv64imafdc/lp64d was always supported. It is rv64imafc/lp64f that is not supported by default.

Let me rephrase:

Some time ago, the Shakti group designed a RV64 device that, by an unfortunate decision, implements only the rv64imafd, without c.

Recently, they decided to write some project templates, which were inspired by the project templates I wrote for the SiFive devices, which are in C++.

When trying to compile the projects generated by the template, the result was 'ld: cannot find -lstdc++'. When asked what is wrong, I suggested them to fix the architecture string from rv64imafd -> rv64imafdc, and the build passed. So there is nothing wrong with the projects or the builds.

But using c is not what they need, since their devices do not implement c at all.

Now the question:

Assuming that since they released their RV64 devices (quite some months ago?), till now (when we tried the C++ project generated by the templates), they ran some tests to validate the design, tests written in C and using the existing toolchains (both GNU MCU Eclipse and SiFive), how is it possible that these tests configured with rv64imafd were successful since the toolchain does not support this architecture?

Why the compiler did not simply flag rv64imafd as an error and quit, and instead proceeded with the compile, proceeded with the link for C, and failed only by chance with a missing library for C++?

What architecture was used by the compiler, giving that rv64imafd is not supported?

Having the compiler pass builds with an undefined architecture isn't an issue to worry about?

jim-wilson commented 5 years ago

Since I don't have their code, or their exact version of the compiler, or their compiler command line options, or their libraries, or their hardware, I can only guess.

The compiler supports any valid combination of -march and -mabi. It is only a question of libraries.

For libraries, the compiler will provide the closest matching library. The linker will accept it if compatible merging arch strings if necessary, or reject it if not compatible. If the end result after arch merging is not OK, the hardware should refuse to run it. If they are trapping and emulating missing instructions, they might not notice the arch merging.

But libraries will only be added in if you call them. If you aren't calling any standard library routines or are providing your own implementations of them, and you have your own startfiles, there is no library problem.

The issue for C++ is that you are effectively always using the standard library, even if you don't call any functions in it, because it is pretty much impossible to escape from the standard library like one can do in C. So this is a possible reason why it "worked" for C, but did not work for C++, because there is no easy way to avoid using the C++ standard library even for trivial C++ programs.

jim-wilson commented 5 years ago

Maybe -nostdlib doesn't disable the -lstdc++ in the C++ driver.

ilg-ul commented 5 years ago

Since I don't have their code, or their exact version of the compiler, or their compiler command line options, or their libraries, or their hardware, I can only guess.

I don't have their code either, but, assuming the hardware is rv64imafd compliant, and the compiler was invoked with -march=rv64imafd -mabi=lp64d, and also assuming they indeed ran some tests to validate the hardware, by what miracle these tests passed, since all available libraries in riscv64-unknown-elf-gcc require c?

it would be interresting to discover that the hardware also implements c, although it is not expected to do so...

The compiler supports any valid combination of -march and -mabi. It is only a question of libraries.

this explains why gcc did not issue errors while compiliing.

but do you think this behaviour (not reporting an error for architectures not fully supported with libraries) is a feature? since in this case it looks more like a bug, before attempting to build a C++ program, they had no indication that the toolchain does not support their architecture.

jim-wilson commented 5 years ago

I think you are making unsafe assumptions here. If there is no matching library, then it should fail exactly the same for C as it does for C++, unless they are doing something funny like using -nostdlib -nostdlib and providing their own library. In which case it failed for C++ only because they did not provide their own C++ library.

Substituting other libraries is a useful feature. If you compile for rv32ic and we don't have a rv32ic library but we do have a rv32i library, then it is reasonable to use the rv32i instead of giving an error. You are only losing a little bit of code size here.

I think you have unreasonable expectations here. We have a potentially infinite number of arch/abi combinations, and a potentially infinite number of ways that people can misuse the toolchain. We will never be able to handle predict them all in advance and devise ways handle them cleanly.

I don't see any evidence of a problem that needs to be fixed here.

ilg-ul commented 5 years ago

I think you are making unsafe assumptions here

then perhaps @sathya281 can clarify what tests they ran on their hardware before attempting to build the template projects.

if there is a logical explanation why the tests passed, and the use case was legal, then there is no problem.

ghost commented 5 years ago

Hi Jim and Liviu,

Thanks for helping me here.

Regarding testing hardware: We used the riscv64-unknown-elf-gcc compiler for our bare metal appln and OS ports. We didn't face issues. When I started to think in terms of IDE, I understood the need to have a multilib.I read some blogs and issues abt this in git/elsewhere.

At the time we developed a march=imafd hardware, we found "C" instruction set was not stable. We had some timing constraints and went with that idea. We had march=imac for 32 bit hardware. Now we are looking for imafdc for 64 bit hardware. Probably few months down the line.

I hope, I have clarified all doubts. Nevertheless I learned a lot by doing this exercise

ilg-ul commented 5 years ago

We used the riscv64-unknown-elf-gcc compiler for our bare metal appln and OS ports. We didn't face issues.

what libraries did you use? since riscv64-unknown-elf-gcc has no libraries for rv64imafd, how did you do it? did you provide your own?

palmer-dabbelt commented 5 years ago

The issue here is only for multilib toolchains, where we select a list of ISA/ABI pairs to build libraries for. GCC always supports all the legal ISA/ABI pairs, and non-multilib toolchains will build the libraries for whatever they have been configured for. That's how we can test GCC and how some users can use the non-standard ISA/ABI pairs.

ilg-ul commented 5 years ago

We used the riscv64-unknown-elf-gcc compiler for our bare metal app... We didn't face issues.

sure, since you compiled your custom version of the toolchain, using --with-arch=rv64imafd.

this explains why the linker did not complain about missing libraries when compiliing your tests.