安装riscv的官方工具链(.ident "GCC: (GNU) 7.2.0"),后对一个c文件进行编译,启动-O3选项时候,编译得到的汇编程序与c代码不一致。
c代码为一个memset的实现,编译错误对应于第二个while语句对应的汇编:
- void* memset(void* dest, int byte, size_t len)
- {
- if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) {
- uintptr_t word = byte & 0xFF;
- word |= word << 8;
- word |= word << 16;
- word |= word << 16 << 16;
- uintptr_t *d = dest;
- while (d < (uintptr_t*)(dest + len))
- *d++ = word;
- } else {
- char *d = dest;
- while (d < (char*)(dest + len))
- *d++ = byte;
- }
- return dest;
- }
复制代码
gcc汇编产生的代码如下:
- memset:
- addi sp,sp,-16
- or a5,a0,a2
- sd s0,0(sp)
- sd ra,8(sp)
- andi a5,a5,7
- mv s0,a0
- add a2,a0,a2 ## a2=dest+len
- beqz a5,.L345 ## 跳入第一个if{}
- bleu a2,a0,.L347 ## 第2个while不成立则跳转到return
- sub a2,a2,a0 ## ======
- andi a1,a1,0xff ## ==着3行出错
- call memset ## ======递归
- .L347:
- mv a0,s0
- ld ra,8(sp)
- ld s0,0(sp)
- addi sp,sp,16
- jr ra
- .L345:
- andi a4,a1,0xff
- slli a1,a4,8
- or a4,a4,a1
- slli a1,a4,16
- or a4,a4,a1
- slli a5,a4,32
- or a4,a4,a5
- bleu a2,a0,.L347
- mv a5,a0
- .L348:
- addi a5,a5,8
- sd a4,-8(a5)
- bgtu a2,a5,.L348
- mv a0,s0
- ld ra,8(sp)
- ld s0,0(sp)
- addi sp,sp,16
- jr ra
复制代码
这个可能是什么问题,如何避免?谢谢!
|