メモ Edit

コード生成 Edit

もっとシンプルなものにしよう。

レジスタの概要 Edit

  • 1つのレジスタのサイズは4バイト。
  • レジスタ数は暫定で64。
  • s64,f64など64bitな値型はレジスタに格納することができないのでstructやpodなどと同じ扱いを受ける。
  • ↑64bitな値型を頻繁に使うことはないという判断。

変数とレジスタ Edit

  • ローカル変数は全てレジスタに割り当てられる。
  • スコープを考慮してレジスタの使用数はなるべく少なくて済むように最適化される。
  • 一時変数もレジスタに割り当てられる。
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
    
    -
    |
    -
    |
    |
    -
    |
    !
    |
    -
    |
    !
    |
    |
    |
    |
    !
    !
    
    utility Hoge {
    static void func()
    {
        int a; // R01
        int b; // R02
        {
            int c; // R04
        }
        int d; // R03
        {
            int e; // R04
        }
        d = (a + b) * d; 
        // (a + b)が一時変数としてR04に格納される
        // R04 = a + b; 
        // R03 = R04 * R03;
    }
    };

引数とレジスタ Edit

  • 引数はR01から順番にレジスタに割り当てられる。
  • 非staticなメンバ関数はR01にthisポインタが割り当てられる。
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
    
     
    -
    |
    |
    |
    |
    |
    -
    |
    |
    !
    !
     
    
    pod Vector3
    {
        float x;
        float y;
        float z;
     
        void func(float addValue)
        {
            // R01 : this
            // R02 : addValue
        }
    }
    

戻り値とレジスタ Edit

  • 戻り値はR00に格納される。
  • STFR命令が実行されるとR00の値は関数戻り値レジスタにコピーされる。
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
    
     
    -
    |
    -
    |
    !
    !
     
    
    utility Hoge
    {
        static int GetOne()
        {
            return 1; // R00 = 1
        }
    };
    

アセンブラのイメージ Edit

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
-
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0: void func()
1:{
2:    int i = 3;
3:    i = i + 4;
4:}
# 命令コード
Instruction:
  LOADC   R01 0x0000
  LOADC   R02 0x0004
  ADDI32  R01 R01 R02
  RETURN
 
# ローカル変数のレジスタマッピング情報
RegisterMap:
  R01: L2 i 
 
# コンパイル時に確定する定数のテーブル
ConstantTable:
  0x0000: 3
  0x0004: 4

命令コード Edit

命令書式コメント
LDCLDC Reg ConstantTableIndexConstantTableの値を指定レジスタにロード
LDRLDR Reg1 Reg2Reg2の値をReg1にロード
LDBPLDBP Reg1 BasePointerOffset(S16)BasePointerから相対アドレス分移動したアドレスをReg1にロード
LDFRLDFR Reg関数戻り値レジスタの値を指定のレジスタにロード
LDFARCLDFR FAReg ConstantTableIndexConstantTableの値を指定関数引数レジスタにロード
LDFARRLDFR FAReg Reg指定のレジスタの値を指定の関数引数レジスタにロード
LDPTRLDPTR Reg1 Reg2Reg2の値をアドレスとみなし,Reg2が指す値を取得する
LDHDLLDHDL Reg1 Reg2Reg2の値をオブジェクトハンドルとみなし,Reg2が指すオブジェクトハンドルのアドレスを取得する
CPFARCPFAR RegisterCount関数引数レジスタの値を指定した数レジスタにコピー
ADDxxxADDI32 Reg1 Reg2 Reg3Reg1 = Reg2 + Reg3
SUBxxxSUBI32 Reg1 Reg2 Reg3Reg1 = Reg2 - Reg3
MULxxxMULS32 Reg1 Reg2 Reg3Reg1 = Reg2 * Reg3
DIVxxxMULS32 Reg1 Reg2 Reg3Reg1 = Reg2 / Reg3
MODxxxMODS32 Reg1 Reg2 Reg3Reg1 = Reg2 % Reg3
PUSHREGPUSHREG PushRegisterCount
POPREGPOPREG PopRegisterCount
PUSHPUSH PushStackSize
POPPOP PopStackSize
CALLCALL SymbolTableIndex
STFRSTFRR00の値を関数戻り値レジスタに設定する
RETRET

意味解析 Edit

  • 定数(enum,immutable)の確定
  • ユーザー定義型のサイズの決定
  • ユーザー定義型の静的・非静的メンバ変数の位置を決定
  • 自動生成関数の生成
  • 関数のレジスタ割り当ての決定
  • 関数の定数テーブルを作成
  • 関数の非値型のスタックマッピングおよびスタックサイズを決定

    ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS