15.命令追加
残念ながらドライストーンは走りませんでした。原因は、10BYTE命令が出現してしまったからです。当面FPGA内RAMしか使うつもりはなかったので、多くても32KBスペースだから、Displacement:24命令をGCCは、吐かないだろうと期待していたのですが、見事にはずれました。(一体どうなっているのでしょう。Displacement:16で充分のはずですが。)
仕方ないのでインプリメントしてみます。マイクロコードの設計がよかったので、マイクロコード変更でいけそうです。ついでに、詳しく命令の追加方法について見ていきましょう。
<問題>
H8プロジェクトのフェッチハードウェアは、8Byte単位です。10Byte命令は、どうすればいいのでしょうか?また、あのウンザリするマイクロコード全体を書き換える勇気はありません。なんとか、マイクロコードフォーマットを変更せずに対応したいです。どうすれば、よいでしょう?
ヒントは、命令フォーマットにあります。
mov.l ERs,@(d:24,ERd)と、STC ERs,@(d:24,ERd)は、10Byte命令、mov.w ERs,@(d:24,ERd)は、8Byte命令です。10Byte命令を2Byte <<
すると下のインプリメント済み命令に似た形になる所がミソです。
従って、1回目のFetchの最初のステートで、PC++、NOP IR待ちを行います。最初の16ビットフィールドでしか、STCとmov.lは区別がつかないので、ハードフラグを追加します。フラグをSetして後は、レジスタフィールドを含まれないので捨ててもOKです。2回目のIRは、あたかもmov.w...に見えますが、ステートインクリメントは継続させ、mov.w..が使用していないステートで、デコードを継続すれば、いいのです。
命令 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
mov.l ERs、@(d:24,ERd) | 8'h01 | 8'h00 | 8'h78 | 1'b1,ERd,4'h00 | 8'h6b | 4'ha,1'b0,ERs | 8’h0 | 24ビットdisplacement | ||
STC CCR,@(d:24,ERd) | 8'h01 | 8'h04 | 4'ha,4'h0 | |||||||
mov.w Rs,@ (d:24,ERd) |
8'h78 | 1'b0,ERd,4'h00 | 8'h6b | 4'ha,Rs | 8’h0 | 24ビットdisplacement |
ステート数は、かなり多くなってしまいますが、10BYTE命令の出現頻度は低いのでパフォーマンスにも影響しないでしょう。
以下の命令も上と同様に扱えます。
下段が、類似既インプリメント命令になります。
ところで、LDCとSTCは、前半のデコードでは区別できませんので、フラグは共通とします。また、STCだけを考えれば、ステート数は短くてもいいのですが、LDCとSTCが区別できないために、2nd Decodeでは、最長ステート(LDC)に合わせた待ち合わせを行います(NOP挿入)。結果、この4命令(10バイト命令全部)については、6-8ステートになります。
命令 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
mov.l @(d:24,ERs),ERd | 8'h01 | 8'h00 | 8'h78 | 1'b0,ERs,4'h00 | 8'h6b | 4'h2,ERd | 8’h0 | 24ビットdisplacement | ||
LDC @(d:24,ERs),CCR | 8'h01 | 8'h40 | 4'h2,4'h0 | |||||||
mov.w @(d:24,ERs), Rd | 8'h78 | 1'b0,ERs,4'h00 | 8'h6b | 4'h2,Rd | 8’h0 | 24ビットdisplacement |