chibicc compiler を6800向けに改造する (14) アドレッシングと最適化(2)
chibicc compiler を6800向けに改造する (5) アドレッシングと最適化 の続き。
MC6800で良いコードを生成するには、Acc A,B と IX,SP の使い分けが必要だと書いたが、もっと場合分けが必要なことに気がついた。
1つは2バイト操作をIXで処理する場合、もう1つはlong/floatを処理する内部ルーチンへのパラメータ渡しである。
2バイト処理はIXをなるべく使いたい
グローバル変数 int x, ローカル変数 int yがあるときに、 x=y+1 のような処理はどのようにすると良いか。
2025/11/09 現在の chibicc-6800 では、このようなコードが生成される。
ldx @bp ldab 1,x ldaa 0,x addb #<1 adca #>1 stab _x+1 staa _x
IXを使えば簡潔で速くなる。これを処理するには右辺がIXだけで生成でき、左辺の処理にIXが不要であることを知らないといけない。
ldx @bp ldx 0,x inx stx _x
if式の中もIXを使いたい
if (y!=1) や if(y-1) のような式も同様である。どちらもy!=1のときに、本体を実行する。
前者は現在の chibicc-6800 でも最適化できていて、このようなコードになる。
ldx @bp ldx 0,x dex jeq L_else_1
後者はこうなってしまう。同じコードで良いのに。
ldx @bp ldab 1,x ldaa 0,x subb #<1 sbca #>1 aba adca #0 jeq L_else_1
内部ルーチンへのパラメータ渡し
longやfloatを扱う場合、特定の場所にある値をワーク領域(@long)に読み込む処理が必要である。
領域がglobalな場所であったり、IXレジスタで示される領域(オフセットが0)であれば、IXレジスタに先頭のアドレスを入れてサブルーチンコールすれば良い。
問題は、ローカル変数のときで、大抵の場合はオフセットは0ではないので、パラメータとしてIXとオフセットの両方を渡す必要がある。
しかも、サブルーチン側では両方の加算処理(6命令)を行なってから処理をする必要がある。無駄すぎる。
アドレス計算の結果はAccABに入るので、これを直接渡した方がまだマシである。AccABからIXへ転送が必要だが、3命令で済む。
もっと言えば、ローカル変数であれば単にオフセットを渡して、サブルーチン側で@bpと加算すれば、呼び出し側のサイズが小さくなる。そうすべきである。
結局のところ、単にAccAB、IXを使うかどうかだけではなく、もっと細かい場合わけが必要である。
- 定数0
- 2バイト定数(IXが使える)、グローバル変数のアドレスも含む
- IXだけで直接指定できる(off=0)
- IXだけで指定できる(off=1〜255の固定値)
- IXと可変オフセット(必要?)
- IXだけで計算できる(定数との同値比較、+1,-1)
- @bpとオフセットで指定できる(オフセット固定)
- @boとオフセットで指定できる(オフセット可変)
- AccABだけで計算できる
- AccABとIXの両方が必要(ローカル配列のアドレス計算など)
これ場合わけするのはさすがに難しいな……どうしたものか

ディスカッション
コメント一覧
まだ、コメントがありません