0
点赞
收藏
分享

微信扫一扫

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(九)- 向量定点算术指令

水沐由之 04-10 23:30 阅读 3

 1. 引言

以下是《riscv-v-spec-1.0.pdf》文档的关键内容:
这是一份关于向量扩展的详细技术文档,内容覆盖了向量指令集的多个关键方面,如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量算术指令格式、向量整数和浮点算术指令、向量归约操作、向量掩码指令、向量置换指令、异常处理以及标准向量扩展等。
首先,文档定义了向量元素和向量寄存器状态之间的映射关系,并阐述了向量指令的格式。在此基础上,提出了配置设置指令,如vsetvl、ivsetiv和vlsetvl,用于设定向量长度(VL)和向量对齐长度(AVL)。
接着,文档详细说明了向量加载和存储操作,以及向量内存对齐和一致性模型。这些模型确保了向量操作的高效性和准确性。
然后,文档介绍了向量算术指令格式,包括向量整数、固定点和浮点算术指令。这些指令支持广泛的数学运算,为高性能计算提供了强大的支持。
此外,文档还涉及向量归约操作、掩码指令和置换指令,这些指令增强了向量操作的灵活性和功能性。
最后,文档讨论了异常处理机制,并列举了标准向量扩展指令列表。这些扩展指令为向量处理器提供了丰富的功能集,使其能够适应不同的应用场景和性能需求。
综上所述,这份文档为向量指令集的设计和实现提供了全面的指导和参考,有助于开发者更好地理解和利用向量处理器的能力。

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(一)-向量扩展编程模型-CSDN博客

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(二)-向量元素到向量寄存器状态的映射-CSDN博客【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(三)-向量指令格式-CSDN博客

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(四)- 配置和设置指令(vsetvli/vsetivli/vsetvl)-CSDN博客

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(五)- 向量加载和存储-CSDN博客

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(六)- 向量内存一致性模型-CSDN博客

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(七)- 向量算术指令格式-CSDN博客

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(八)- 向量整数算术指令-CSDN博客

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(九)- 向量整数算术指令-CSDN博客

12 向量定点算术指令

前面的一系列整数算术指令被扩展以支持定点算术。

定点数是一个二进制补码有符号或无符号整数,被解释为具有隐含分母的分数中的分子。定点指令旨在应用于分子;软件负责管理分母。一个N位元素可以容纳范围在-2^(N-1)…+2^(N-1)-1内的二进制补码有符号整数,以及范围在0…+2^(N-1)内的无符号整数。定点指令通过支持缩放和舍入,有助于在狭窄的操作数中保持精度,并且可以通过将结果饱和到目标格式范围内来处理溢出。

注意:上述扩展整数操作也可以用来避免溢出。

12.1 向量饱和形式的整数加法和减法

为有符号和无符号整数提供了饱和形式的整数加法和减法。如果结果会溢出目标,则将结果替换为最接近的可表示值,并设置vxsat位。

# Saturating adds of unsigned integers.
vsaddu.vv vd, vs2, vs1, vm   # Vector-vector
vsaddu.vx vd, vs2, rs1, vm   # vector-scalar
vsaddu.vi vd, vs2, imm, vm   # vector-immediate
# Saturating adds of signed integers.
vsadd.vv vd, vs2, vs1, vm   # Vector-vector
vsadd.vx vd, vs2, rs1, vm   # vector-scalar
vsadd.vi vd, vs2, imm, vm   # vector-immediate
# Saturating subtract of unsigned integers.
vssubu.vv vd, vs2, vs1, vm   # Vector-vector
vssubu.vx vd, vs2, rs1, vm   # vector-scalar
# Saturating subtract of signed integers.
vssub.vv vd, vs2, vs1, vm   # Vector-vector
vssub.vx vd, vs2, rs1, vm   # vector-scalar

12.2 向量平均加法和减法指令

平均加法和减法指令将结果右移一位,并根据vx rm中的设置对结果进行四舍五入。提供了无符号和有符号两种版本。对于vaaddu和vaadd,结果中不可能发生溢出。对于vasub和vasubu,会忽略溢出,结果会环绕。

注意:对于vasub,只有在rne或rnu舍入下从最大数中减去最小数时才会发生溢出。

# Averaging add
# Averaging adds of unsigned integers.
vaaddu.vv vd, vs2, vs1, vm    # roundoff_unsigned(vs2[i] + vs1[i], 1)
vaaddu.vx vd, vs2, rs1, vm    # roundoff_unsigned(vs2[i] + x[rs1], 1)	

# Averaging adds of signed integers.
vaadd.vv vd, vs2, vs1, vm    # roundoff_signed(vs2[i] + vs1[i], 1)
vaadd.vx vd, vs2, rs1, vm    # roundoff_signed(vs2[i] + x[rs1], 1)
# Averaging subtract	

# Averaging subtract of unsigned integers.
vasubu.vv vd, vs2, vs1, vm   # roundoff_unsigned(vs2[i] - vs1[i], 1)
vasubu.vx vd, vs2, rs1, vm   # roundoff_unsigned(vs2[i] - x[rs1], 1)
# Averaging subtract of signed integers.
vasub.vv vd, vs2, vs1, vm   # roundoff_signed(vs2[i] - vs1[i], 1)
vasub.vx vd, vs2, rs1, vm   # roundoff_signed(vs2[i] - x[rs1], 1)

