跳转至

算术指令

向量算术指令使用单独 opcode:OP-V=1010111 ,指令格式如下所示:

funct6[5:0] vm rs2[4:0] rs1[4:0] funct3[2:0] rd[4:0] opcode[6:0]
funct6 vm vs2 vs1 000 vd 1010111 OPIVV
funct6 vm vs2 vs1 001 vd/sd 1010111 OPFVV
funct6 vm vs2 vs1 010 vd/sd 1010111 OPMVV
funct6 vm vs2 simm5 011 vd 1010111 OPIVI
funct6 vm vs2 ss1 100 vd 1010111 OPIVS
funct6 vm vs2 ss1 101 vd 1010111 OPFVS
funct6 vm vs2 ss1 110 vd 1010111 OPMVS

其中:

  • funct3域用来定义指令的子类,包括操作数的类型和来源:
funct3[2:0] 指令类型 操作类型 操作数来源
000 OPIVV 整数 向量寄存器-向量寄存器
001 OPFVV 浮点数 向量寄存器-向量寄存器
010 OPMVV 整数 向量寄存器-向量寄存器
011 OPIVI 整数 向量寄存器-立即数
100 OPIVS 整数 向量寄存器-共享寄存器
101 OPFVS 浮点数 向量寄存器-共享寄存器
110 OPMVS 整数 向量寄存器-共享寄存器

指令中的操作数来源寄存器(向量寄存器/共享寄存器)根据funct3域确定。注意其中操作数2(vs2)总是向量寄存器。

  • funct6域用来指定计算类型,其与funct3共同编码算术指令类型。详细编码表见附表。
  • vm 域为 0 的时候表示该指令仅在 vv0 对应元素的 LSB 为 1 时生效

以下列出基本的算术指令。考虑初步实现的简化,暂时略去诸多指令。注意,略去的指令编码也在附表中给出。

整数算术指令

整数算术指令目前仅考虑单宽度的基本整数算术指令,暂时不考虑整数乘除法指令等。

整数加减法指令

整数加减(反减)法指令:

# Integer add
vadd.vv vd, vs2, vs1, vm    # Vector-vector, vd[i] = vs2[i] + vs1[i]
vadd.vs vd, vs2, ss1, vm    # vector-scalar, vd[i] = vs2[i] + ss1
vadd.vi vd, vs2, imm, vm    # vector-immediate, vd[i] = vs2[i] + imm
# Integer subtract
vsub.vv vd, vs2, vs1, vm    # Vector-vector, vd[i] = vs2[i] - vs1[i]
vsub.vs vd, vs2, ss1, vm    # vector-scalar, vd[i] = vs2[i] - ss1
# Integer reverse subtract
vrsub.vs vd, vs2, ss1, vm   # vd[i] = ss1 - vs2[i]
vrsub.vi vd, vs2, imm, vm   # vd[i] = imm - vs2[i]

整数按位逻辑指令

整数按位与、或、异或指令:

# Bitwise logical operations.
vand.vv vd, vs2, vs1, vm    # Vector-vector, vd[i] = vs2[i] & vs1[i]
vand.vs vd, vs2, ss1, vm    # vector-scalar, vd[i] = vs2[i] & ss1
vand.vi vd, vs2, imm, vm    # vector-immediate, vd[i] = vs2[i] & imm
vor.vv vd, vs2, vs1, vm     # Vector-vector, vd[i] = vs2[i] | vs1[i]
vor.vs vd, vs2, ss1, vm     # vector-scalar, vd[i] = vs2[i] | ss1
vor.vi vd, vs2, imm, vm     # vector-immediate, vd[i] = vs2[i] | imm
vxor.vv vd, vs2, vs1, vm    # Vector-vector, vd[i] = vs2[i] ^ vs1[i]
vxor.vs vd, vs2, ss1, vm    # vector-scalar, vd[i] = vs2[i] ^ ss1
vxor.vi vd, vs2, imm, vm    # vector-immediate, vd[i] = vs2[i] ^ imm

