* HLX-001
-(by [[K]], 2021.06.20)

** (0)
-HLXは、[[a21_txt01]]やその続編で作ったHLシリーズ(はりぼて言語)をベースに、[[K]]が望む理想の言語を作るプロジェクトです。
--中・長期の目標は[[a21_hlx000]]に書いてあります。
-HLX-001はその最初のバージョンです。まあHL-23みたいなものです。

** (1) 概要
-(以下は現時点での予定です)
-HLX-001は、HL-9a, HL-16a, HL-22aの3つを統合し、さらに改良を加えたものです。
-統合されているので、モードを切り替えて使います。
--[codemode 0] HL-9a相当の実行モードで、JITコンパイルせずに中間コードを実行します。x86, x64以外でも(ソースからコンパイルすれば)動くはずです。
--[codemode 1] HL-16a相当の実行モードで、x86の32bitの機械語をJITコンパイラで生成します。64bit版でもこのモードを利用することができますが、64bit版は32bit用の機械語を実行できないので、 codedump 1 で機械語を表示することしかできません(将来のバージョンではアセンブラも出力できます。)
--[codemode 2] HL-22a相当の実行モードで、x64の64bitの機械語をJITコンパイラで生成します(MS-Windows系のABI)。32bit版でもこのモードを利用することができますが、32bit版は64bit用の機械語を実行できないので、 codedump 1 で機械語を表示することしかできません(将来のバージョンではアセンブラも出力できます。)
--[codemode 3] HL-22a相当の実行モードで、x64の64bitの機械語をJITコンパイラで生成します(System V系のABI)。以下同文。・・・しかし、codemode 3は全くデバッグしてないので、このバージョンではきちんと動かないかもしれません。

-[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ではバッファは可変長で、大きなソースコードを扱うときはメモリをたくさん使い、小さい時はメモリを少ししか使わない、そういう処理方法になります。
-http://k.osask.jp/files/hlx001a.zip (75.3KB)
--[内容物]
--hlx001_32.exe : 32bit版の実行ファイル(21.5KB)
--hlx001_64.exe : 64bit版の実行ファイル(29.0KB)
--mandel.cなどのサンプルプログラム
--hlx001src/
---hlx001.c (935行) - ソースコードから共通中間コードに変換
---esvm.c (945行) - 共通中間コードを最適化する
---esvm_run.c (200行) - 共通中間コードをインタプリタで実行
---esvm_x864.c (1027) - 共通中間コードをx86/x64の機械語に変換

-[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)なのです。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS