寻求68K数据寄存器间符号值快速复制的无分支优化方案
无分支快速复制符号位的68000汇编方案
针对你的需求——用无分支操作替代MULS.W来将D0的符号(±1)应用到正数D1上,这里有一个高效的指令序列,周期消耗远低于乘法:
; 假设D0是字节型的±1,D1是字型的正数 EXT.W D0 ; 将D0从字节扩展为字:-1 → $FFFF,1 → $0001(4周期) ASR.W #15, D0 ; 算术右移15位,生成掩码:-1对应$FFFF,1对应$0000(6周期) EOR.W D0, D1 ; D0为$FFFF时取反D1,为$0000时D1不变(4周期) ANDI.W #1, D0 ; 将掩码转换为触发位:$FFFF→$0001,$0000→$0000(4周期) ADD.W D0, D1 ; 取反后加1完成求补(NEG),不变时加0保持原值(4周期)
为什么这个方案有效?
你的核心需求是:当D0=-1时,将正数D1转为-D1;当D0=1时,保持D1不变。而NEG D1等价于NOT D1 + 1,我们通过无分支的掩码操作来控制这两个步骤:
ASR.W #15, D0利用算术右移的符号位填充特性,把±1转换成全1或全0的掩码,完美对应"需要求补"和"不需要操作"的状态。- 后续的
EOR和ADD组合,在掩码为全1时自动执行"取反+加1"的求补操作,掩码为全0时则完全不改变D1的值。
周期对比
原方案的MULS.W最多需要70个周期,而这个序列的总周期是4+6+4+4+4=22周期,性能提升非常明显。
替代简化方案(稍慢但更直观)
如果你觉得算术右移不好理解,也可以用条件设置指令实现,总周期24,依然远优于乘法:
EXT.W D0 ; 字节转字(4周期) CMP.W #1, D0 ; 比较D0是否为1(4周期) SNE D0 ; 不等时(即D0=-1)设置D0为$FFFF,否则为$0000(4周期) EOR.W D0, D1 ; 同前(4周期) ANDI.W #1, D0 ; 同前(4周期) ADD.W D0, D1 ; 同前(4周期)
两种方案都完全符合你的无分支要求,不需要任何跳转指令,完美适配你的场景。
内容的提问来源于stack exchange,提问作者KONEY
相关产品推荐
相关产品推荐

