E300 32/64 bit ? Confused by Assembly

On the face of it that’s a stupid question, (so should be easy to clear up) as the reference manual clearly states:

“The configurable E31 RISC-V Coreplex provides a high-performance single-issue in-order 32-bit
execution pipeline, with a peak sustained execution rate of one instruction per clock cycle.”

So it’s clearly a 32 bit Arch. But the document riscv-compressed-spec-v1.7.pdf states:

C.SD is an RV64C/RV128C-only instruction that stores a 64-bit value in register rs2′ to memory. It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1′. It expands to sd rs2′, offset7:3.

So that C.SD instruction, which expands to sd rs2… is 64/128 bit only. But the compiler produces that instruction for my LoFive board, which is 32bit?

  addi	sp,sp,-32             
  sd	s0,24(sp)
  addi	s0,sp,32 

Perhaps I’ve got the wrong version of that compressed document. I’m not very proficient at assembly so perhaps I’m mis-reading both documents. Actually that first 3 lines of assembly in my main() strike me as a strange, back to re-reading the compressed-spec

The binary encoding used for C.SD in RV64C/RV128C is used by RV32C for C.FSW i.e. storing a 32 bit floating point value.

You can see this in the table in section 12.7.

It looks like you have a compiler that emits 64-bit code by default. Add -march=rv32imac -mabi=ilp32 to get soft-float rv32imac code. Or use configure options --with-arch=rv32imac --with-abi=ilp32 when building a compiler if you want to build your own.

The compiler does not emit compressed instructions. If you are looking at -S output, you won’t see any compressed instructions unless they came from an extended asm. Compressed instructions are created by the assembler when appropriate, and by the linker if possible during relaxation. So normally you will only see them in disassembled output.

s0 is the frame pointer. That looks like a typical function prologue that requires a frame pointer, so that would not be a c.fsw in disguise. The disassembler can tell the difference between rv32 and rv64 from the elf header, so this is a rather unlikely mistake from the disassembler.

Oh dear! I’d be most frustrated if the assembly language instruction “sd” depended on the arch. Would that not cause a world of potential heartache? I’m coming from an embedded programming background so believe me there are no floats in this code :wink: All I’m doing is flashing a LED, getting used to the toolchain and stuff. On that front I’m using the LoFive toolchain from [1] which is specifically for the LoFive.

I’m not saying that you’re wrong about the “-march” settings, but I certainly hope you are :wink: because the toolchain is specifically for this target device, as I understand it. I’ll have a look. Perhaps I should be specific about what it is I’m looking at. I’m compiling with -S option to have a look at the assembly produced so:

…/freedom-e-sdk/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc -S -I…/freedom-e-sdk/bsp/env/freedom-e300-lofive -I…/freedom-e-sdk/bsp/include -I…/freedom-e-sdk/bsp/env my_hello.c

Thanks for all the responses.

[1] https://github.com/mwelling/freedom-e-sdk

A riscv64 toolchain always emits 64-bit code by default. We have both 32-bit and 64-bit cores supported by this toolchain, so the toolchain needs to be able to emit both.

If you look at bsp/env/freedom-e300-lofive/settings.mk, you will see that it is setting ARCH and ISA, but this works only if your makefile includes this file, and your makefile uses ARCH and ISA when calling the compiler. The makefiles that come with freedom-e-sdk are including this file and using the makefile variables to emit correct code.

“sd” is always “sd”, unless maybe it is c.sd. But if you are looking at binary instruction encodings, then c.sd (rv64) and c.fsw (rv32) share the same encoding.

1 Like

Ahhh and Oops. I was bypassing that arch setting because I was calling the compiler directly with the ‘-S’ option and not using the makefile provided to build the actual target.

Thanks a million for all that. Hopefully I’m learning something with all your help.

At present I’ve just added my project into the software directory of that freedom-e300-lofive toolchain, so I’m using the Makefile provided, just inheriting everything. I think to fully understand, or make sure I do understand, I should create my own makefile completely decoupled for there and point to compiler and include directories.

thanks again.