FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

オリジナルLLVM Backendを追加しよう (24. グローバル変数の対応)

LLVMにはすでにRISC-Vのバックエンドサポートが追加されている。しかし、勉強のために独自のRISC-V実装をLLVMに追加している。

jonathan2251.github.io

第6章はグローバル変数をサポート。 グローバル変数のサポートには4種類があって、それぞれどのような処理が必要なのか見ていく。

  • リロケーションモード : static, Smallsection : 未使用
  • リロケーションモード : static, Smallsection : 使用
  • リロケーションモード : PIC, Smallsection : 未使用
  • リロケーションモード : PIC, Smallsection : 使用

グローバル変数

これまではローカル変数についてみてきたが、今回はグローバル変数のアクセス変換について学ぶ。

グローバル変数のDAG変換は、過去に学んだDAG変換とは異なる。 バックエンドのC++コードが、llc -relocation-moelオプションに基づいてIR DAGノードを作成する。 一方で、他のDAGはIR DAGを直接マシンコードのDAGに変換する。 マシンコードのIR DAGはIR DAGの入力ファイルに基づく(例外的に、 Chapter3_4で使用するRetLR疑似命令は除く)。加えて、バックエンドを持っている場合は、アセンブリディレクティブ(マクロ)に関連するグローバル変数のための関数を出力するためのマシン命令について考えておく必要がある。

Chapter6_1グローバル変数をサポートしている。ch6_1.cppコンパイルしてみよう。

  • リロケーションモード : static, Smallsection使用

    • ch6_1.static.small.s
 ori  x10, x3, %gp_rel(gI)
    lw   x10, 0(x10)
    sw   x10, 4(x2)
    lw   x10, 4(x2)
...
    .type gI,@object              # @gI
    .globl    gI
    .p2align  2
gI:
    .4byte  100                     # 0x64
    .size gI, 4

あれ?x3はどこから来たんだ?なんか問題がありそうな気がする。

  • ch6_1.static.large.s
 lui  x10, %hi(gI)
    ori  x10, x10, %lo(gI)
    lw   x10, 0(x10)
    sw   x10, 4(x2)
    lw   x10, 4(x2)
...
    .type gI,@object              # @gI
    .globl    gI
    .p2align  2
gI:
    .4byte  100                     # 0x64
    .size gI, 4

こちらはSmallsectionを使わないので、アドレスを2命令を使って生成している。

  • ch6_1.pic.small.s
 lw   x10, %got(gI)(x3)
    lw   x10, 0(x10)
    sw   x10, 4(x2)
    lw   x10, 4(x2)

こちらはGOTを使って生成する。そしてSmallsectionなのでアドレス生成も1命令で。

  • ch6_1.pic.large.s
 lui  x10, %got_hi(gI)
    add  x10, x10, x3
    lw   x10, %got_lo(gI)(x10)
    lw   x10, 0(x10)
    sw   x10, 4(x2)
    lw   x10, 4(x2)

こちらはGOTを使って、さらにアドレスを2命令で生成している。