68000汇编优化:无分支代码计数有符号比较条件是否更高效?
背景
我有两个包含10个有符号字的固定数据集A和B,以及两个有符号阈值a和b。需要在一次遍历中完成以下操作:
- 存储
C[i] = A[i] + B[i] - 累加
CONT1 += (A[i] > b) - 累加
CONT2 += (B[i] < a)
下方代码可正常运行,已使用DBF指令实现恰好10次迭代,所有输入输出通过栈传递。我的问题仅针对微优化内循环:是否存在68k架构的惯用写法,能够移除两条Bcc指令中的一条,同时保持计数结果正确?
最小可运行程序(Easy68k)
ORG $8000 A DC.W 2,2,1,0,4,4,2,5,-1,2 B DC.W 2,3,1,2,-7,4,-3,-2,0,2 C DS.W 10 aVal DC.W -3 bVal DC.W 5 CONT1 DS.W 1 CONT2 DS.W 1 START: MOVE.W bVal,-(A7) ; push b (value) MOVE.W aVal,-(A7) ; push a PEA.L C ; push &C PEA.L B ; push &B PEA.L A ; push &A BSR.S Process10 ADDA.L #12,A7 ; pop params SIMHALT ; -------- Process10(&A,&B,&C,a,b) -------- ; 4(A7)=&A 8(A7)=&B 12(A7)=&C 16=a 18=b ; OUT: CONT1 (A> b), CONT2 (B< a) Process10: MOVE.W 16(A7),D2 ; a MOVE.W 18(A7),D3 ; b MOVEA.L 4(A7),A0 ; A MOVEA.L 8(A7),A1 ; B MOVEA.L 12(A7),A2 ; C MOVEQ #9,D7 ; DBF count (10 words) CLR.W D4 ; CONT1 CLR.W D5 ; CONT2 Loop10: MOVE.W (A0)+,D0 ; A[i] CMP.W D3,D0 ; A > b ? BLE.S SkipA ADDQ.W #1,D4 SkipA: MOVE.W (A1)+,D1 ; B[i] CMP.W D2,D1 ; B < a ? BGE.S SkipB ADDQ.W #1,D5 SkipB: ADD.W D1,D0 MOVE.W D0,(A2)+ DBF D7,Loop10 MOVE.W D4,CONT1 MOVE.W D5,CONT2 RTS END START
问题
在Loop10内,我使用了两条条件分支指令(BLE.S和BGE.S)来更新CONT1和CONT2。在68k架构下,是否可以:
- 使用
Scc+ADDQ或其他技巧,将每个比较-更新操作合并为单条指令, - 且不增加额外寄存器,也不会在标准68000上减慢循环速度?
(如果答案是“你当前的分支组合已是最佳权衡方案”也可以——我只是想确认自己没有遗漏经典的68k惯用写法。)
编辑——用MOVEQ #0替代CLR.L及其他小幅调整
根据@Peter Cordes的计时建议:
- **
MOVEQ #0,Dn(4个周期)**是清零32位寄存器最快的方式,因此现在使用MOVEQ初始化CONT1/2。 - 保留无分支的
Scc / SUB.B逻辑,因为这是Scc之后实现“-1或0 ➜ +1或0”成本最低的单指令方式。
ORG $8000 ; ---------- data ---------- VectorA DC.W 2,2,1,0,4,4,2,5,-1,2 VectorB DC.W 2,3,1,2,-7,4,-3,-2,0,2 C DS.W 10 aVal DC.W -3 bVal DC.W 5 CONT1 DS.W 1 CONT2 DS.W 1 ; ---------- main ---------- START: MOVE.W bVal,-(A7) MOVE.W aVal,-(A7) PEA.L C PEA.L VectorB PEA.L VectorA BSR.S Process10 ADDA.L #12,A7 MOVE.W D4,CONT1 MOVE.W D5,CONT2 SIMHALT ; ------------------------------------------------------------ ; Process10(&A,&B,&C,a,b) — branch-free counters ; ------------------------------------------------------------ Process10: MOVE.W 16(A7),D2 ; a MOVE.W 18(A7),D3 ; b MOVEA.L 4(A7),A0 ; A MOVEA.L 8(A7),A1 ; B MOVEA.L 12(A7),A2 ; C MOVEQ #9,D7 ; 10 iterations MOVEQ #0,D4 ; CONT1 MOVEQ #0,D5 ; CONT2 Loop10: MOVE.W (A0)+,D0 CMP.W D3,D0 ; A > b ? SGT D6 ; $00 / $FF SUB.B D6,D4 ; CONT1 += 1/0 MOVE.W (A1)+,D1 CMP.W D2,D1 ; B < a ? SLT D6 ; $00 / $FF SUB.B D6,D5 ; CONT2 += 1/0 ADD.W D1,D0 ; C[i] = A + B MOVE.W D0,(A2)+ DBF D7,Loop10 RTS END START
现在两个计数器都以最快方式初始化(MOVEQ #0),且内循环仍仅包含一条分支指令(DBF)。
内容的提问来源于stack exchange,提问作者Pato
相关产品推荐
相关产品推荐