其中将向量-立即数的 VXOR.VI 指令中的立即数设置为 -1 可以实现按位 NOT 操作,可以提供伪汇编指令 vnot.v

整数移位指令

整数移位指令:

# Bit shift operations
vsll.vv vd, vs2, vs1, vm    # Vector-vector, vd[i] = vs2[i] << vs1[i](lg2(SEW)-1, 0)
vsll.vs vd, vs2, ss1, vm    # vector-scalar, vd[i] = vs2[i] << ss1(lg2(SEW)-1, 0)
vsll.vi vd, vs2, uimm, vm   # vector-immediate, vd[i] = vs2[i] << uimm(lg2(SEW)-1, 0)
vsrl.vv vd, vs2, vs1, vm    # Vector-vector, vd[i] = vs2[i] >> vs1[i](lg2(SEW)-1, 0)
vsrl.vs vd, vs2, ss1, vm    # vector-scalar, vd[i] = vs2[i] >> ss1(lg2(SEW)-1, 0)
vsrl.vi vd, vs2, uimm, vm   # vector-immediate, vd[i] = vs2[i] >> uimm(lg2(SEW)-1, 0)
vsra.vv vd, vs2, vs1, vm    # Vector-vector, vd[i] = signed(vs2[i]) >> vs1[i](lg2(SEW)-1, 0)
vsra.vs vd, vs2, ss1, vm    # vector-scalar, vd[i] = signed(vs2[i]) >> ss1(lg2(SEW)-1, 0)
vsra.vi vd, vs2, uimm, vm   # vector-immediate, vd[i] = signed(vs2[i]) >> uimm(lg2(SEW)-1, 0)

其中立即数均按照无符号数处理(uimm = unsigned imm)。寄存器值中的低 lg2(SEW) 位被取出作为移位量。

整数比较指令

整数比较指令的结果写入结果寄存器的 LSB 中,即结果寄存器作为向量 mask 寄存器使用:

# Set if equal
vmseq.vv vd, vs2, vs1, vm   # Vector-vector, vd[i] = vs2[i] == vs[i]
vmseq.vs vd, vs2, ss1, vm   # vector-scalar, vd[i] = vs2[i] == ss1
vmseq.vi vd, vs2, imm, vm   # vector-immediate, vd[i] = vs2[i] == imm
# Set if not equal
vmsne.vv vd, vs2, vs1, vm   # Vector-vector, vd[i] = vs2[i] != vs[1]
vmsne.vs vd, vs2, ss1, vm   # vector-scalar, vd[i] = vs2[i] != ss1
vmsne.vi vd, vs2, imm, vm   # vector-immediate, vd[i] = vs2[i] != imm
# Set if less than, unsigned
vmsltu.vv vd, vs2, vs1, vm  # Vector-vector, vd[i] = vs2[i] < vs[1]
vmsltu.vs vd, vs2, ss1, vm  # Vector-scalar, vd[i] = vs2[i] < ss1
# Set if less than, signed
vmslt.vv vd, vs2, vs1, vm   # Vector-vector, vd[i] = signed(vs2[i]) < signed(vs[1])
vmslt.vs vd, vs2, ss1, vm   # vector-scalar, vd[i] = signed(vs2[i]) < signed(ss1)
# Set if less than or equal, unsigned
vmsleu.vv vd, vs2, vs1, vm  # Vector-vector, vd[i] = vs2[i] <= vs[1]
vmsleu.vs vd, vs2, ss1, vm  # vector-scalar, vd[i] = vs2[i] <= ss1
vmsleu.vi vd, vs2, uimm, vm  # Vector-immediate, vd[i] = vs2[i] <= uimm
# Set if less than or equal, signed
vmsle.vv vd, vs2, vs1, vm   # Vector-vector, vd[i] = signed(vs2[i]) <= signed(vs[1])
vmsle.vs vd, vs2, ss1, vm   # vector-scalar, vd[i] = signed(vs2[i]) <= signed(ss1)
vmsle.vi vd, vs2, imm, vm   # vector-immediate, vd[i] = signed(vs2[i]) <= imm
# Set if greater than, unsigned
vmsgtu.vs vd, vs2, ss1, vm  # Vector-scalar, vd[i] = vs2[i] > ss1
vmsgtu.vi vd, vs2, uimm, vm  # Vector-immediate, vd[i] = vs2[i] > uimm
# Set if greater than, signed
vmsgt.vs vd, vs2, ss1, vm   # Vector-scalar, vd[i] = signed(vs2[i]) > signed(ss1)
vmsgt.vi vd, vs2, imm, vm   # Vector-immediate, vd[i] = signed(vs2[i]) > imm