12.3 向量小数乘法指令

有符号小数乘法指令将两个SEW输入的乘积扩大到2*SEW,然后将结果右移SEW-1位,根据vx rm对这些位进行四舍五入,然后将结果饱和到SEW位。如果结果导致饱和,则设置vxsat位。

# Signed saturating and rounding fractional multiply
# See vx rm  description for rounding calculation
vsmul.vv vd, vs2, vs1, vm  # vd[i] = clip(roundoff_signed(vs2[i]*vs1[i], SEW-1))
vsmul.vx vd, vs2, rs1, vm  # vd[i] = clip(roundoff_signed(vs2[i]*x[rs1], SEW-1))

注意

当将两个N位有符号数相乘时,最大的幅度值是通过-2^(N-1) * -2^(N-1)获得的,产生结果为+2^(2N-2),当以2N位存储时,它只有一个(零)符号位。所有其他乘积在2N位中有两个符号位。为了在N个结果位中保持更高的精度,乘积会向右移动比N少一位的位数,使最大幅度值饱和,但对于所有其他乘积,结果精度会提高一位。

我们没有提供等效的小数乘法,其中一个输入是无符号的,因为这些会保留所有上部的SEW位,并且不需要饱和。当舍入仅仅是截断(rdn)时,此操作部分由vmulhu和vmulhsu指令覆盖。

12.4 向量移位指令

这些指令将输入值向右移动,并根据vx rm对移出的位进行四舍五入。比例右移既有零扩展形式(vssrl),也有符号扩展形式(vssra)。要移动的数据位于由vs2指定的向量寄存器组中,而移位量值可以来自向量寄存器组vs1、标量整数寄存器rs1或零扩展的5位立即数。只有移位量值的低lg2(SEW)位用于控制移位量。

# Scaling shift right logical		
vss rl.vv vd, vs2, vs1, vm   # vd[i]	=	roundoff_unsigned(vs2[i], vs1[i])
vss rl.vx vd, vs2, rs1, vm   # vd[i]	=	roundoff_unsigned(vs2[i], x[rs1])
vss rl.vi vd, vs2, uimm, vm  # vd[i]	=	roundoff_unsigned(vs2[i], uimm)
# Scaling shift right arithmetic		
vssra.vv vd, vs2, vs1, vm   # vd[i]	=	roundoff_signed(vs2[i],vs1[i])
vssra.vx vd, vs2, rs1, vm   # vd[i]	=	roundoff_signed(vs2[i], x[rs1])
vssra.vi vd, vs2, uimm, vm  # vd[i]	=	roundoff_signed(vs2[i], uimm)

12.5 向量缩小定点裁剪

vnclip指令用于将定点值打包到更窄的目标中。这些指令支持舍入、缩放和饱和到最终的目标格式。源数据位于由vs2指定的向量寄存器组中。缩放移位量值可以来自向量寄存器组vs1、标量整数寄存器rs1或零扩展的5位立即数。向量或标量移位量值的低lg2(2*SEW)位(例如,对于从SEW=64位到SEW=32位的缩小操作,使用低6位)用于控制右移量,从而提供缩放。

# Narrowing unsigned clip
# SEW 2*SEW SEW
vnclipu.wv vd, vs2, vs1, vm  # vd[i] = clip(roundoff_unsigned(vs2[i], vs1[i]))
vnclipu.wx vd, vs2, rs1, vm  # vd[i] = clip(roundoff_unsigned(vs2[i], x[rs1]))
vnclipu.wi vd, vs2, uimm, vm # vd[i] = clip(roundoff_unsigned(vs2[i], uimm))
# Narrowing signed clip
vnclip.wv vd, vs2, vs1, vm   # vd[i] = clip(roundoff_signed(vs2[i], vs1[i]))
vnclip.wx vd, vs2, rs1, vm   # vd[i] = clip(roundoff_signed(vs2[i], x[rs1]))
vnclip.wi vd, vs2, uimm, vm  # vd[i] = clip(roundoff_signed(vs2[i], uimm))

对于vnclipu/vnclip指令,舍入模式在vx rm CSR中指定。舍入发生在目标的最低位附近,并且在饱和之前进行。

对于vnclipu,经过移位和舍入的源值被视为无符号整数,如果结果会溢出被视为无符号整数的目标,则会发生饱和。

没有单独的指令可以将有符号值饱和到无符号目标。如果不需要为负数设置vxsat值,则可以使用一系列两个向量指令,首先使用vmax与0进行最大值操作以去除负数,然后使用vnclipu将结果的无符号值裁剪到目标中。这两个指令之间需要使用vsetvli来改变SEW。

对于vnclip,经过移位和舍入的源值被视为有符号整数,并且如果结果会溢出被视为有符号整数的目标,则会发生饱和。

如果任何目标元素饱和,则会在vxsat寄存器中设置vxsat位。

举报

相关推荐

0 条评论