FPGA開発日記

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

RISC-Vのベクトル命令のエンコーディングをまとめる

RISC-Vのベクトル命令について勉強している。ベクトル拡張の仕様はv0.8をベースにしている。命令のエンコーディングについて調べているが、理解に時間がかかっているのでまとめてみる。

公式の仕様書には、以下のようなエンコーディングのリストが載っているが、何が何だか分からない。

f:id:msyksphinz:20200118123938p:plain
ベクトル命令のエンコーディングテーブル

まず、この表について理解する必要がある。この表はfunct3エンコーディングによって複数の命令の分類があることを示している。そしてそれぞれの命令分類(OPIVV, OPIVX, ... など)は別の表で命令エンコーディングの定義がなされている。

  • 整数ベクトル命令1
    • OPIVV
    • OPIVX
    • OPIVI
  • 整数ベクトル命令2
    • OPMVV
    • OPMVX
  • 浮動小数点ベクトル命令
    • OPFVV
    • OPFVF

それぞれの命令フォーマットは以下のように定義されている。

Formats for Vector Arithmetic Instructions under OP-V major opcode

31       26  25   24      20 19      15 14   12 11      7 6     0
  funct6   | vm  |   vs2    |    vs1   | 0 0 0 |    vd   |1010111| OP-V (OPIVV)
  funct6   | vm  |   vs2    |    vs1   | 0 0 1 |  vd/rd  |1010111| OP-V (OPFVV)
  funct6   | vm  |   vs2    |    vs1   | 0 1 0 |  vd/rd  |1010111| OP-V (OPMVV)
  funct6   | vm  |   vs2    |   simm5  | 0 1 1 |    vd   |1010111| OP-V (OPIVI)
  funct6   | vm  |   vs2    |    rs1   | 1 0 0 |    vd   |1010111| OP-V (OPIVX)
  funct6   | vm  |   vs2    |    rs1   | 1 0 1 |    vd   |1010111| OP-V (OPFVF)
  funct6   | vm  |   vs2    |    rs1   | 1 1 0 |  vd/rd  |1010111| OP-V (OPMVX)
     6        1        5          5        3        5        7

つまり、命令のエンコーディングとしては以下の手順を取ることになる。

  1. まずはopcode[6:0]でベクトル命令であることを認識する。
  2. funct3でベクトル命令を7種類に分類する。
  3. funct6で命令を分類する。

さらに、もう一つ大きな分類として25ビット目にvmというビットが定義されている。vmビットによってベクトルレジスタに対してマスクを適用するかを決定する。

さて、もう一度命令一覧表に戻ってみると3種類の分類(OPIVV, OPIVV, OPIVIOPMVV, OPMVXOPFVV, OPFVF)によって命令が定義されていることが分かる。

f:id:msyksphinz:20200118124017p:plain
ベクトル命令の分類と命令エンコーディング

たとえばvadd命令だとV, X, Iの場合はOPIVV, OPIVX, OPIVIの3種類にチェックが付いているので、3種類の命令フォーマットが定義可能だ。

# Integer adds.
vadd.vv vd, vs2, vs1, vm   # Vector-vector
vadd.vx vd, vs2, rs1, vm   # vector-scalar
vadd.vi vd, vs2, imm, vm   # vector-immediate

一方でvsub命令はVXつまりOPIVV, OPIVXのフォーマットが定義可能である。

# Integer subtract
vsub.vv vd, vs2, vs1, vm   # Vector-vector
vsub.vx vd, vs2, rs1, vm   # vector-scalar

さらに、vrsub命令はXIつまりOPIVX, OPIVIのフォーマットが定義可能である。

# Integer reverse subtract
vrsub.vx vd, vs2, rs1, vm   # vd[i] = rs1 - vs2[i]
vrsub.vi vd, vs2, imm, vm   # vd[i] = imm - vs2[i]

これらをベクトル命令の一覧表をまとめた。命令の分類とfunct[5:4]で表を作った。

f:id:msyksphinz:20200118124059p:plain
ベクトル命令の全体テーブル。