未列出的指令变种作为伪汇编指令实现。

Warning

TODO:补充伪汇编指令映射实现。

浮点算术指令

浮点算术指令同样暂时只考虑单宽度的基本浮点算术指令。

浮点加减法指令

浮点加减法指令:

# Floating-point add
vfadd.vv vd, vs2, vs1, vm   # Vector-vector vd[i] = vs2[i] + vs1[i]
vfadd.vs vd, vs2, ss1, vm   # vector-scalar vd[i] = vs2[i] + ss1
# Floating-point subtract
vfsub.vv vd, vs2, vs1, vm   # Vector-vector vd[i] = vs2[i] - vs1[i]
vfsub.vs vd, vs2, ss1, vm   # Vector-scalar vd[i] = vs2[i] - ss1
vfrsub.vs vd, vs2, ss1, vm  # Scalar-vector vd[i] = ss1 - vs2[i]

浮点乘除法指令

浮点乘除法指令:

# Floating-point multiply
vfmul.vv vd, vs2, vs1, vm   # Vector-vector vd[i] = vs2[i] * vs1[i]
vfmul.vs vd, vs2, ss1, vm   # vector-scalar vd[i] = vs2[i] * ss1
# Floating-point divide
vfdiv.vv vd, vs2, vs1, vm   # Vector-vector vd[i] = vs2[i] / vs1[i]
vfdiv.vs vd, vs2, ss1, vm   # vector-scalar vd[i] = vs2[i] / ss1
# Reverse floating-point divide vector = scalar / vector
vfrdiv.vs vd, vs2, ss1, vm  # scalar-vector, vd[i] = ss1 / vs2[i]

浮点乘加指令

浮点乘加指令包含四种乘加操作的各两个变种(结果覆盖加数/第一个乘数):

