Z80/8080をベースにしたオリジナルのCPUを考えています。
http://d.hatena.ne.jp/nowokay/20130121#1358765504
これを、次のようなコードに分解するわけです。
http://d.hatena.ne.jp/nowokay/20130122#1358829249
ここで、実行フェーズとメモリ読み込みをどうするかということを考えてみます。
大まかには、実行フェーズは次のような5フェーズになります。
命令読み込み→デコード→実行→メモリ読み書き→レジスタ割り当て
ここで問題になるのは、オペランドの読み込みで、8ビット命令なら1バイト、16ビット読み込みの場合は2バイトほどを、命令のほかに読み込む必要があります。
そこで今回は、デコード時に1バイト目、そして2バイト目が必要であれば実行時に読み込むことにします。オペランドは、パラメータ1に読み込むことにします。
4bit | 1bit | 1bit | 1bit | 3bit | 16bit | 16bit | 4bit | 16bit |
---|---|---|---|---|---|---|---|---|
操作 | 8/16bit | 出力有無 | オペランド2バイト目有無 | 条件(フラグ) | パラメータ1 | パラメータ2 | 出力レジスタ | PC |
こう考えると、実は LD (HL), nnのような、間接16ビット読み書きというのは実現できないのだなーと思ったりします。
このようにすると、各フェーズをパイプライン化して並列実行ということはできなくなるのですが、そもそもパイプライン化はメモリアクセスの効率をよくするために行うので、もとからメモリアクセスの効率がよければ不要ということになります。*1
ところで、こうするとリトルエンディアンであれば8bit命令でも16bit命令でも最初に読み込んだオペランドは必ず下位バイトにもっておけばよくなるので効率的になるのだけど、ビッグエンディアンになるとちょっと不自然な感じになる気がします。
なんでモトローラは68系CPUでビッグエンディアンを採用したんだろう?と思ったり。
*1:追記:この表現は正しくなくて、メモリアクセス速度以上の高速化に意味がないということがいいたかった