Shiba/Shiba VM
をテンプレートにして作成
ホーム
検索
最終更新
ヘルプ
Wiki書式ヘルプ(整形ルール)
開始行:
* Shiba VM [#y3d91a37]
#contents
シンプルでもいける気がしてきた。
** レジスタの概要 [#b2e56c51]
- 1つのレジスタのサイズは8バイト。
- 4バイトでもいいかなと思ったが,64bit環境でポインタが1...
- ただし,メモリがきつきつの環境もあるので32bitモード用意...
- 1つのレジスタはUNIONで表現。
#code(c,){{
struct Register
{
union
{
bool boolVal;
u32 data32;
u64 data64;
s32 i32val;
s64 i64val;
f32 f32val;
f64 f64val;
void* ptr; // 64bit環境だとこれは8バイト。
};
};
}}
** レジスタ構成 [#ka053590]
|Full Name|Short Name|Comment|h
|Stack Register Pointer|SRP|スタックレジスタポインタ。&br...
|Stack Pointer|SP|スタックポインタ。現在のスタック位置。|
|Program Counter|PC|プログラムカウンタ。現在実行している...
|Program Function|PF|プログラムの関数オブジェクトのポイン...
|Program Line|PL|プログラムのソースコードの行数。デバッグ...
|Link Register|LR|リンクレジスタ。戻り先のバイトコードの...
|Function Register|FR|関数レジスタ。全部で16個。FR00 - FR...
#code(c,){{
struct SEVMContext
{
// 関数開始時に保存されるレジスタ達。
struct SaveReg
{
void* srp;
void* lr;
SEFunction* pf;
uint32 pl;
};
SaveReg saveReg;
// 保存されないレジスタ達。
void* sp;
void* pc;
};
}}
** スタックレジスタ [#bb1584f7]
- 計算の一時領域として使うレジスタはStackRegister(スタッ...
- スタックレジスタ数は動的に変更し,最大で256。それを越え...
- SRP(Stack Register Pointer)からのオフセットがスタック...
- SR01ならSRP + 0x08のアドレスとなる。(32bitモードなら+0x...
- 通常,関数の先頭でFUNCET命令を使い関数で使用するスタッ...
** 変数とレジスタ [#w8f36726]
- ローカル変数は全てスタックレジスタに割り当てられる。
- スコープを考慮してスタックレジスタの使用数はなるべく少...
- 一時変数もスタックレジスタに割り当てられる。
#code(c,){{
utility Hoge {
static void func()
{
int a; // SR01
int b; // SR02
{
int c; // SR03
}
int d; // SR02
{
int e; // SR03
}
d = (a + b) * d;
// (a + b)が一時変数としてSR03に格納される
// SR03 = a + b;
// SR02 = R03 * R02;
}
};
}}
** 戻り値とレジスタ [#lb8a56e2]
- 戻り値はFR00に格納される。
- FUNCRT命令が実行されるとSR00の値はFR00にコピーされる。
#code(c,){{
utility Hoge
{
static int GetOne()
{
return 1; // FR00 = 1
}
};
}}
** 引数とレジスタ [#g01df345]
- 引数は関数レジスタのFR01から順番にレジスタに割り当てら...
- 非staticなメンバ関数はFR01にthisポインタが割り当てられ...
- 関数レジスタは16個しか用意されていないので,引数の最大...
|戻り値あり|非staticなメンバ関数|最大引数|h
|x|x|16|
|x|o|15|
|o|x|15|
|o|o|14|
#code(c,){{
pod Vector3
{
float x;
float y;
float z;
void func(float addValue)
{
// FR01 : this
// FR02 : addValue
}
}
}}
** boolとレジスタ [#g2fb75db]
- boolのサイズは環境によって1バイトだったり4バイトだった...
- falseはだいたいの環境で0なので,falseの代入には0の代入...
- trueの代入についてはreg.boolVal = trueで実現する。
** アセンブラのイメージ [#sc9a365f]
- 簡単なコード
#code(c,){{
0:int add(int a, int b)
1:{
2: return a + b;
3:}
4:void func()
5:{
6: int i = 3;
7: i = add(i , 4);
8:}
# 命令コード
Instruction:
add:
DFUNC 0x0000
DLINE 1 // '{'の位置
FUNCET 0x03 0x03
DLINE 2
ADDI32 R00 R01 R02
DLINE 3 // '}'の位置
FUNCLV 0x03
func:
DFUNC 0x0001
DLINE 5
FUNCET 0x02 0x00
DLINE 6
LDSRC4 SR00 0x0000
DLINE 7
LDSRC4 SR01 0x0004
LDFRSR FR01 SR00
LDFRSR FR02 SR01
CALL 0x0000
LDRF SR00 FR00
FUNCLV 0x02
# コンパイル時に確定する定数のテーブル
ConstantTable:
0x0000: 3
0x0004: 4
SymbolTable:
0x0000: int add(int,int)
0x0004: void func()
}}
** 命令コード [#ac30d5cb]
- どの命令コードも32bitで統一。
- SRegおよびFRegはu8。
|命令|書式|コメント|h
|>|>|BGCOLOR(ORANGE):''ロード''|
|LDSRZR|LDSRZR SReg|指定したスタックレジスタをゼロクリア...
|LDSRBT|LDSRBT SReg|指定したスタックレジスタにtrueを代入...
|LDSRC1|LDSRC4 SReg ConstantTableIndex(u16)|ConstantTable...
|LDSRC2|~|~|
|LDSRC4|~|~|
|LDSRC8|~|~|
|LDSRSR|LDSRSR SReg1 SReg2|SReg2の値をSReg1にロード|
|LDSRSP|LDSRSP SReg1 StackPointerOffset(u16)|StackPointer...
|LDSRP1|LDSRP1 SReg1 SReg2|SReg2の値をアドレスとみなし,S...
|LDSRP2|~|~|
|LDSRP4|~|~|
|LDSRP8|~|~|
|LDSROJ|LDSROJ SReg1 SReg2|SReg2の値をobject型とみなし,S...
|LDSRFZ|LDSRFZ SReg|FR00の値をSRegにロード|
|LDFRSR|LDFRSR FReg SReg|SRegの値をFRegにロード|
|>|>|BGCOLOR(ORANGE):''算術演算''|
|ADDI32|ADDI32 SReg1 SReg2 SReg3|SReg1 = SReg2 + SReg3|
|SUBI32|SUBI32 SReg1 SReg2 SReg3|SReg1 = SReg2 - SReg3|
|MULS32|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 * SReg3|
|DIVS32|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 / SReg3|
|MODS32|MODS32 SReg1 SReg2 SReg3|SReg1 = SReg2 % SReg3|
|INCI32|INCI32 SReg1|SReg1++|
|DECI32|DECI32 SReg1|SReg1--|
|NEGS32|NEGS32 SReg1 SReg2|SReg1 = -SReg2|
|>|>|BGCOLOR(ORANGE):''比較演算''|
|LTS32|LTS32 SReg1 SReg2 SReg3|SReg1 = SReg2 < SReg3|
|LES32|LES32 SReg1 SReg2 SReg3|SReg1 = SReg2 <= SReg3|
|EQI32|EQI32 SReg1 SReg2 SReg3|SReg1 = SReg2 == SReg3|
|EQBOOL|EQBOOL SReg1 SReg2 SReg3|~|
|NEI32|NEI32 SReg1 SReg2 SReg3|SReg1 = SReg2 != SReg3|
|NEBOOL|NEBOOL SReg1 SReg2 SReg|~|
|>|>|BGCOLOR(ORANGE):''ビット演算''|
|ANDI32|ANDI32 SReg1 SReg2 SReg3|SReg1 = SReg2 & SReg3|
|ORI32|ORI32 SReg1 SReg2 SReg3|SReg1 = SReg2 | SReg3|
|XORI32|XORI32 SReg1 SReg2 SReg3|SReg1 = SReg2 ^ SReg3|
|NTI32|NOTI32 SReg1 SReg2|SReg1 = ~SReg2|
|NTBOOL|NTBOOL SReg1 SReg2|SReg1 = !SReg2|
|>|>|BGCOLOR(ORANGE):''シフト演算''|
|SLLI32|SLLI32 SReg1 SReg2 SReg3|SReg1 = SReg2 << SReg3|
|SLRI32|SLRI32 SReg1 SReg2 SReg3|SReg1 = SReg2 >> SReg3|
|>|>|BGCOLOR(ORANGE):''分岐命令''|
|JMP|JMP RelativePCPos(s16)|RelativePCPosの値をpcに足す。...
|JMPPOS|JMPPOS SReg1 RelativePCPos(s16)|SReg1がtrueならJM...
|JMPNEG|JMPNEG SReg1 RelativePCPos(s16)|SReg1がfalseならJ...
|>|>|BGCOLOR(ORANGE):''関数あれこれ''|
|FENTER|FENTER AllocSRegNum CopyFRegNum|Function Enter. &...
|FLEAVE|FLEAVE FreeSRegNum|Function Leave. &br;FreeSRegNu...
|CALL|CALL SymbolTableIndex(u16)|LRにPCを代入する。 &br;S...
|CALLVF|CALLVF SReg1 ConstantTableIndex(u16)|Call Virtual...
|>|>|BGCOLOR(ORANGE):''スタック''|
|PUSH|PUSH SReg ConstantTableIndex(u16)|ConstantTableInde...
|POP|POP ConstantTableIndex(u16)|ConstantTableIndexが指す...
|>|>|BGCOLOR(ORANGE):''オブジェクト''|
|OBJNEW|OBJNEW SReg SymbolIndex|Object New.&br;指定のSymb...
|OBJDEL|OBJDEL SReg|Object Delete.&br;指定のSRegが指すオ...
|OBJRFI|OBJRFI SReg|Object Reference Increment.&br;指定の...
|OBJRFD|OBJRFD SReg|Object Reference Decrement.&br;指定の...
|>|>|BGCOLOR(ORANGE):''デバッグ''|
|DLINE|DLINE ConstantValue(u24)|Debug Line.&br;デバッグ情...
|DFUNC|DFUNC SymbolTableIndex(u16)|Debug Function.&br;デ...
** クラス構成 [#lfe85b6e]
*** SEVMCore [#bb572835]
- 仮想マシン本体。
- コンパイル済みの命令コード,ユーザー定義型の初期化デー...
- staticなデータはこいつが持ち,複数のContextで共有するこ...
*** SEVMContext [#uc0127e1]
- コンテキスト。スレッド。
- スタック,レジスタは各ScriptContextがそれぞれ持つ。
** SEVMCore [#hae3d592]
*** 手順 [#i4dc4609]
- セットアップ前準備(ユーザーがやる)
-- コンパイル済みのオブジェクトファイルの追加。
-- 関数,クラス類,変数類のC++とのバインド。
- セットアップ
-- 1) リンク&未解決シンボルのチェック。
-- 2) staticデータに.initデータをコピー。
-- 3) (ver2.0)各クラスのstaticコンストラクタ&static inva...
- ファイナライズ
-- 1) 全Contextが終了していることを確認。
-- 2) ガベージコレクトを実行。
-- 3) (ver2.0)各クラスのstatic invariant()&staticデスト...
-- 4) ガベージコレクトを実行。
-- 5) ゴミが残っていないかチェック。
** SEVMContext [#q24e9b98]
*** 実行開始手順 [#xe3c6b37]
- (ユーザーがやる)
- エントリーポイントとなる関数とその引数を設定。
** その他 [#n8572b2d]
[[./メモ]]
終了行:
* Shiba VM [#y3d91a37]
#contents
シンプルでもいける気がしてきた。
** レジスタの概要 [#b2e56c51]
- 1つのレジスタのサイズは8バイト。
- 4バイトでもいいかなと思ったが,64bit環境でポインタが1...
- ただし,メモリがきつきつの環境もあるので32bitモード用意...
- 1つのレジスタはUNIONで表現。
#code(c,){{
struct Register
{
union
{
bool boolVal;
u32 data32;
u64 data64;
s32 i32val;
s64 i64val;
f32 f32val;
f64 f64val;
void* ptr; // 64bit環境だとこれは8バイト。
};
};
}}
** レジスタ構成 [#ka053590]
|Full Name|Short Name|Comment|h
|Stack Register Pointer|SRP|スタックレジスタポインタ。&br...
|Stack Pointer|SP|スタックポインタ。現在のスタック位置。|
|Program Counter|PC|プログラムカウンタ。現在実行している...
|Program Function|PF|プログラムの関数オブジェクトのポイン...
|Program Line|PL|プログラムのソースコードの行数。デバッグ...
|Link Register|LR|リンクレジスタ。戻り先のバイトコードの...
|Function Register|FR|関数レジスタ。全部で16個。FR00 - FR...
#code(c,){{
struct SEVMContext
{
// 関数開始時に保存されるレジスタ達。
struct SaveReg
{
void* srp;
void* lr;
SEFunction* pf;
uint32 pl;
};
SaveReg saveReg;
// 保存されないレジスタ達。
void* sp;
void* pc;
};
}}
** スタックレジスタ [#bb1584f7]
- 計算の一時領域として使うレジスタはStackRegister(スタッ...
- スタックレジスタ数は動的に変更し,最大で256。それを越え...
- SRP(Stack Register Pointer)からのオフセットがスタック...
- SR01ならSRP + 0x08のアドレスとなる。(32bitモードなら+0x...
- 通常,関数の先頭でFUNCET命令を使い関数で使用するスタッ...
** 変数とレジスタ [#w8f36726]
- ローカル変数は全てスタックレジスタに割り当てられる。
- スコープを考慮してスタックレジスタの使用数はなるべく少...
- 一時変数もスタックレジスタに割り当てられる。
#code(c,){{
utility Hoge {
static void func()
{
int a; // SR01
int b; // SR02
{
int c; // SR03
}
int d; // SR02
{
int e; // SR03
}
d = (a + b) * d;
// (a + b)が一時変数としてSR03に格納される
// SR03 = a + b;
// SR02 = R03 * R02;
}
};
}}
** 戻り値とレジスタ [#lb8a56e2]
- 戻り値はFR00に格納される。
- FUNCRT命令が実行されるとSR00の値はFR00にコピーされる。
#code(c,){{
utility Hoge
{
static int GetOne()
{
return 1; // FR00 = 1
}
};
}}
** 引数とレジスタ [#g01df345]
- 引数は関数レジスタのFR01から順番にレジスタに割り当てら...
- 非staticなメンバ関数はFR01にthisポインタが割り当てられ...
- 関数レジスタは16個しか用意されていないので,引数の最大...
|戻り値あり|非staticなメンバ関数|最大引数|h
|x|x|16|
|x|o|15|
|o|x|15|
|o|o|14|
#code(c,){{
pod Vector3
{
float x;
float y;
float z;
void func(float addValue)
{
// FR01 : this
// FR02 : addValue
}
}
}}
** boolとレジスタ [#g2fb75db]
- boolのサイズは環境によって1バイトだったり4バイトだった...
- falseはだいたいの環境で0なので,falseの代入には0の代入...
- trueの代入についてはreg.boolVal = trueで実現する。
** アセンブラのイメージ [#sc9a365f]
- 簡単なコード
#code(c,){{
0:int add(int a, int b)
1:{
2: return a + b;
3:}
4:void func()
5:{
6: int i = 3;
7: i = add(i , 4);
8:}
# 命令コード
Instruction:
add:
DFUNC 0x0000
DLINE 1 // '{'の位置
FUNCET 0x03 0x03
DLINE 2
ADDI32 R00 R01 R02
DLINE 3 // '}'の位置
FUNCLV 0x03
func:
DFUNC 0x0001
DLINE 5
FUNCET 0x02 0x00
DLINE 6
LDSRC4 SR00 0x0000
DLINE 7
LDSRC4 SR01 0x0004
LDFRSR FR01 SR00
LDFRSR FR02 SR01
CALL 0x0000
LDRF SR00 FR00
FUNCLV 0x02
# コンパイル時に確定する定数のテーブル
ConstantTable:
0x0000: 3
0x0004: 4
SymbolTable:
0x0000: int add(int,int)
0x0004: void func()
}}
** 命令コード [#ac30d5cb]
- どの命令コードも32bitで統一。
- SRegおよびFRegはu8。
|命令|書式|コメント|h
|>|>|BGCOLOR(ORANGE):''ロード''|
|LDSRZR|LDSRZR SReg|指定したスタックレジスタをゼロクリア...
|LDSRBT|LDSRBT SReg|指定したスタックレジスタにtrueを代入...
|LDSRC1|LDSRC4 SReg ConstantTableIndex(u16)|ConstantTable...
|LDSRC2|~|~|
|LDSRC4|~|~|
|LDSRC8|~|~|
|LDSRSR|LDSRSR SReg1 SReg2|SReg2の値をSReg1にロード|
|LDSRSP|LDSRSP SReg1 StackPointerOffset(u16)|StackPointer...
|LDSRP1|LDSRP1 SReg1 SReg2|SReg2の値をアドレスとみなし,S...
|LDSRP2|~|~|
|LDSRP4|~|~|
|LDSRP8|~|~|
|LDSROJ|LDSROJ SReg1 SReg2|SReg2の値をobject型とみなし,S...
|LDSRFZ|LDSRFZ SReg|FR00の値をSRegにロード|
|LDFRSR|LDFRSR FReg SReg|SRegの値をFRegにロード|
|>|>|BGCOLOR(ORANGE):''算術演算''|
|ADDI32|ADDI32 SReg1 SReg2 SReg3|SReg1 = SReg2 + SReg3|
|SUBI32|SUBI32 SReg1 SReg2 SReg3|SReg1 = SReg2 - SReg3|
|MULS32|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 * SReg3|
|DIVS32|MULS32 SReg1 SReg2 SReg3|SReg1 = SReg2 / SReg3|
|MODS32|MODS32 SReg1 SReg2 SReg3|SReg1 = SReg2 % SReg3|
|INCI32|INCI32 SReg1|SReg1++|
|DECI32|DECI32 SReg1|SReg1--|
|NEGS32|NEGS32 SReg1 SReg2|SReg1 = -SReg2|
|>|>|BGCOLOR(ORANGE):''比較演算''|
|LTS32|LTS32 SReg1 SReg2 SReg3|SReg1 = SReg2 < SReg3|
|LES32|LES32 SReg1 SReg2 SReg3|SReg1 = SReg2 <= SReg3|
|EQI32|EQI32 SReg1 SReg2 SReg3|SReg1 = SReg2 == SReg3|
|EQBOOL|EQBOOL SReg1 SReg2 SReg3|~|
|NEI32|NEI32 SReg1 SReg2 SReg3|SReg1 = SReg2 != SReg3|
|NEBOOL|NEBOOL SReg1 SReg2 SReg|~|
|>|>|BGCOLOR(ORANGE):''ビット演算''|
|ANDI32|ANDI32 SReg1 SReg2 SReg3|SReg1 = SReg2 & SReg3|
|ORI32|ORI32 SReg1 SReg2 SReg3|SReg1 = SReg2 | SReg3|
|XORI32|XORI32 SReg1 SReg2 SReg3|SReg1 = SReg2 ^ SReg3|
|NTI32|NOTI32 SReg1 SReg2|SReg1 = ~SReg2|
|NTBOOL|NTBOOL SReg1 SReg2|SReg1 = !SReg2|
|>|>|BGCOLOR(ORANGE):''シフト演算''|
|SLLI32|SLLI32 SReg1 SReg2 SReg3|SReg1 = SReg2 << SReg3|
|SLRI32|SLRI32 SReg1 SReg2 SReg3|SReg1 = SReg2 >> SReg3|
|>|>|BGCOLOR(ORANGE):''分岐命令''|
|JMP|JMP RelativePCPos(s16)|RelativePCPosの値をpcに足す。...
|JMPPOS|JMPPOS SReg1 RelativePCPos(s16)|SReg1がtrueならJM...
|JMPNEG|JMPNEG SReg1 RelativePCPos(s16)|SReg1がfalseならJ...
|>|>|BGCOLOR(ORANGE):''関数あれこれ''|
|FENTER|FENTER AllocSRegNum CopyFRegNum|Function Enter. &...
|FLEAVE|FLEAVE FreeSRegNum|Function Leave. &br;FreeSRegNu...
|CALL|CALL SymbolTableIndex(u16)|LRにPCを代入する。 &br;S...
|CALLVF|CALLVF SReg1 ConstantTableIndex(u16)|Call Virtual...
|>|>|BGCOLOR(ORANGE):''スタック''|
|PUSH|PUSH SReg ConstantTableIndex(u16)|ConstantTableInde...
|POP|POP ConstantTableIndex(u16)|ConstantTableIndexが指す...
|>|>|BGCOLOR(ORANGE):''オブジェクト''|
|OBJNEW|OBJNEW SReg SymbolIndex|Object New.&br;指定のSymb...
|OBJDEL|OBJDEL SReg|Object Delete.&br;指定のSRegが指すオ...
|OBJRFI|OBJRFI SReg|Object Reference Increment.&br;指定の...
|OBJRFD|OBJRFD SReg|Object Reference Decrement.&br;指定の...
|>|>|BGCOLOR(ORANGE):''デバッグ''|
|DLINE|DLINE ConstantValue(u24)|Debug Line.&br;デバッグ情...
|DFUNC|DFUNC SymbolTableIndex(u16)|Debug Function.&br;デ...
** クラス構成 [#lfe85b6e]
*** SEVMCore [#bb572835]
- 仮想マシン本体。
- コンパイル済みの命令コード,ユーザー定義型の初期化デー...
- staticなデータはこいつが持ち,複数のContextで共有するこ...
*** SEVMContext [#uc0127e1]
- コンテキスト。スレッド。
- スタック,レジスタは各ScriptContextがそれぞれ持つ。
** SEVMCore [#hae3d592]
*** 手順 [#i4dc4609]
- セットアップ前準備(ユーザーがやる)
-- コンパイル済みのオブジェクトファイルの追加。
-- 関数,クラス類,変数類のC++とのバインド。
- セットアップ
-- 1) リンク&未解決シンボルのチェック。
-- 2) staticデータに.initデータをコピー。
-- 3) (ver2.0)各クラスのstaticコンストラクタ&static inva...
- ファイナライズ
-- 1) 全Contextが終了していることを確認。
-- 2) ガベージコレクトを実行。
-- 3) (ver2.0)各クラスのstatic invariant()&staticデスト...
-- 4) ガベージコレクトを実行。
-- 5) ゴミが残っていないかチェック。
** SEVMContext [#q24e9b98]
*** 実行開始手順 [#xe3c6b37]
- (ユーザーがやる)
- エントリーポイントとなる関数とその引数を設定。
** その他 [#n8572b2d]
[[./メモ]]
ページ名: