针对N64架构,能否强制GCC Mips生成整数乘法指令而非移位指令?
如何让GCC为N64架构生成使用mult指令的乘法汇编?
问题背景
原始C代码:
u32 foo; foo = foo*11;
GCC默认编译MIPS代码时,会将foo*11优化为移位加法组合(foo*8 + foo*2 + foo),生成如下汇编:
lui t3, $hi(foo) LW t0, $lo(foo)(t3) sll t1, t0, $3 sll t2, t0, $1 add t1, t1, t2 add t0, t0, t1 sw t0, $lo(foo)(t3)
但针对N64架构,期望生成使用mult指令的汇编(注:原代码中$b应为11,是乘11的立即数):
lui t3, $hi(foo) LW t0, $lo(foo)(t3) addiu t1, r0, 11 mult t0, t1 mflo t0 sw t0, $lo(foo)(t3)
实现方法
以下几种方式可以实现需求:
- 指定目标架构编译选项:编译时添加
-march=vr4300(N64的核心架构)或-march=mips64,明确告知编译器针对N64硬件优化,此时编译器会更倾向于使用mult指令而非移位加法。 - 禁用MIPS16模式:添加编译选项
-mno-mips16,避免编译器生成MIPS16指令集下的优化代码,强制使用传统MIPS指令。 - 调整优化级别或禁用特定优化:如果使用了较高优化级别(如
-O2),可以尝试降低到-O1,或者添加-fno-tree-vectorize禁用向量化优化,避免移位加法替代乘法的逻辑。 - 内联汇编强制实现:如果编译选项无法满足需求,直接使用内联汇编硬编码逻辑,推荐使用寄存器约束让编译器管理寄存器,避免冲突:
u32 foo; __asm__ __volatile__( "addiu %1, $zero, 11\n" "mult %0, %1\n" "mflo %0\n" : "+r"(foo) : "r"(11) : "hi", "lo" );
这种方式会让编译器自动分配合适的寄存器,同时保证乘法逻辑按照期望执行。
内容的提问来源于stack exchange,提问作者Kaze Emanuar
相关产品推荐
相关产品推荐

