【发布时间】:2021-04-15 14:44:51
【问题描述】:
我正在尝试将平淡无奇的 c 代码编译为 RV32i 处理器可执行的 elf 格式。
但是,当我启用优化(-Os 或 -O2)时,生成的程序集包含我无法执行的压缩指令。 我所有的自制代码都被编译成普通的 rv32i 指令,只有辅助函数*被编译成 C 指令。如何完全禁用 C 指令?
我的意思是 __riscv_save_0, __riscv_restore_0, __riscv_save_4, ...
我使用编译代码
riscv32-unknown-elf-gcc $(CFLAGS) -T link.ld $(SRCS) -o $@ -lgcc
CFLAGS 为:
-g -O2 -msave-restore -mabi=ilp32 -march=rv32i --specs=nosys.specs -nostdlib -Wall -Wl,-gc-sections -ffunction-sections -ffreestanding -fno-builtin
反汇编看起来像这样 - 优化了:(出于某种原因,我的所有代码都没有 C 指令,所有辅助函数都带有 C 指令)
00000174 <__riscv_save_0>:
174: 1141 addi sp,sp,-16
176: c04a sw s2,0(sp)
178: c226 sw s1,4(sp)
17a: c422 sw s0,8(sp)
17c: c606 sw ra,12(sp)
17e: 8282 jr t0
...
00000198 <__riscv_restore_0>:
198: 4902 lw s2,0(sp)
19a: 4492 lw s1,4(sp)
19c: 4422 lw s0,8(sp)
19e: 40b2 lw ra,12(sp)
1a0: 0141 addi sp,sp,16
1a2: 8082 ret
...
000001c4 <main>:
1c4: fb1ff2ef jal t0,174 <__riscv_save_0>
1c8: 034000ef jal ra,1fc <func_a>
1cc: 00000537 lui a0,0x0
1d0: 00000613 li a2,0
1d4: 00000593 li a1,0
1d8: 1a450513 addi a0,a0,420
1dc: 098000ef jal ra,274 <func_b>
1e0: 00000537 lui a0,0x0
1e4: 00000613 li a2,0
1e8: 00000593 li a1,0
1ec: 1b450513 addi a0,a0,436
1f0: 084000ef jal ra,274 <func_b>
1f4: 154000ef jal ra,348 <func_c>
1f8: fa1ff06f j 198 <__riscv_restore_0>
【问题讨论】:
-
看起来您可能正在反汇编链接器输出。尝试找出编译器是否生成了辅助函数,或者它们是否是从库中获得的。这应该可以帮助您缩小问题的根源。您可以通过反汇编目标文件来查看这些函数和/或任何压缩指令是否存在于编译器输出、预链接器中。 (您可以看到
main可以使用压缩指令,但没有。) -
据我所知这些函数来自 -lgcc 库
-
每当我在编译期间不包含 -lgcc 时。它会抛出一个错误,即找不到 __riscv_restore_0,...
-
它们很小,您可以提供自己的等价物吗?或者也许不使用
-msave_restore??否则,-march=rv32i与-march=rv32imac相比,必须有适当版本的库,但我不知道 gcc 在这方面应该如何工作。 -
编辑:当我排除 -msave_restore 时,一切都编译为无 C 指令 :) 但是这些辅助函数是代码优化的一个很好的补充。如果您有任何其他线索可以用适当的非 C 实现替换它们,那就太好了。
标签: compiler-errors compiler-optimization riscv riscv32