ブログが長らく休止状態になっていたのですが,現在,nlccという完全独自のCコンパイラを開発しています.
https://kozos.jp/nlcc/

nlの意味のひとつは「No Learn, No Listen」で,「何も見ず,聞かず,参考にせずに作る」です.まあ特別そうした確固たるポリシーがあるとかではないですが,そういうやりかたで作ってみたら面白い…というか独自性あるものになるかもと思って,そういうやりかたで作っています.

なのでおそらく,実装や用語や考え方が独自になっている部分が多いと思います.

前段階として,nlshという独自シェル(見ためはtcsh互換)と,nllibcという独自の標準Cライブラリを開発していて,それらと合わせた形で「nlux」として配布しています.

 

一応,gcc(に含まれる,cc1相当)の代替となることを目指して開発しています.

 

nlccやnlshは,nllibcを利用することで,システム標準のライブラリを一切使わずにビルドすることができます.ライブラリ的に完全に閉じてビルドできる,ということです.nllibcはスタートアップやシステムコールラッパーも持っているので,システムが持つそれらも不要です.
さらにnlcc/nlsh/nllibcも,nlccでコンパイルできます.
つまり,nllibcを使ってnlccをビルドして,そのnlccを使ってnllibcをビルドして,さらにそのnllibcを使ってnlccをビルドして...ということができます.

もちろん,システム標準のライブラリ(libc)を使ってビルドしたり,gcc/clang等を使ってビルドすることも可能です.

また,ヘッダファイルはシステム標準のものを使うが,ライブラリの本体はnllibcを使う,という方法でビルドすることも可能です.(ただこの対応はシステム依存部がややこしくなるので,将来的に廃止するかもしれない)

システム標準のヘッダファイルをインクルードしたファイルを,コンパイルすることもできます.(つまりFreeBSDやDebianが持つヘッダファイルもコンパイルを通すことができる,ということです)

FreeBSD/Debian/CentOSでのビルドに対応しています.(ただCentOS対応は将来的に廃止するかもしれない)
要するに,組合せ自由でビルドできる,ということです.

nlccの最大の特徴は,「アーキテクチャ対応する際の対応必要部分を最小限にしてある」という点です.
数百行程度のファイルを用意すれば,それで新規アーキテクチャに対応できます.
数百行のファイルを用意するだけで新しいアーキテクチャに対応できるとしたら,すごく面白いんではないかなと.

 

というように,nllibc使ってシステムのライブラリ使わずビルドできる,組合せ自由でビルドできる,アーキテクチャ対応しやすい,などといった特徴がありますが,まあ大熱血アセンブラ入門の著者がCコンパイラ作ったらこんなふうになるだろう,という考えでそうしてみました.

アーキテクチャ対応しやすいというのは,アーキテクチャ全体を俯瞰して処理や設計を極力共通化することと,ビルトインを充実させることで実現されています.
アーキテクチャ対応する際には,処理に応じたアセンブリの命令を登録するのですが,登録が面倒ならば未登録にしておけば,ビルトインで等価の処理をしてくれます.(もしくは等価の別処理(!=は==の演算での別処理に置き換えるとか)にしてくれます)
たとえばかけ算や割算は,命令を登録しなくてもOKです.登録しなければ,ビルトインが使われます.まあソフトウェア計算になるので要するにループ回した計算になるのでたいへん遅くなりますが,それでもとりあえず動くコードを生成してくれますし,対応の初期はとりあえずビルトインにしておいて検証して後できちんとした命令を登録する,ということが可能です.
まあもちろん,ビルトインが存在する処理に限られます.今のところシフト演算・かけ算・割算・剰余算・ビット反転(~n)・符号反転(-n)はビルトインに置き換え可能,符号拡張・比較演算の一部(==と<以外)は等価の別処理に置き換え可能です.つまりこれらは対応しなくても,とりあえずアーキテクチャ対応することはできます.

 

可変長引数,ビットフィールド,構造体の引数渡しにも対応しています.

(構造体の戻り値にも対応しているが,開放済みスタックを利用しているので不十分だがまあとりあえずは動くと思う)

 

現状,以下のアーキテクチャに対応しています.
x86/x86_64 (実際に動作し,テストセットがすべて通りnlcc自身をセルフビルドできるレベル)
AArch64/ARM/MIPS/PowerPC/Thumb/MIPS16 (とりあえずアーキテクチャ対応のファイルを用意し,アセンブリは出力できるが未検証,というレベル)
OSECPU (実験的実装のレベル)

 

nllibcも様々なアーキテクチャに対応しているので,原理的にはARMやMIPS上でもnllibc使ったセルフビルドができるはず...
(ただしnlccはコンパイラのみなので,プリプロセッサ・アセンブラ・リンカは別途必要)

64ビット対応はしてありますが,ホストが32ビットの場合には,long long のような64ビット値は64ビット値でなく,32ビット値として扱われます.(sizeofでは64ビット値として扱われるが,演算などは32ビットで行われる.なのでひとまず動作はするという感じ)

多種アーキテクチャを意識しているというのはあるのですが,そのぶん,最適化というものをほとんど一切していなくて,生成されるアセンブリの効率は悪いです.
gccでビルドしたnlccと,nlccでビルドしたnlccで,コンパイル速度を比較すると,明らかに遅いです.
原因はいろいろわかってはいるのですが,多種アーキテクチャに対応しやすいことを優先させていて,とりあえず速度向上の改良は後回しとしています.