* OSECPU-VMのレジスタ -(by [[K]], 2014.08.04) ** (0) -rev2になって浮動小数点レジスタが追加されたり、ローカルレジスタが増えたり、m32規格ができたたりで、分かりにくくなったかもしれないので、ここに情報をまとめます。 ** (1) 標準構成のレジスタ -Rxx : 整数レジスタ (全64本) --符号付き整数レジスタで、特にビット幅は規定されておらず、アプリが必要なビット幅を演算ごとに指定する仕様になっています。 --VMは指定されたビット幅か、もしくはそれを超えるビット幅で演算することを保証します。 --VMにとってサポートできないビット幅が指定されたときは、しょうがないのでエラーになりますが、これはJITC段階で検出できるとします。もちろんそれはアプリの不備ではなくてVMの責任です。 --なおASKAはあまり頭がよくないので、無条件に32ビットのビット幅を指定しています。ですからとりあえず32ビットに対応しておけば、現行のほとんどすべてのアプリは問題なく実行できることになります。 --R00~R27 : ローカルレジスタ。関数の中で自由に使えます。呼び出し元のR00~R27には影響を与えません。 --R28~R2B : グローバルレジスタ(アプリ用)。全関数を通じて共有されているレジスタです。用途はアプリが自由に決められます。 --R2C~R2F : グローバルレジスタ(システム用)。全関数を通じて共有されているレジスタです。用途はシステムが決めているのでそれに従ってください。 --R30~R3B : テンポラリレジスタ。演算時の一時的な値や、関数の引数や返値の受け渡しなどに使われます。値はすぐに壊れます。 --R3C~R3F : 特殊レジスタ。VMが特別な用途で使うレジスタで、アプリが自由に使うことはできません。 -Pxx : ポインタレジスタ (全64本) --メモリを指し示すことができるレジスタで、ビット数などは一切規定されていません。ポインタレジスタの値を整数レジスタに入れることはできないので、ビット数が不明なことは何の問題も生じません。 ---メモリなどを経由しても、ポインタレジスタの値を読み取ることはできません。ただし2つのポインタの差を取って、その値を整数値で得ることはできます。 --P00~P27 : ローカルレジスタ。 ---ただしP00はベースポインタとして使われる予定なので、P01以降を使ってください。 --P28~P2B : グローバルレジスタ(アプリ用)。 --P2C~P2F : グローバルレジスタ(システム用)。 --P30~P3B : テンポラリレジスタ。 --P3C~P3F : 特殊レジスタ。 -Fxx : 浮動小数点レジスタ(floatレジスタ) (全64本) --浮動小数点値を保持できるレジスタで、ビット数は32か64かそれ以上です。 --このレジスタをサポートしないVMもあり得ます。 --F00~F27 : ローカルレジスタ。 --F28~F2B : グローバルレジスタ(アプリ用)。 --F2C~F2F : グローバルレジスタ(システム用)。 --F30~F3B : テンポラリレジスタ。 --F3C~F3F : 特殊レジスタ。 -DRx : デバッグレジスタ (全4本:将来増やすかもしれません) --アプリはこのレジスタに符号付き整数の定数のみを代入することができます。しかし代入した値を参照することはできません。基本的には、現在はソースコード上の○○行目を実行していますよ、ということを示すために使います。 --DR0 : 行番号情報 --DR1 : モジュール番号(DLLなどが入り乱れても区別できるように) --DR2 : 未定 --DR3 : 未定 --これらのレジスタもビット数は規定されていません。基本的にプログラムが指定した値を確実に保持できることが期待されています。保持できない長さのデータが指定されたときは、VMのJITC時のエラーとしてください。 ** (2) m32構成のレジスタ -標準構成との差異のみを記述します。 -Rxxレジスタはすべて32ビットに固定化されます。 -Fxxレジスタはすべて32ビットに固定化されます。 -DRxレジスタはすべて32ビットに固定化されます。 ** (3) テクニック的なこと -R3Fは、直後の命令のimmの代わりに使われます(バックエンドのバイトコードの話です)。したがってR3Fは即値しか代入できませんし、直後の命令以外では参照できません。 --フロントエンドコードでは命令にimmが使えますが、それらはすべてR3Fを使ったバックエンドバイトコードに展開されています。 -P3Fへの代入は、ジャンプ命令として扱われます。 -関数呼び出しに際して、OSECPU-VMはスタックを使いません。P30にリターンアドレスを代入してから、P3Fに関数のアドレスを代入して分岐します。つまり「終わったらここに帰ってきてください」という場所を引数として渡しているようなものです。 -P2Fには、API関数のポインタが入っています。ここを呼び出すとAPIが使えます。 * こめんと欄 #comment