* HLX-001 -(by [[K]], 2021.06.20) ** (0) -HLXは、[[a21_txt01]]やその続編で作ったHLシリーズ(はりぼて言語)をベースに、[[K]]が望む理想の言語を作るプロジェクトです。 --中・長期の目標は[[a21_hlx000]]に書いてあります。 -HLX-001はその最初のバージョンです。 ** (1) 概要 -(以下は現時点での予定です) -[1] HL-9a, HL-16b, HL-22bを統合します(ひとつの実行ファイルにします)。これで以下のようなことができるようになります。 --x86版で普通のインタプリタとJITコンパイラの実行速度の比較が簡単にできます。x86用のアセンブラ出力だけではなく、x64用のアセンブラ出力もできます。 --x64版でも同様のことができます。 --x86でもx64でもない環境でも、普通のインタプリタによる実行はでのできますし、x86やx64のアセンブラ出力もできるので、クロス開発環境としても使えます。 --この3つを統合して、どのくらいの行数になるか、どのくらいのサイズになるか(実行ファイルが)、それも確認してみたいと思っています。 -[2] HL-16bやHL-22bのJITコンパイラでは、簡略化のためにJcc命令がすべてnear-jmpになっていました。しかしHLX-001では、距離が短い場合にはshort-jmpを使うようになり、コードがよりコンパクトになります。 -[3] HLシリーズでは簡略化のためにバッファを固定で確保して、それがあふれてしまったら誤動作するようになっていましたが、HLX-001ではバッファは可変長で、大きなソースコードを扱うときはメモリをたくさん使い、小さい時はメモリを少ししか使わない、そういう処理方法になります。 -[4] 対応できる型を増やすとか、構造体をサポートするとか、ローカル変数をサポートするなどの対応は、HLX-002以降でやります。 ** (2) 内部構造 -プログラムは最初にトークン番号の列に変換された後、中間内部コード列(A)に変換されます。 -(ここまでが上位言語レイヤです。ここまではCPUに依存しません。) -(以下は下位言語レイヤです。) -そしてこの中間内部コード(A)から「インタプリタ実行用の中間コード(B)(HL-9aの中間コード相当)」「x86、x64兼用の共通化された仮想的な機械語(C)」のどちらに変換されます。 --インタプリタ実行の場合は、そのまま実行します。 -x86、x64兼用の仮想機械語(C)は、そこからx86、x64の機械語(D)に変換されるか、もしくはx86用のアセンブラ(E)、x64用のアセンブラ(E)に変換されます。 --(B)はHL-9aの内部コードとほぼ同じです。(D)や(E)はHL-16bやHL-22bが出力していたものとほぼ同じです。 --(A)や(C)が今回新規に導入された中間コードになります。 -[Q] なぜそんなに中間コードを多くしたのか。 -[A] まず中間コードは少ないほうがいいです。そのほうが処理が速くなります。処理もシンプルです。だからHLシリーズでは極力中間層を減らして設計・実装していました。~ しかし、HL-9aで使っていた中間コード(B)は高速に実行するために余計な情報を載せる余地がなくて、それだとJITコンパイルするときには不便です。だからそこに1層だけ増やして、上位レイヤは常に1通りの変換をすればいいようにしました。これが(A)を新設した理由です。これで上位レイヤはシンプルになり、CPU別に作り分ける必要がなくなります。~ 次に、x64の機械語を見ていると、REXプリフィクスの中にレジスタ番号の上位1bitが分離されていて、アセンブル出力するにしても、JITコンパイルのために最適化をするにしても、実にやりにくいです。もっといえば、x86の機械語にしてもmod r/mのバイトの中に3bitだけ命令番号が入っている場合もあります。これだって十分に不便です。これらを解消し、命令体系をシンプルした機械語があれば、おそらく機械語生成はもっと簡単に書けるはずです。そのための中間コードが(C)なのです。