# FP multiply-accumulate, overwrites addend
vfmacc.vv vd, vs1, vs2, vm      # vd[i] = +(vs1[i] * vs2[i]) + vd[i]
vfmacc.vs vd, ss1, vs2, vm      # vd[i] = +(s[ss1] * vs2[i]) + vd[i]
# FP negate-(multiply-accumulate), overwrites subtrahend
vfnmacc.vv vd, vs1, vs2, vm     # vd[i] = -(vs1[i] * vs2[i]) - vd[i]
vfnmacc.vs vd, ss1, vs2, vm     # vd[i] = -(s[ss1] * vs2[i]) - vd[i]
# FP multiply-subtract-accumulator, overwrites subtrahend
vfmsac.vv vd, vs1, vs2, vm      # vd[i] = +(vs1[i] * vs2[i]) - vd[i]
vfmsac.vs vd, ss1, vs2, vm      # vd[i] = +(s[ss1] * vs2[i]) - vd[i]
# FP negate-(multiply-subtract-accumulator), overwrites minuend
vfnmsac.vv vd, vs1, vs2, vm     # vd[i] = -(vs1[i] * vs2[i]) + vd[i]
vfnmsac.vs vd, ss1, vs2, vm     # vd[i] = -(s[ss1] * vs2[i]) + vd[i]
# FP multiply-add, overwrites multiplicand
vfmadd.vv vd, vs1, vs2, vm      # vd[i] = +(vs1[i] * vd[i]) + vs2[i]
vfmadd.vs vd, ss1, vs2, vm      # vd[i] = +(s[ss1] * vd[i]) + vs2[i]
# FP negate-(multiply-add), overwrites multiplicand
vfnmadd.vv vd, vs1, vs2, vm     # vd[i] = -(vs1[i] * vd[i]) - vs2[i]
vfnmadd.vs vd, rs1, vs2, vm     # vd[i] = -(s[ss1] * vd[i]) - vs2[i]
# FP multiply-sub, overwrites multiplicand
vfmsub.vv vd, vs1, vs2, vm      # vd[i] = +(vs1[i] * vd[i]) - vs2[i]
vfmsub.vs vd, ss1, vs2, vm      # vd[i] = +(s[ss1] * vd[i]) - vs2[i]
# FP negate-(multiply-sub), overwrites multiplicand
vfnmsub.vv vd, vs1, vs2, vm     # vd[i] = -(vs1[i] * vd[i]) + vs2[i]
vfnmsub.vs vd, ss1, vs2, vm     # vd[i] = -(s[ss1] * vd[i]) + vs2[i]

附表:算术指令功能码表

