move.[bw] #0,dn
clr.[bw] dn
clr.l では moveq に置換するの対して move.[bw] では clr.[bw] を使う. moveq に変えてしまうと使用容量と実行速度が同じ上に bit 31:16 が 0 になってしまうのでよいことはない.
話がそれるが clr 命令はレジスタのみに使う. clr 命令をメモリに使うのはよくない. マイクロコードの都合なのか不要な memory read が発生して遅い. 68010 以降はこの問題がない. bclr 命令はメモリを読んでフラグを更新してからメモリに書くので memory read の必要性はあるんだが、clr 命令はそれがない.
lea (an,dn.[wl]),an
src と dest の an が同じ場合に限る.
adda.[wl] dn,an
data pointer table 共通事項
jump table 共通事項の jmp/jsr がない. 基本方針は jump table と同じで dc.l を dc.w か dc.b の配列に変える.
このため index が pointer の数を超えている動作の場合は同等にならない. jump table では高確率でおかしくなるので元々のプログラム開発時に気づいて直していると思うが, data table は気づかずに動いてしまっていることが十分に考えられる.
pointer の中身が1種類
jump table の場合
jmp pointer
data table の場合
lea poiter,an
意外なことにこれが結構あった.
pointer が等間隔
pointer0
dc.w 0,1,2,3,4,5
pointer1:
dc.w 6,7,8,9,10,11
基本は data pointer table だけに適用する. jump table の場合は定数設定だけで分岐している場合だったので適切なコードを作った方がいい.
;間隔12の場合は index * 4 + index * 8 -> (index << 2) + (index << 3)
;として乗算をシフトと加算に変える.
lsl.w #2,dn
if near
lea (pc,pointer0,dn.w),an
else
lea pointer0,an
adda.w dn,an
endif
lsl.w #1,dn
adda.w dn,an
2の累乗ではない値の乗算回避のテーブルと思いきや間隔が 2 や 8 もあった.
加算回数が多すぎる場合は自動生成をやめて元通りテーブルを使うのも悪くはない. その場合は dc.l (→ lea; movea.l) から dc.w (→ lea; adda.w) に変えるほうが容量を削減できる.
pointer の中身が -0x80 から 0x7f で収まる場合
ほかの条件は jump table とやることは大体同じなので省略.
if near
move.b (pc,table,dn.w),dn
ext.w dn
lea (pc,table,dn.w),an
else
lea table,an
move.b (an,dn.w),dn
ext.w dn
adda.w dn,an
endif
...
...
table:
dc.b pointer0 - table
dc.b pointer1 - table
align 2
その他
pointer table の index を 8 bit でうち bit7 を別の意味を持たせている場合.
元のコード
lea table,an
tst.w dn
bmi xxx
andi.w #$007f,d7
lsl.w #2,d7
movea.l (an,d7.w),an
...
...
...
xxx:
andi.w #$007f,d7
lsl.w #2,d7
movea.l (an,d7.w),an
...
...
...
修正後
lea table,an
andi.w #$00ff,d7 ;bit15:8 を 0 にする
lsl.b #1,d7 ;.w から .b に変えて bit7 の有無をフラグにする
movea.w (an,d7.w),an ;movea はフラグが変わらない
bcs xxx
...
...
...
xxx:
...
...
...
src の bit0 を dest の bit7 へ代入
static uint8_t hoge(uint8_t src, uint8_t dest)
{
dest &= 0x7f;
if(src & 1){
dest |= 0x80;
}
return dest;
}
;d0 = src, d1 = dest
lsl.b #1,d1 ;d1 <<= 1
lsr.b #1,d0 ;x=d0[0]
roxr.b #1,d1 ;d1[7:0]= {x,d1[7:1]}