Scheme Compiler の勉強 (10) - Unary Primitives (fxadd1)

  • scheme 流の define-syntax はエレガントだけど今のところとても使い辛い。式を変形したいだけであって、別にパターンマッチをしたい訳じゃないんだよなぁ。
  • define-syntax でうなっているうち、そもそも根本的に勘違いしていることに気付いた。define-syntax の勉強は後回し。

1.3 Unary Primitives について。ここはかなり大きな固まりで、少しずつ実装して試す、ということがし辛い。もう一段階分解しても良いと思う。

fxadd1 について。

  • $fxadd1 ($を付けている理由が書いていない、、内部関数との違い?)の定義。
    • まず与えられた値を、 return value register %eax に格納するコードを吐く。(=emit-expr)
    • 次に %eax の値を1ふやすコードを吐く。
    • ret を吐く。
    • ただし、このコンパイラーでは、30bit 部分だけを fixnum として使う世界なので、数値も変換してやる。
  • テストスイート tests-1.3-req.scm は、($fxadd1 1) => 2 だけじゃなく、($fxadd1 ($fxadd 0)) => 2 も要求している。
  • ということは、 emit-expr はこの時点で再帰的に呼び出されなくちゃならない。再帰構造は emit-expr の中に含まれている。
    • 0 を %eax に格納するコード
    • %eax を1増やすコード
    • %eax を1増やすコード

LLVM だと特に %eax に相当するものは存在しない。ターゲットとなるマシン毎に適当に変換してくれる。いまの教材に合わせたいので、適当に %ret という変数を作って、それを fxadd1 が更新するようにした※(かなり怪しいことをやっている可能性大)。
さらに LLVM の世界では「単一静的代入」らしいので※(良くわかっていない、注意)、$fxadd1 の中で使う「変数」名は毎回変えてやるようにした。

これでようやく、 tests-1.3-req.scm の最初の部分のテストが通った。

Performing fxadd1 tests ...
test 110:($fxadd1 0) ... ok
test 111:($fxadd1 -1) ... ok
test 112:($fxadd1 1) ... ok
test 113:($fxadd1 -100) ... ok
test 114:($fxadd1 1000) ... ok
test 115:($fxadd1 536870910) ... ok
test 116:($fxadd1 -536870912) ... ok
test 117:($fxadd1 ($fxadd1 0)) ... ok
test 118:($fxadd1 ($fxadd1 ($fxadd1 ($fxadd1 ($fxadd1 ($fxadd1 12)))))) ... ok
;; (fxadd1 7) をコンパイル
gosh> (build-program '($fxadd1 7))
#<undef>
stst.s: 生成された LLVM のコード

define i32 @scheme_entry() nounwind {
entry:
    %ret = alloca i32
    store i32 28, i32* %ret
    %val16 = load i32* %ret
    %tmp16 = add i32 4, %val16
    store i32 %tmp16, i32* %ret
    %retval = load i32* %ret
    ret i32 %retval
}
stst.n.s: さらに変換された PowerPC 用のアセンブラ
	.machine ppc7400
	.section __TEXT,__textcoal_nt,coalesced,pure_instructions
	.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16
	.text


	.globl	_scheme_entry
	.align	4
_scheme_entry:
	li r2, 28
	stw r2, -4(r1)
	li r3, 32
	stw r3, -4(r1)
	blr 

	.subsections_via_symbols

いかにもどんくさそうな気がするが、とりあえず前に進もう。そのうち最適化とか出てくるから。


続く、はず。