Fuzix-Compiler-Kitの6800用コンパイラ(8) peep hole optimizer(1)
EtchedPixels/Fuzix-Compiler-Kit: Fuzix C Compiler ProjectのCコンパイラには、peephole optimizer (のぞき穴的最適化プログラム)が付属している。
このoptimizerはZ80用のz88dkや、6809用のacwjでも使われている汎用的なツールである。アセンブラプログラムを簡単なパターンマッチで操作できる。
- Fuzix-Compiler-Kit/copts.c at main · EtchedPixels/Fuzix-Compiler-Kit
- z88dk/src/copt at master · z88dk/z88dk
- acwj/64_6809_Target/cpeep.c at master · DoctorWkt/acwj
fcc付属オプティマイザーの使い方
オプティマイズ用のルールは rules.CPU名 というファイル名で置かれている。6800用は rules.6800 である。
rules.6800の中には最低限のルールが書かれている。peephole optimizerで頑張りすぎると全体の見通しが悪くなるので、ルールを減らしている。バグがでたときに解析不能になるし。
簡単な例
次の例は、直後のラベルへの無条件ジャンプを消し去るルール。
ルールは、 = を挟んで前後に記述する。ルール間の区切りは空行。# がコメント。%0-%9がパターンマッチに使える。タブと空白は区別される。
ルール間の区切りが空行なのは少しわかりにくい。acwjのcopt(acwj/64_6809_Target/lib/6809/rules.6809 at master · DoctorWkt/acwj)は、====を区切りにするように改良されている。
# Branches jmp %1 %1: = %1:
%0-%9によるマッチング
%0-%9があると、置き換え前のパターンに入れて、置き換え後に使える。
探すパターンに正規表現が使えないし、場合分けもできないのが面倒。6800のアドレッシング別に処理をしたい場合は、 ,x や # などを書いて区別する必要がある。
ldx #%1 stb %2,x = stb %1+%2
%L,%M,%N
ラベル生成用の特殊変数。書き換え後にラベルが必要となったときに使える。使うたびに +1 される。
%L,%M,%N の3種類使えて、通常の用途では足りるはず。
pshb psha clra ldab %1 jsr __cclteq ; jeq %2_%3 = subb %1 sbca #0 jgt %2_%3 jlt M%M_cc ; jsr __cclteq tstb jne %2_%3 M%M_cc:
%activate
書き換えたい箇所と、書き換えのきっかけになる箇所が離れているときに使う。
下記の例では %1: jeq %2 というコードを見つけたら、jeq %1命令をjeq %2に書きかえる条件を生成(activate)する。
最初の%activateで、%activate %jeq %1 = … が起動され、それを元に書き換えが行われる。すごくわかりにくい。
activateを一度だけ行う場合は %once。
%1: jeq %2 = %activate %2: = %%activate jeq %1 = jeq %2 ; jmp destination change from %1 to %2
%check
パターンマッチで使った変数 %0-%9 が特定の範囲内のときだけ、書き換えを行う。
比較の <= は、変更できない。< などに置き換えるとエラーになる。 z88dk/lib/z80rules.1 at master · z88dk/z88dkが参考になる。
%check min <= %n <= max
%check 0 <= %1 <= 65535 ld l,(hl) ld h,0 ld de,%1 ex de,hl = ld e,(hl) ld d,0 ld hl,%1 ;const
%eval
逆ポーランド記法(RPN)で書かれた式を評価する。
数値、+ * | & > < / %
> < はシフト(2項演算)
% はパラメータ変数
%% は 剰余演算
ld (hl),%eval(%1 256 %%) inc hl ld (hl),%eval(%1 256 /) ld hl,%2
ディスカッション
コメント一覧
まだ、コメントがありません