更新日: 2011 年 11 月 15 日
MC68060 の分岐予測エラーの解説
説明
exx.x の添付ドキュメントです。
bpe.doc
────────────────────────────────────
68060 における分岐予測エラーについて
鎌田 誠
────────────────────────────────────
●分岐予測エラーとは
分岐予測エラー(Branch Prediction Error)というのは、68060 において分
岐キャッシュが分岐命令以外の場所でヒットしてしまった場合に発生する例外で
す。これはアクセスエラーの一種なので、060turbo で発生するとバスエラーの
白帯が出てプログラムが止まってしまいます。勿論、分岐キャッシュを禁止すれ
ば発生しません。
●オペランドワードで分岐命令を飛び越えてはならない
オペランドワードで分岐命令を飛び越えている部分があるプログラムを 68060
で実行すると、分岐予測エラーが発生する可能性があります。
オペランドワードで分岐命令を飛び越えることがあるのは、例えば 68000 用
に次のような最適化を行った場合です。
┌──────────────────────────────────┐
│ ; 最適化前 ; 最適化後 │
│ subA: bsr.s subC subA: bsr.s subC │
│ bra.s @f .dc.w $303C │
│ subB: bsr.s subD → subB: bsr.s subD │
│ @@: clr.w d0 clr.w d0 │
│ : : │
│ rts rts │
└──────────────────────────────────┘
最適化後にある $303C は move.w #imm,d0 のオペコードです。ここで d0.w
を犠牲にして直後の bsr.s subD を飛び越えています(後の clr.w d0 で d0.w
が消去されるので d0.w を破壊しても構わない)。
68000 の場合、bra.s は 10 クロックで move.w #imm,dn は 8 クロックです
から、最適化前よりも最適化後のほうが 2 クロック少なくなっています。つま
り、68000 用の最適化としては間違っていません。
ところが、上の例の最適化後のコードを 68060 で実行するとき、bsr.s subD
が分岐キャッシュに乗っている状態で $303C が実行されると、分岐予測エラー
が発生してしまいます。なぜなら、 $303C は分岐命令ではないのにその途中で
分岐キャッシュがヒットしてしまうからです。つまり、subB を呼び出してすぐ
に subA を呼ぶと、バスエラーの白帯が出てプログラムが止まってしまうのです。
従来のプログラムでこれに該当するようなものは滅多にないと思いますが、念
のため注意して下さい。
●分岐キャッシュが更新される命令
68060 で分岐キャッシュが更新される命令は以下の 10 通りです。
┌──────────────────────────┐
│ Bcc.swl BRA.swl BSR.swl │
│ DBcc.W DBRA.W │
│ FBcc.wl │
│ JMP (d16,PC) JMP xxx.wl │
│ JSR (d16,PC) JSR xxx.wl │
└──────────────────────────┘
ここで、Bcc.S、BRA.S、BSR.S の 3 つ以外は必ず 2 ワード以上あるので、
68000 用の最適化ではほとんど該当しないと思われます。
●分岐予測エラーからの復帰
分岐予測エラーが発生しても、68060 専用のアクセスエラーハンドラを用意す
れば処理を続行できることがあります(分岐予測エラーはアクセスエラーの
FSLW の BPE(Branch Prediction Error)で示されるのですが、WE(Bus Error
on Write)が同時にセットされる理由がよくわかりません)。
●まとめ
分岐予測エラーは、オペランドワードで分岐命令を飛び越えている部分がある
プログラムで発生することがあります。プログラムを書くときは、できる限り分
岐予測エラーを発生させないように注意して下さい(68060 専用のアクセスエラ
ーハンドラを用意しても、バスエラーのベクタを乗っ取られたらおしまいです)。
「普通に実行するとバスエラーで止まるが、データキャッシュや命令キャッシ
ュの状態に関係なく分岐キャッシュだけ禁止すると動く」という場合は、分岐予
測エラーの発生が考えられます。
(EOF)