funct6 OPIVV OPIVS OPIVI OPMVV OPMVS OPFVV OPFVS
000000 vadd.vv vadd.vs vadd.vi vredsum.vs vfadd.vv vfadd.vs
000001 vredand.vs vfredsum.vs
000010 vsub.vv vsub.vs vredor.vs vfsub.vv vfsub.vs
000011 vrsub.vs vrsub.vi vredxor.vs vfredosum.vs
000100 vminu.vv vminu.vs vredminu.vs vfmin.vv vfmin.vs
000101 vmin.vv vmin.vs vredmin.vs vfredmin.vs
000110 vmaxu.vv vmaxu.vs vredmaxu.vs vfmax.vv vfmax.vs
000111 vmax.vv vmax.vs vredmax.vs vfredmax.vs
001000 vaaddu.vv vaaddu.vs vfsgnj.vv vfsgnj.vs
001001 vand.vv vand.vs vand.vi vaadd.vv vaadd.vs vfsgnjn.vv vfsgnjn.vs
001010 vor.vv vor.vs vor.vi vasubu.vv vasubu.vs vfsgnjx.vv vfsgnjx.vs
001011 vxor.vv vxor.vs vxor.vi vasub.vv vasub.vs
001100 vrgather.vv vrgather.vs vrgather.vi
001101
001110 vslideup.vs vslideup.vi vslide1up.vs
001111 vslidedown.vs vslidedown.vi vslide1down.vs
010000 vadc.vvm vadc.vsm vadc.vim VWXUNARY0 VRX-UNARY0 VWFUNARY0 VRF-UNARY0
010001 vmadc.vvm vmadc.vsm vmadc.vim
010010 vsbc.vvm vsbc.vsm vsbc.vim
010011 vmsbc.vvm vmsbc.vsm vmsbc.vim
010100 VMUNARY0
010101
010110
010111 vmerge.vxm
vmv.v.v
vmerge.vsm
vmv.v.s
vmerge.vim
vmv.v.i
vcompress.vm vmerge.vsm
vfmv.v.s
011000 vmseq.vv vmseq.vs vmseq.vi vmandnot.mm vmfeq.vv vmfeq.vs
011001 vmsne.vv vmsne.vs vmsne.vi vmand.mm vmfle.vv vmfle.vs
011010 vmsltu.vv vmsltu.vs vmor.mm
011011 vmslt.vv vmslt.vs vmxor.mm vmflt.vv vmflt.vs
011100 vmsleu.vv vmsleu.vs vmsleu.vi vmornot.mm vmfne.vv vmfne.vs
011101 vmsle.vv vmsle.vs vmsle.vi vmnand.mm vmfgt.vs
011110 vmsgtu.vs vmsgtu.vi vmnor.mm
011111 vmsgt.vs vmsgt.vi vmxnor.mm vmfge.vs
100000 vsaddu.vv vsaddu.vs vsaddu.vi vdivu.vv vdivu.vs vfdiv.vv vfdiv.vs
100001 vsadd.vv vsadd.vs vsadd.vi vdiv.vv vdiv.vs vfrdiv.vs
100010 vssubu.vv vssubu.vs vremu.vv vremu.vs VFUNARY0
100011 vssub.vv vssub.vs vrem.vv vrem.vs VFUNARY1
100100 vmulhu.vv vmulhu.vs vfmul.vv vfmul.vs
100101 vsll.vv vsll.vs vsll.vi vmul.vv vmul.vs
100110 vmulhsu.vv vmulhsu.vs
100111 vsmul.vv vsmul.vs vmv<nf>r.v vmulh.vv vmulh.vs vfrsub.vs
101000 vsrl.vv vsrl.vs vsrl.vi vfmadd.vv vfmadd.vs
101001 vsra.vv vra.vs vsra.vi vmadd.vv vmadd.vs vfnmadd.vv vfnmadd.vs
101010 vssrl.vv vssrl.vs vssrl.vi vfmsub.vv vfmsub.vs
101011 vssra.vv vssra.vs vssra.vi vnmsub.vv vnmsub.vs vfnmsub.vv vfnmsub.vs
101100 vnsrl.vv vnsrl.vs vnsrl.vi vfmacc.vv vfmacc.vs
101101 vnsra.vv vnsra.vs vnsra.vi vmacc.vv vmacc.vs vfnmacc.vv vfnmacc.vs
101110 vnclipu.vv vnclipu.vs vnclipu.vi vfmsac.vv vfmsac.vs
101111 vnclip.vv vnclip.vs vnclip.vi vnmsac.vv vnmsac.vs vfnmsac.vv vfnmsac.vs
110000 vwredsumu.vs vwaddu.vv vwaddu.vs vfwadd.vv vfwadd.vs
110001 vwred-vsum.vs vwadd.vv vwadd.vs vfwred-sum.vs
110010 vwsubu.vv vwsubu.vs vfwsub.vv vfwsub.vs
110011 vwsub.vv vwsub.vs vfwredosum.vs
110100 vwaddu.wv vwaddu.ws vfwadd.wv vfwadd.ws
110101 vwadd.wv vwadd.ws
110110 vwsubu.wv vwsubu.ws vfwsub.wv vfwsub.vs
110111 vwsub.wv vwsub.ws
111000 vdotu.vv vwmulu.vv vwmulu.vs vfwmul.vv vfwmul.vs
111001 vdot.vv vfdot.vv
111010 vwmulsu.vv vwmulsu.vs
111011 vwmul.vv vwmul.vs
111100 vqmaccu.vv vqmaccu.vs vwmaccu.vv vwmaccu.vs vfwmacc.vv vfwmacc.vs
111101 vqmacc.vv vqmacc.vs vwmacc.vv vwmacc.vs vfwnmacc.vv vfwnmacc.vs
111110 vqmaccus.vs vwmaccus.vv vwmaccus.vs vfwmsac.vv vfwmsac.vs
111111 vqmaccsu.vv vqmaccsu.vs vwmaccsu.vv vwmaccsu.vs vfwnmsac.vv vfwnmsac.vs

Warning

作为框架供参考。TODO:表格需要校对。


最后更新: April 9, 2020
作者: Harry Chen (8.12%), Jianhui Han (69.74%), Jiajie Chen (21.77%), Jiajie Chen (0.37%)