Tiny C Compiler written in Python 2.
Tiny C のコードを入力して, アセンブリ言語のコードを出力する.
出力形式は NASM (x86) と LLVM Assembly である.
- Tiny C 標準 (参考文献1を参照のこと)
- コメント /* Comment */
- 加算代入演算子 (+=) / 減算代入演算子 (-=)
- 前置増分演算子 (++) / 前置減分演算子 (--)
利用する命令
- NASM
- COMMON
- EXTERN
- GLOBAL
- x86 (IA-32)
- 演算子
- add
- and
- dec
- idiv
- imul
- inc
- neg
- or
- sub
- xor
- Call
- call
- ret
- Jump / Test
- cmp
- je
- jmp
- jz
- sete
- setg
- setge
- setl
- setle
- setne
- test
- Move
- cdq
- mov
- movzx
- Stack
- pop
- push
- 演算子
llvmpy を用いて, LLVM Assembly のコードを作成し, 最適化パスに渡す.
- 定数計算のコンパイル時実行 (算術/論理/比較)
- 不要な条件分岐の削除
- 重複しているラベルを削除して統合
- 利用されていないラベルの削除
- 重複する EXTERN の削除
- GLOBAL と EXTERN を先頭に括りだし
- jmp 命令後の実行されないコードの削除
- 自身の直後への jmp 命令を削除
- 不要命令の削除
- add R, 0
- sub R, 0
- imul R, 1
- メモリストア直後のロード命令の削除
- アクセスされることのないレジスタ書き込みを削除
- 効率の良い命令への書き換え
- imul R 0 -> mov R 0
- mov R 0 -> xor R R
- inc R -> add R 1 (参考文献6の3.5.1.1)
- dec R -> sub R 1 (参考文献6の3.5.1.1)
- ebp 相対アクセスを esp 相対アクセスに書き換え
llvm-as-3.3 < /dev/null | opt-3.3 -disable-output -debug-pass=Arguments -std-compile-opts
で出力されるパスと同じものを使用.
-targetlibinfo -no-aa -tbaa -basicaa -notti -preverify -domtree
-verify -globalopt -ipsccp -deadargelim -instcombine -simplifycfg
-basiccg -prune-eh -inline-cost -inline -functionattrs
-argpromotion -sroa -domtree -early-cse -simplify-libcalls
-lazy-value-info -jump-threading -correlated-propagation
-simplifycfg -instcombine -tailcallelim -simplifycfg -reassociate
-domtree -loops -loop-simplify -lcssa -loop-rotate -licm -lcssa
-loop-unswitch -instcombine -scalar-evolution -loop-simplify
-lcssa -indvars -loop-idiom -loop-deletion -loop-unroll -memdep
-gvn -memdep -memcpyopt -sccp -instcombine -lazy-value-info
-jump-threading -correlated-propagation -domtree -memdep -dse
-adce -simplifycfg -instcombine -strip-dead-prototypes -globaldce
-constmerge -preverify -domtree -verify
$ pip install git+https://github.com/litesystems/tinyc.git
$ tcc -h
LLVM IR のコードを出力するためには, 追加で LLVM 3.3 と, llvmpy 0.12 が必要である. llvmpy は setup.py の requirements にあえて指定していないので手動でインストールする.
$ export LLVM_CONFIG_PATH=/path/to/llvm-config
$ pip install llvmpy
複数のサンプルコードを準備している.
LLVM Assembly 出力のテスト用コード. Makefile
を環境に応じて適宜修正すること.
$ make clean dots test
とすると, 以前のコンパイル結果の削除 /
コンパイル処理 (構文��木出力を含む) / Graphviz 用の dot ファイルの出力 /
テストの実行と結果の出力を行う.
NASM 出力のテスト用コード. Makefile
を環境に応じて適宜修正すること.
$ make clean test
とすると, 以前のコンパイル結果の削除 /
コンパイル処理 (構文��木出力を含む) / テストの実行と結果の出力を行う.
某所での最終報告会用のテストコード. all
と tcln
を環境に応じて適宜修正すること.
$ ./all
でコンパイル処理とテストの実行と結果の出力を行う.
- OS X
- NASM 2.11.05
- clang 3.3
- llvmpy 0.12.4
- Debian jessie/sid
- NASM 2.11
- clang 3.3
- GCC 4.9.0
- llvmpy 0.12.4
- 計算機科学実験及演習 3(ソフトウェア)実験資料
- 湯浅太一, コンパイラ (情報系教科書シリーズ), 昭晃堂, 2001
- IA-32 インテル® アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、上巻: 基本アーキテクチャー
- IA-32 インテル® アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 A: 命令セット・リファレンス A-M
- IA-32 インテル® アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 B: 命令セット・リファレンス N-Z
- インテル® 64 アーキテクチャーおよび IA-32 アーキテクチャー最適化リファレンス・マニュアル
- PLY (Python Lex-Yacc)
- Atul's Mini-C Compiler
- LLVM 3.4 Documentation
- llvmpy 0.12.4 documentation
- OS X ABI Function Call Guide