* Essen Rev2 JIT00 -(by [[K]], 2017.07.31) ** JIT00で提供する機能 -ラベルを使えるようにする -CPUに依存するレイヤをここに集約する(JIT01以降はCPUに依存しない) -実際のCPUのレジスタ数がいくつであるかなどの制約を受けずに済むようにする ** 基本仕様 -l# : ローカル変数(#=0~) -g# : グローバル変数 -p# : ポインタレジスタ(p0~p7しかない) -L# : 分岐先指定などに使うラベル -ローカル変数、グローバル変数には、どんな型の値でも代入できる。なぜならEssenは値が型を持つ言語だから。 -ポインタレジスタはポインタしか代入できない。 -基本構文 命令 パラメータ1 パラメータ2 ... -人間にとって書きやすい構文にしようとしていない。どうせこれはJIT01から渡されてくる中間言語でしかない。 --だからコメントやマクロなどはない。 -パラメータはスペース区切り(コンマはいらない) -命令の命名規則 --最初の一文字はnかs。nはノーマル。sはスピード優先。 --二文字目はパラメータの数。 --末尾には型を表す接尾子が入る場合がある。 -例1: n0sysEnt // JITコードの先頭に入れるべきコード、レジスタを初期化する s2limm_s32 g0 0 // g0の定数0を代入 n1label L0 // ここをL0とする s2addi_s32 g0 1 // g0 += 1 s4cjmpi_s32 g0 1000000000 1 L0 // 条件ジャンプ命令 if (g0 != 1000000000) goto L0 n0sysRet // JITコードから帰る場合に入れるべきコード -[Q]人間が書くわけじゃない中間言語なのに、どうしてバイナリにしなかったの?テキストなんて生成するのも解釈するのも手間じゃないか。 --[A]その意見には全面的に賛成します。まあひとまずはデバッグを楽にするためにテキストでやっています、くらいの感じで。・・・将来的にはバイナリ化するかもしれません。 ** x86(32bit)版の仕様 -こうでなければいけないということではないが、とりあえず最初のバージョンではこうやって構成した、という例として: -変数は16バイト --型(32bit)、補助属性(32bit)、値(最大64bit) --値が64bitに収まらない場合や可変長の場合は、ポインタを入れておく。 -EAX: テンポラリデータレジスタ -EDI: グローバル変数のベース -EBP: ローカル変数のベース -ESI: ワークエリアのベース -EBX: p0 -ECX: p1 -EDX: テンポラリポインタ --p2~p7はワークエリア内にある -例1は以下のような機械語になる(2017.07.28時点) 60 PUSHAD n0sysEnt BF E8 24 48 00 EDI=.... B8 00 00 00 00 EAX=0 s2limm_s32 g0 0 89 87 08 00 00 00 [EDI+8]=EAX n1label L0 8B 87 08 00 00 00 EAX=[EDI+8] s2addi_s32 g0 1 40 EAX++ 89 87 08 00 00 00 [EDI+8]=EAX 3D 00 CA 9A 3B CMP(EAX,0x3b9aca00) s4cjmpi_s32 g0 1000000000 1 L0 // EAX=[EDI+8]を自動で省略している. 0F 85 E8 FF FF FF JNE L0 61 POPAD n0sysRet C3 RET -[Q]もっと短い機械語を生成しなくていいのか? --[A]もちろんやりたいが、今は他を先に作るべきだと思っているので、今はまだそこには着手しない。