There is a toolchain in riscv.org Git release. Freedom SDK includes another toolchain.
Which one should be used for E3000 platform?
Thanks
Bob
There is a toolchain in riscv.org Git release. Freedom SDK includes another toolchain.
Which one should be used for E3000 platform?
Thanks
Bob
For developing against the E300 platform, you should always use the version included in the Freedom E SDK.
Thanks
Does it support RISC-V compressed extension, RVC?
Yes.
I just ordered the Hifive, and started to play with the software. A little experimentation shows that you can add…
-march=RV32IC
… to the CFLAGS in your Makefile.
Some output:
demo_gpio.o: file format elf32-littleriscv
Disassembly of section .text:
00000000 <no_interrupt_handler>:
0: 1141 addi sp,sp,-16
2: c622 sw s0,12(sp)
4: 0800 addi s0,sp,16
00000006 <.LM2>:
6: 0001 nop
8: 4432 lw s0,12(sp)
a: 0141 addi sp,sp,16
c: 8082 ret
0000000e <handle_m_ext_interrupt>:
e: 1101 addi sp,sp,-32
10: ce06 sw ra,28(sp)
12: cc22 sw s0,24(sp)
14: 1000 addi s0,sp,32
00000016 <.LM4>:
16: 000007b7 lui a5,0x0
1a: 00078513 mv a0,a5
1e: 00000317 auipc t1,0x0
22: 000300e7 jalr t1
26: fea42623 sw a0,-20(s0)
0000002a <.LM5>:
2a: fec42783 lw a5,-20(s0)
2e: cb9d beqz a5,64 <.L3>
00000030 <.LM6>:
30: fec42703 lw a4,-20(s0)
34: 47a1 li a5,8
36: 02e7e763 bltu a5,a4,64 <.L3>
0000003a <.LM7>:
3a: 000007b7 lui a5,0x0
3e: fec42703 lw a4,-20(s0)
42: 070a slli a4,a4,0x2
44: 00078793 mv a5,a5
48: 97ba add a5,a5,a4
4a: 439c lw a5,0(a5)
4c: 9782 jalr a5
Nice. Will try it later.
Thanks
Yes, the FE310 supports the C extension.
Just be aware that GDB doesn’t yet support misaligned breakpoints. So if you’re trying to debug your ‘C’ code, you may have to get creative on where you place them
I notice that in .o files from gcc -march=RV32IC there are many longer than necessary instructions, such as branches, and even completely unnecessary instructions such as auipc with #0. Looking at the final executable, many of those have been cleaned up, but not all.
Presumably the linker has done this?
for example, in .o
00000000 <fib>:
0: 4785 li a5,1
2: 02a7d863 ble a0,a5,32 <.L8>
6: 1141 addi sp,sp,-16
8: c606 sw ra,12(sp)
a: c422 sw s0,8(sp)
c: c226 sw s1,4(sp)
e: 842a mv s0,a0
10: 1579 addi a0,a0,-2
12: 00000317 auipc t1,0x0
16: 000300e7 jalr t1
1a: 84aa mv s1,a0
1c: fff40513 addi a0,s0,-1
20: 00000317 auipc t1,0x0
24: 000300e7 jalr t1
28: 9526 add a0,a0,s1
2a: 40b2 lw ra,12(sp)
2c: 4422 lw s0,8(sp)
2e: 4492 lw s1,4(sp)
30: 0141 addi sp,sp,16
00000032 <.L8>:
32: 8082 ret
And then in executable:
00010164 <fib>:
10164: 4785 li a5,1
10166: 02a7d263 ble a0,a5,1018a <fib+0x26>
1016a: 1141 addi sp,sp,-16
1016c: c606 sw ra,12(sp)
1016e: c422 sw s0,8(sp)
10170: c226 sw s1,4(sp)
10172: 842a mv s0,a0
10174: 1579 addi a0,a0,-2
10176: 37fd jal 10164 <fib>
10178: 84aa mv s1,a0
1017a: fff40513 addi a0,s0,-1
1017e: 37dd jal 10164 <fib>
10180: 9526 add a0,a0,s1
10182: 40b2 lw ra,12(sp)
10184: 4422 lw s0,8(sp)
10186: 4492 lw s1,4(sp)
10188: 0141 addi sp,sp,16
1018a: 8082 ret
Also, the documentation (User-Level ISA specification) says that millicode routines are used for saving and restoring registers when -Os is used with the standard toolchain, but I haven’t been able to trigger this.
Also, a complete example without any handwaving of how to build and run (on an emulator) HelloWorld would be useful.
Is there no install package for a Debian/Ubuntu x86-64 qemu-riscv (-user) somewhere? Everyone having to build their own seems a bit daft. I tried the docker image sorear/fedora-riscv-wip but when I copy a binary into it (which took some googling to find out how to do that – EXPLICIT INSTRUCTIONS PLEASE) I get
[root@84eef74525b3 ~]# qemu-riscv64 fib_rv
fib_rv: Invalid ELF image for this architecture
$ file fib_rv
fib_rv: ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped
Does qemu-riscv64 only execute 64 bit binaries? But 32 bit is a strict subset…
Soooo confused.
One last question for now: if I hand write some assembler, is there a syntax to specify that I want a compressed instruction, or it’s just automatic when it’s possible?
You can write RVC code directly if you want, but the assembler always compresses instructions when possible, so usually there’s little point in doing so.
Branches aren’t relaxed until link time, which is why they show up as 4 bytes long in the .o files.
So I’ve just found a show-stopper, at least until my hardware (HiFive1, not the FPGA board) arrives: qemu doesn’t support RVC! That explains why I was having trouble running it.
Looking at the code, it’s probably no more than a couple of day’s work to implement RVC crudely by:
stop branches checking for 4 byte alignment
making sure unaligned reads of 4 bytes to fetch instructions work
if the bottom two bits of the just fetched 4 byte instruction are not 11
then back up the PC by 2 bytes before the next fetch.
decode the 2 byte instruction to the equivalent 4 byte one, and substitute it for the four bytes you read from memory.
generate host code as normal
It won’t be all that fast, but as it’s a JIT I don’t think it would be critical. The only problem I see is if there is a 16 bit instruction in the last two bytes of a memory page and the next page is not readable. I don’t know if real hardware allows that situation.
However, I don’t have that couple of days right now…
Thanks for creating the associated issue on the riscv-qemu repository.
Part 3 of that proposal seems like a potential pitfall. If the RVC instruction generates an exception, will EPC be set correctly? I’d look into how qemu’s Thumb2 (or even x86) port handles variable-length instructions, and follow their lead. Hopefully, the riscv-qemu maintainers can assist with this process.
In the mean time, Spike can interpret RVC code.
Yeah, I have no idea at all how the internals of qemu work to map generated x86 code back to the corresponding emulated opcode, or if explicit code is generated to check for exceptions, or what. I’ve never looked into the qemu code.
Where do you find spike?
$ find . -name \*spike\*
./riscv-gnu-toolchain/scripts/spike.exp
$ cat riscv-gnu-toolchain/scripts/spike.exp
load_generic_config "sim"
set_board_info sim "spike pk"
set_board_info compiler "[find_gcc]"
set_board_info ldflags "-static -pthread"
set_board_info gdb,nosignals 1
set_board_info is_simulator 1
$
That doesn’t seem terribly helpful.
Spike isn’t part of the riscv-gnu-toolchain. You can get it by installing the full riscv-tools suite: https://github.com/riscv/riscv-tools
It’s the riscv-isa-sim submodule, but you need several other things so you may want to install the full suite.
Megan