如何解决llc生成的AVR汇编无法被avr-as兼容的问题?
解决方案
1. 调整llc参数(最直接的解决方式)
优先试试给llc加-no-integrated-as参数——这个参数会强制llc生成适配外部汇编器(而非LLVM内部集成汇编器)的代码,很多格式兼容问题都是因为默认输出是给LLVM自己的汇编器用的。命令改成这样:
llc-15 -march=avr -mcpu=atmega32u4 -no-integrated-as foo.ll -filetype=asm -o foo.fixed.s
另外atmega32u4属于avr5架构,可以再加个-mattr=+avr5明确指定架构属性,避免生成超出该CPU支持的指令:
llc-15 -march=avr -mcpu=atmega32u4 -mattr=+avr5 -no-integrated-as foo.ll -filetype=asm -o foo.fixed.s
如果还是有问题,试试降低优化等级到-O0,某些优化可能会生成avr-as不兼容的特殊汇编代码。
2. 换用LLVM自带的汇编器llvm-mc
llc生成的代码本来就是LLVM生态的产物,直接用llvm-mc汇编完全不会有兼容问题,命令如下:
llvm-mc-15 -triple avr -mcpu=atmega32u4 foo.ll.s -filetype=obj -o foo.o
后续链接可以用llvm-ld或者avr-gcc的链接器完成。
3. 轻量后处理适配avr-as
既然只有37行出错,针对性批量修改就行,给几个常见问题的处理脚本:
- 清理行尾垃圾字符:用sed去掉行尾多余的空格、制表符:
sed 's/[[:space:]]*$//' foo.ll.s > foo.step1.s - 注释掉不兼容的调试伪指令:avr-as大多不支持LLVM的
.cfi_*系列伪指令,直接注释掉这些行:sed '/^\.cfi_/s/^/\/\//' foo.step1.s > foo.step2.s - 修复符号类型声明:把LLVM风格的
.type foo,@function改成avr-as认的.type foo,function:sed 's/@function/function/' foo.step2.s > foo.fixed.s - 替换未知操作码:如果错误提示是某个操作码不认识,比如llc生成的
mulsu而avr-as只认muls,就针对性用sed替换,具体看你的错误日志调整。
内容的提问来源于stack exchange,提问作者Cactus
相关产品推荐
相关产品推荐

