Compatibility Issue: A RISC-V 32-bit app can work well on RISC-V 64-bit core?

If a binary executable application is built with RV32 tool chain,
I wonder if it work well on RV64 core ?
Is there any compatibility issue ?
I know a 16-bit 8086 program can work well on 32-bit 80386 and 64-bit x64.
Is RISC-V has same compatibility feature ?
thanks.

An rv32 binary will not work in rv64 mode on an rv64 core unless maybe you trap every opcode that has different meanings as rv32 and rv64 instructions. As far as I know, no one has tried to implement this. It would likely be inconvenient.

If you are running an OS, then there is a bit you can set in one of the csrs to switch between rv32 and rv64 mode, if the core supports it. This would require OS level support, and multilib library support, and maybe also other stuff. As far as I know, no one has tried to implement this. This would likely be a lot of work.

It would much easier to just use an rv64 qemu to emulate rv32 instructions in rv64 mode on an rv64 part, though probably slower. This has probably been tried before and probably works.

Otherwise, no, this isn’t going to work.

Jimw, thanks for your quick feedback.
You have given us useful info.

Currently, most of PC, server and mobile phone have already been working on 64-bit CPU cores.
If RISC-V wants to go to these market, to keep simple, no need to keep 32-bit compatibility, right ?
Anyway, as all software need to be rebuilt, let they are only built for RV64.
I think this is advantage of RISC-V to get rid of such this historical burden.

As to other embed use case, there is less need to keep backwards compatibility.

But I think RV128 should keep backwards compatibility with RV64.

There is no old RV32 code to be compatible with. There is only new RV32 and new RV64 code.

RV128/RV64 has the same problem as RV64/RV32. It won’t work without some effort. But we probably have some time before that becomes a practical problem, and solutions may be available by then.

I believe RISC-V may have been designed at the start as a 64 bit ISA, with the idea to make a similar 32 bit ISA coming only a little later.

They are in fact two different ISAs that happen to share instruction mnemonics and encodings. But they are incompatible.

With a little care it’s possible to write assembly language programs that can assemble to a 32 bit program or a 64 bit program. The main thing you need to do is define pseudo-ops for “load register” and “store register” that map to lw/sw or ld/sd depending on which you are building. You also need a constant that can be 4 or 8 to help with calculating stack frame and struct sizes and offsets.

With a LOT of care you can write a short 32 bit assembly language program that will also run on a 64 bit machine. However it is very very restricted. For example unless you can make sure it is loaded in the top or bottom 2 GB of address space on a 64 bit machine, you will not even be able to save the return address from a function so that you can call another function and then successfully load it again. You also have to either turn off the C extension, or else somehow make sure you don’t use the c.jal instruction or compressed floating point loads and stores. You definitely won’t be able to use anything from the standard library or startup functions.

Probably the best thing to do is do something that will tell you if the runtime machine is 32 bit or 64 bit and then have two copies of your program and jump to the correct one. For example, you could take (or create) any register containing a nonzero value, shift it left by 16 bits, and then shift left by another 16 bits. If the result is not zero then you are running on a 64 bit CPU. I think the minimum sequence to do this would be a LUI with at least the lowest 4 bits clear and some other bit(s) set, a shift left, and a BEQZ/BNEZ.

As Jim said, you can try to set a field in the MISA CSR to switch between 32 bit and 64 bit modes. You then need to check the result to see if it really changed to discover whether switching instruction sets is supported on your CPU. No SiFive CPU supports switching between 32 bit and 64 bit instruction sets, and there are no current plans to do so. I’m not aware of anyone else with a CPU that supports it either.