如何指定GCC不生成特定指令?自制MIPS CPU适配需求
如何让GCC不为自定义MIPS CPU生成特定指令(比如MUL)
嘿,做自定义MIPS CPU还得适配GCC,这个场景我太熟了!其实不用急着直接改GCC,先试试这些方法,实在不行再动源码:
一、用GCC编译选项快速禁用(无需修改GCC)
针对MIPS架构,GCC本身就提供了不少指令集控制选项,刚好可以用来禁用你没实现的指令:
- 全局禁用MUL指令:编译时加上
-mno-mul选项,这会让GCC放弃生成硬件MUL指令,转而用加法+移位的软件逻辑来模拟乘法操作。如果你的CPU基础指令集是MIPS1/MIPS2这类,搭配-march=mips1(或者对应你的指令集版本)一起用效果更好,比如:gcc -march=mips1 -mno-mul -o output input.c - 针对特定函数禁用:如果不想全局禁用,只想让某个函数不生成MUL指令,可以用函数属性来精准控制:
__attribute__((target("no-mul"))) int safe_multiply(int a, int b) { return a * b; // 这里的乘法会用软件模拟,不会生成MUL指令 }
二、修改GCC后端(彻底禁用特定指令)
如果编译选项满足不了需求(比如你要禁用的是更冷门的自定义指令),那就要动手改GCC的MIPS后端代码了:
- 找到GCC源码中的MIPS机器描述文件:
gcc/config/mips/mips.md,这里定义了所有GCC能生成的MIPS指令模板。 - 搜索你要禁用的指令,比如MUL相关的
mulsi3(无符号整数乘法)、mulsidi3(64位乘法)等指令定义。 - 注释掉或者删除对应的
(define_insn)块,或者修改指令的匹配条件,让GCC永远不会选中这个指令模板。比如找到类似这样的代码:
你可以把条件(define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=d") (mult:SI (match_operand:SI 1 "register_operand" "%d") (match_operand:SI 2 "register_operand" "d")))] "TARGET_MUL" "mul\t%0, %1, %2" [(set_attr "type" "imul") (set_attr "mode" "SI")])"TARGET_MUL"改成永远为假(比如"0"),或者直接删掉这个insn定义,这样GCC就会自动 fallback 到软件实现。 - 重新编译GCC,用新编译的版本来生成代码。
三、验证方法
不管用哪种方法,最后一定要验证生成的二进制里有没有你禁用的指令:
用objdump反汇编输出文件,检查是否存在MUL指令:
objdump -d output | grep -i mul
如果没有任何输出,就说明成功了!
内容的提问来源于stack exchange,提问作者TheNetAdmin
相关产品推荐
相关产品推荐

