【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(十)- 向量浮点算术指令
1. 引言
以下是《riscv-v-spec-1.0.pdf》的关键内容:
RISC-V 指令集
RISC-V指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
RISC-V 指令集
13. 向量浮点指令
标准向量浮点指令将被视为遵循IEEE-754/2008标准以处理数值。当向量浮点操作数的有效宽度(EEW)与支持的有效IEEE浮点类型不符时,则该指令编码得以维持。
是否支持浮点运算?同时能支持哪些元素宽度?这些数值类型是由相应的向量扩展来决定的。当前的扩展集涵盖了32位和64位浮点值的支持。当增加16位及128位元素宽度时,这些新增类型的数值同样满足IEEE-754/2008标准的要求。未来可能会增加更多符合IEEE-754/2008标准的浮点类型。
该系统必须具备相应的基线标量浮点扩展操作与之匹配的向量运算功能。
请注意:特别指出未来将配备16位半精度浮点值的向量扩展,并且这些扩展也将同样需要一些标量半精度浮点支持。
当mstatus.FS处于关闭位设置时,所有向量浮点指令的操作者都将触发非法指令异常。一旦修改任何浮点扩展状态(包括浮点CSR或f寄存器),相关的向量浮点指令必须先将其标记为脏态。
一旦成功地实现了虚拟机管理程序的扩展,并且V值等于1,则vsstatus.FS字段将继续影响向量浮点指令的有效性。当vsstatus.FS字段或mstatus.FS处于关闭状态时,任何试图执行向量浮点指令的操作都将导致非法指令异常。对于任何修改涉及的浮点扩展状态(包括浮点CSR寄存器或f寄存器)的向量浮点指令而言,在操作后必须确保mstatus.FS和vsstatus.FS都被标记为Dirty。
向量浮点指令在处理NaNs时与标量浮点指令具有相同的行为。
浮点向量-标量操作的标量值来源于“向量算术指令编码”部分所述。
13.1 向量浮点异常标志
当向量浮点异常触发时,在fflags寄存器中设置了标准的FP异常标志;而只有活动元素才会进行设置。
13.2 向量浮点加法/减法指令
# Floating-point add
vfadd.vv vd, vs2, vs1, vm # Vector-vector
vfadd.vf vd, vs2, rs1, vm # vector-scalar
# Floating-point subtract
vfsub.vv vd, vs2, vs1, vm # Vector-vector
vfsub.vf vd, vs2, rs1, vm # Vector-scala r vd[i] = vs2[i] - f[rs1]
vfrsub.vf vd, vs2, rs1, vm # Scalar-vector vd[i] = f[rs1] - vs2[i]
13.3 向量扩展浮点加法/减法指令
# Widening FP add/subtract,2*SEW = SEW +/- SEW
vfwadd.vv vd, vs2, vs1, vm # vector-vector
vfwadd.vf vd, vs2, rs1, vm # vector-scalar
vfwsub.vv vd, vs2, vs1, vm # vector-vector
vfwsub.vf vd, vs2, rs1, vm # vector-scalar
# Widening FP add/subtract,2*SEW = 2*SEW +/- SEW
vfwadd.wv vd, vs2, vs1, vm # vector-vector
vfwadd.wf vd, vs2, rs1, vm # vector-scalar
vfwsub.wv vd, vs2, vs1, vm # vector-vector
vfwsub.wf vd, vs2, rs1, vm # vector-scalar

13.4 向量浮点乘法/除法指令
# Floating-point multiply
vfmul.vv vd, vs2, vs1, vm # Vector-vector
vfmul.vf vd, vs2, rs1, vm # vector-scalar
# Floating-point divide
vfdiv.vv vd, vs2, vs1, vm # Vector-vector
vfdiv.vf vd, vs2, rs1, vm # vector-scalar
# Reverse floating-point divide vector = scalar / vector
vfrdiv.vf vd, vs2, rs1, vm # scalar-vector, vd[i] = f[rs1]/vs2[i]
13.5 向量浮点扩展乘法指令
# Widening floating-point multiply
vfwmul.vv vd, vs2, vs1, vm # vector-vector
vfwmul.vf vd, vs2, rs1, vm # vector-scalar
13.6 向量浮点融合乘加指令
包含了多种融合乘加的形式,并且其中两种破坏模式会覆盖其中一个操作数, 指的是加法操作项或作为第一个因子参与的数值。
# FP multiply-accumulate, overwrites addend
vfmacc.vv vd, vs1, vs2, vm # vd[i] = +(vs1[i] * vs2[i]) + vd[i]
vfmacc.vf vd, rs1, vs2, vm # vd[i] = +(f[rs1] * 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.vf vd, rs1, vs2, vm # vd[i] = -(f[rs1] * 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.vf vd, rs1, vs2, vm # vd[i] = +(f[rs1] * 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.vf vd, rs1, vs2, vm # vd[i] = -(f[rs1] * vs2[i]) + vd[i]
# FP multiply-add, overwrites multiplicand
vfmadd.vv vd, vs1, vs2, vm # vd[i] = +(vs1[i] * vd[i]) + vs2[i]
vfmadd.vf vd, rs1, vs2, vm # vd[i] = +(f[rs1] * 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.vf vd, rs1, vs2, vm # vd[i] = -(f[rs1] * vd[i]) - vs2[i]
# FP multiply-sub, overwrites multiplicand
vfmsub.vv vd, vs1, vs2, vm # vd[i] = +(vs1[i] * vd[i]) - vs2[i]
vfmsub.vf vd, rs1, vs2, vm # vd[i] = +(f[rs1] * 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.vf vd, rs1, vs2, vm # vd[i] = -(f[rs1] * vd[i]) + vs2[i]

注意:考虑到我们在标量FP FMA编码中未使用的两种舍入模式可能会导致微体系结构变得复杂化。
13.7 向量加宽浮点融合乘加指令
在加宽的浮点融合乘加指令中, 结果会覆盖被操作的宽型数据. 所有乘数输入均采用SEW宽度设置, 被操作的数据(即被加数与目标)均为双倍SEW位宽度.
# FP widening multiply-accumulate, overwrites addend
vfwmacc.vv vd, vs1, vs2, vm # vd[i] = +(vs1[i] * vs2[i]) + vd[i]
vfwmacc.vf vd, rs1, vs2, vm # vd[i] = +(f[rs1] * vs2[i]) + vd[i]
# FP widening negate-(multiply-accumulate), overwrites addend
vfwnmacc.vv vd, vs1, vs2, vm # vd[i] = -(vs1[i] * vs2[i]) - vd[i]
vfwnmacc.vf vd, rs1, vs2, vm # vd[i] = -(f[rs1] * vs2[i]) - vd[i]
# FP widening multiply-subtract-accumulator, overwrites addend
vfwmsac.vv vd, vs1, vs2, vm # vd[i] = +(vs1[i] * vs2[i]) - vd[i]
vfwmsac.vf vd, rs1, vs2, vm # vd[i] = +(f[rs1] * vs2[i]) - vd[i]
# FP widening negate-(multiply-subtract-accumulator), overwrites addend
vfwnmsac.vv vd, vs1, vs2, vm # vd[i] = -(vs1[i] * vs2[i]) + vd[i]
vfwnmsac.vf vd, rs1, vs2, vm # vd[i] = -(f[rs1] * vs2[i]) + vd[i]

13.8 向量浮点平方根指令
这是一条一元向量-向量指令。
# Floating-point square root
vfsqrt.v vd, vs2, vm # Vector-vector square root
13.9 向量浮点平方根倒数指令
这是一条返回1/sqrt(x)的7位精确估计值的一元向量-向量指令。
# Floating-point reciprocal square-root estimate to 7 bits.
vfrsqrt7.v vd, vs2, vm
注意:在早期草案中使用了汇编器名称vfrsqrte7。然而这可能会引起与元素宽度ex表示法之间的混淆。因此这些名称仍可作为工具链中的别名保留。
下表描述了该指令对所有浮点输入类别的行为:
| Input | Output | Exceptions Raised |
|---|---|---|
| -∞ = x < -0.0 | canonical NaN | NV |
| -0.0 | -∞ | DZ |
| +0.0 | +∞ | DZ |
| +0.0 < x __ < +∞ | estimate __of1/sqrt(x) | |
| +∞ | +0.0 | |
| qNaN | canonical NaN | |
| sNaN | canonical NaN | NV |
所有正常和次正常输入都会产生正常输出。输出值与动态舍入模式无关。
针对正常情况而言,在计算过程中需结合以下步骤操作:首先,在执行查找前会将次正规输入转换为标准化形式,并对指数进行相应调整。随后,请执行以下操作:取运算对象的有效数字中包含整数部分与小数点后六位数值;然后将其与运算对象的小数值中位于小数点后七位的位置上的数值进行结合;接着,请查阅下述表格以获取对应的结果值;最后,在确定计算结果后,请按照运算规则设定好各部分的具体数值即可完成此次运算任务
详细说明如下:详细说明了计算流程。当输入呈现正常分布时,请将规范化后的指数设定为其原始数值对应的指数值;若不符合此条件,则将其设置为负值与尾部中前导零的数量之差。对于非标准数值的情况,则需将尾部数字向左移动指定数量的位置以恢复规范化状态,并舍弃高位多余的零元素。随后按照公式确定输出数值的具体参数:输出数值的指数则由下述公式确定:floor函数作用于(3倍B减一再减去规范化后的指数的一半),其中floor函数用于向下取整运算处理结果;而输出数值本身的符号则直接继承自原始数据源的信息内容。
下表详细列出了输出尾数中的7个最高有效位(MSBs),这些数值构成了基于正规化输入指数最低有效位(LSB)以及正规化输入尾数前6个最高有效位所构建的功能函数;其余所有输出尾数均设为零值。
Table 16. vfrsqrt7.v common-case lookup table contents
| exp[0] | sig[MSB -: 6] | sig__out[MSB -: 7] |
|---|---|---|
| 0 | 0 ~ 63 | 52 ~ 0 |
| 1 | 0 ~ 63 | 127 ~ 53 |
注释:例如,当SEW=32时,vfrsqrt7(0x00718abc (≈ 1.043e-38)) = 0x5f080000 (≈ 9.800e18),而vfrsqrt7(0x7f765432 (≈ 3.274e38)) = 0x1f820000 (≈ 5.506e-20)。
选择7位精度的原因在于其依次需要0至3次牛顿-拉弗森迭代以趋近于bfloat16、FP16、FP32及FP64的精度水平。未来指令将允许设定更高估算精度的需求。
13.10 向量浮点倒数指令
# Floating-point reciprocal estimate to 7 bits.
vfrec7.v vd, vs2, vm
早期草稿版本采用了汇编程序名vfrece7。但因担心其与元素宽度的ex表示法可能产生混淆而被放弃了。为此,在工具链中保留了这一名称作为备用名称存在。
这是一条向量-向量一元指令,它返回一个精确到7位的1 / x的估算值。
下表描述了该指令对于所有浮点输入类别的行为,其中B是指数偏差:
| Input(x) | Rounding Mode | Ouput(y- 1/x) | Exceptions Raised |
|---|---|---|---|
| -∞ | any | -0.0 | |
| -2B+1 < x __ = -2B (normal) | any | -2-(B+1) ≥ y __ > -2-B (subnormal, sig=01…) | |
| -2B < x __ = -2B-1 (normal) | any | -2-B ≥ y __ > -2-B+1 (subnormal, sig=1…) | |
| -2B-1 < x __ = -2-B+1 (normal) | any | -2-B+1 ≥ y __ > -2B-1 (normal) | |
| -2-B+1 < x __ = -2-B (subnormal, sig=1…) | any | -2B-1 ≥ y __ > -2B (normal) | |
| -2-B < x __ = -2-(B+1) (subnormal, sig=01…) | any | -2B ≥ y __ > -2B+1 (normal) | |
| -2-(B+1) < x __ < -0.0 (subnormal, sig=00…) | RUP, RTZ | greatest-mag. negative inite value | NX, OF |
| -2-(B+1) < x __ < -0.0 (subnormal, sig=00…) | RDN, RNE, RMM | -∞ | NX, OF |
| -0.0 | any | -∞ | DZ |
| +0.0 | any | +∞ | DZ |
| +0.0 < x __ < 2-(B+1) (subnormal, sig=00…) | RUP, RNE, RMM | +∞ | NX, OF |
| +0.0 < x __ < 2-(B+1) (subnormal, sig=00…) | RDN, RTZ | greatest inite value | NX, OF |
| 2-(B+1) = x __ < 2-B (subnormal, sig=01…) | any | 2B+1 > y __ ≥ 2B (normal) | |
| 2-B = x __ < 2-B+1 (subnormal, sig=1…) | any | 2B > y __ ≥ 2B-1 (normal) | |
| 2-B+1 = x __ < 2B-1 (normal) | any | 2B-1 > y __ ≥ 2-B+1 (normal) | |
| 2B-1 = x __ < 2B (normal) | any | 2-B+1 > y __ ≥ 2-B (subnormal, sig=1…) | |
| 2B = x __ < 2B+1 (normal) | any | 2-B > y __ ≥ 2-(B+1) (subnormal, sig=01…) | |
| +∞ | any | +0.0 | |
| qNaN | any | canonical NaN | |
| sNaN | any | canonical NaN | NV |
注意:在次正常情况下(即当参数值介于2^{-(B+1)}时),该系统将返回正常的计算结果;而对于超正常情况(即参数值小于2^{-(B+1)}),则会触发异常处理机制以避免计算溢出)。在正常情况下(即当参数值大于等于2^{(B-1)}时),系统将采用特殊算法来处理数据以确保计算精度;而当参数值小于该阈值时,则会采用数值稳定算法以减少计算误差的影响
当发生溢出异常时,输出值取决于动态舍入模式。
对于非异常情况,在处理尾数时最高7位被用来查询相关表格。查询结果将直接映射到最终结果的小数部分高位7位;而低位则全部置零。系统会在查找前自动对次正规输入进行归一化处理,并根据需求调整指数值。为了提高精度,在确定输出指数时会尽量使其与参数倒数相匹配;同时也会对中间结果进行反归一化处理。
详细说明如下:计算规则如下。若输入数据为合法数值,则使规范化的输入指数量与原始输入指数量相等;若为非合法数值,则将规范化的输入指数量设为负尾数中前导零的数量。规范化的输出指数量由下式确定:OB = (2^B - 1) - NORM_{IN}. 若OB超出范围[-1, 2^B]则对应于表中所列异常情况之一。
假设输入属于次正规类别,则通过将 输入的小数值 向左移一位并减去其对应的指数值来获得标准化后的 尾数值 ,并舍弃 前导的一位 。反之,则直接采用原始的小数值作为标准化后的 尾数值 。表格列出了标准化后输出高位的有效数字(MSBs),这些值基于标准化前小数值中的高位数字所决定;而标准化后低位的所有数字均为零。
Table 17. vfrec7.v common-case lookup table contents
| sig[MSB -: 7] | sig__out[MSB -: 7] |
|---|---|
| 0 ~127 | 127 ~ 0 |
若归一化输出指数设为零或负一,则结果属于亚正常值:归一化处理后的尾部数字在前加一个零后整体右移相应的位数。反之则,归一化处理后的尾部数字直接作为最终结果,其归一化指数则与原始数据一致,符号部分同样保持一致。
注意:例如,当SEW=32时,vfrec7(0x00718abc (≈ 1.043e-38)) = 0x7e900000 (≈ 9.570e37),而vfrec7(0x7f765432 (≈ 3.274e38)) = 0x00214000 (≈ 3.053e-39)。
选择7位有效数字的精度水平是因为它分别需要0、1、2、3次牛顿-拉弗森迭代才能达到如bfloat16、FP16等格式所需的精度标准。未来的指令将能够设定更高估算精度。
13.11 向量浮点最大/最小值指令
向量浮点vfm in指令及其vfmax行为等同于RISC-V F/D/Q扩展2.2版中相应的标量浮点指令。
# Floating-point minimum
vfmin.vv vd, vs2, vs1, vm # Vector-vector
vfmin.vf vd, vs2, rs1, vm # vector-scalar
# Floating-point maximum
vfmax.vv vd, vs2, vs1, vm # Vector-vector
vfmax.vf vd, vs2, rs1, vm # vector-scalar
13.12 向量注入指令
符号位注入指令采用向量化处理的方式生成相应的控制信号序列。计算所得的结果基于向量vs2操作数中的所有数据位进行提取。
vfsgnj.vv vd, vs2, vs1, vm # Vector-vector
vfsgnj.vf vd, vs2, rs1, vm # vector-scalar
vfsgnjn.vv vd, vs2, vs1, vm # Vector-vector
vfsgnjn.vf vd, vs2, rs1, vm # vector-scalar
vfsgnjx.vv vd, vs2, vs1, vm # Vector-vector
vfsgnjx.vf vd, vs2, rs1, vm # vector-scalar
请注释以下浮点数值向量运算符功能:该伪指令允许对指定目的寄存器vd中的浮点数值执行取反运算,并将结果存储到同一目的寄存器中。此伪指令定义了以下形式的操作:vfneg.v vd, vs = vfsgnjn.vv vd, vs, vs
可以使用符号插入指令和同一来源的操作数用于计算浮点元素向量的绝对值。该汇编伪指令vfabs.v定义为:vd,vd=vfsgnjx.vvd,vd,vd
13.13 向量比较指令
这些FP类型的矢量化指令用于对两个源操作数执行比较运算,并将运算结果存储在对应的mask寄存器中。为了提高效率,在机器周期内即可完成所有mask数据的获取与处理工作;其中使用的mask数据通常存储在一个专用的mask寄存器中;其具体布局请参见'mask寄存器配置'部分;值得注意的是该功能模块支持多线程并行处理;这种设计不仅降低了硬件开销还显著提升了系统的吞吐能力
该类指令的行为与标量浮点运算指令的语义相一致。仅当它们接收到来自运算单元的操作码中有无效数值(NaN)时才会触发无效操作异常。这些指令会在运算单元产生有效结果的同时接收到静默的无效数值(NaN)或者收到有效的结果并同时存在有效与静默的无效数值的情况下触发无效操作异常。如果任意一个操作源数据域包含无效数值(NaN),则会将数值1赋值给目标数据域中的相应位置。
# Compare equal
vmfeq.vv vd, vs2, vs1, vm # Vector-vector
vmfeq.vf vd, vs2, rs1, vm # vector-scalar
# Compare not equal
vmfne.vv vd, vs2, vs1, vm # Vector-vector
vmfne.vf vd, vs2, rs1, vm # vector-scalar
# Compare less than
vmflt.vv vd, vs2, vs1, vm # Vector-vector
vmflt.vf vd, vs2, rs1, vm # vector-scalar
# Compare less than or equal
vmfle.vv vd, vs2, vs1, vm # Vector-vector
vmfle.vf vd, vs2, rs1, vm # vector-scalar
# Compare greater than
vmfgt.vf vd, vs2, rs1, vm # vector-scalar
# Compare greater than or equal
vmfge.vf vd, vs2, rs1, vm # vector-scalar

Comparison Assembler Mapping Assembler pseudoinstruction
va < vb vmflt.vv vd, va, vb, vm
va <= vb vmfle.vv vd, va, vb, vm
va > vb vmflt.vv vd, vb, va, vm vmfgt.vv vd, va, vb, vm
va >= vb vmfle.vv vd, vb, va, vm vmfge.vv vd, va, vb, vm
va < f vmflt.vf vd, va, f, vm
va <= f vmfle.vf vd, va, f, vm
va > f vmfgt.vf vd, va, f, vm
va >= f vmfge.vf vd, va, f, vm
va, vb vector register groups
f scalar floating-point register

注意:提供所有形式是必要的,以便正确处理NaN的无序比较。
当任一输入为NaN时, 可以通过忽略信号比较过程来遵循C99标准下的静默比较机制, 并在注文中进行说明. 如果被比较的数值是非NaN常量, 则无需执行中间两个指令.
# Example of implementing isgreater()
vmfeq.vv v0, va, va # Only set where A is not NaN .
vmfeq.vv v1, vb, vb # Only set where B is not NaN .
vmand.mm v0, v0, v1 # Only set where A and B are ordered,
vmfgt.vv v0, va, vb, v0.t # so only set flags on ordered values.
注意:在上述序列中,容易想到要去屏蔽第二个vmfeq指令并移除vmand指令的操作。然而,在这种更为高效的操作流程中,在va向量中的一个元素包含了静默的nan值(即未被激活),而vb向量中对应的元素则包含了带有信号激活状态的nan值时,则会导致无法正确触发无效异常的情形发生。
13.14 向量浮点分类指令
这是一个向量-向量一元指令,其操作方式与标量分类指令相同。
vfclass.v vd, vs2, vm # Vector-vector
此指令所生成的10位掩码被置于结果元素的有效最低位置上;其中其高阶位置则全部置零;该指令仅适用于SEW定义为至少16位的情况;因此最终的结果始终包含在目标元素内部
13.15 向量-标量浮点合并指令
支持了vector-scalar类型浮点合并指令。该指令会对位于vstart至vl范围内的所有有效元素执行操作,并不受masking掩码影响。
vfmerge.vfm指令表示为屏蔽指令vm=0;当掩码域为零时赋值第一个向量操作数至目标域;否则赋值标量浮点寄存器至目标域。
vfmerge.vfm vd, vs2, rs1, v0 # vd[i] = v0.mask[i] ? f[rs1] : vs2[i]
13.16 向量浮点移位指令
向量浮点移位操作符负责将单个浮点标量操作数分布至一个向量寄存器组中的各个位置。该操作符的功能是将源f寄存器中的数值复制到目标向量寄存器中的所有活跃存储单元。这种操作符被特别标识为vm=1类的屏蔽型操作符。为了确保数据完整性,在执行过程中必须明确指定vs2字段的值应设为v0,并使该字段的其余各项保持不变
vfmv.v.f vd, rs1 # vd[i] = f[rs1]
注意:vfmv.v.f指令与vfmerge.vfm指令共享编码,但vm=1且vs2=v0。
13.17 浮点/整数转换指令
实现一种能够将浮点数值与无符号整数及有符号整数之间相互转换的操作,在这种情况下源数据与目标数据均为SEW宽度
vfcvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer.
vfcvt.x.f.v vd, vs2, vm # Convert float to signed integer.
vfcvt.rtz.xu.f.v vd, vs2, vm # Convert float to unsigned integer, truncating.
vfcvt.rtz.x.f.v vd, vs2, vm # Convert float to signed integer, truncating.
vfcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to float.
vfcvt.f.x.v vd, vs2, vm # Convert signed integer to float.
在发生异常时进行的转换遵循与标量转换指令相同的规则。而使用frm中的动态舍入模式(除非是rtz变体),它们则会朝零方向进行舍入。
该rtz变体被提供以便加快从浮点向整数转换过程中的截断速度,在C语言及Java等其他编程语言中被广泛采用。
13.18 扩展浮点/整数转换指令
生成一组转换指令旨在用于在更狭窄的数据类型与具有双倍宽度的数据类型之间实现数据类型的扩展。
vfwcvt.xu.f.v vd, vs2, vm # Convert float to double-width unsigned integer.
vfwcvt.x.f.v vd, vs2, vm # Convert float to double-width signed integer.
vfwcvt.rtz.xu.f.v vd, vs2, vm # Convert float to double-width unsigned integer, truncating.
vfwcvt.rtz.x.f.v vd, vs2, vm # Convert float to double-width signed integer, truncating.
vfwcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to double-width float.
vfwcvt.f.x.v vd, vs2, vm # Convert signed integer to double-width float.
vfwcvt.f.f.v vd, vs2, vm # Convert single-width float to double-width float.
这些指令集对向量寄存器重叠区域施加的约束与扩展性指令在处理方式上一致。
双宽度IEEE浮点值总是可以准确地表示单宽度整数。
双宽度IEEE浮点值总是可以准确地表示单宽度IEEE浮点值。
不建议将浮点加宽转换视为一个完整的单一指令集;然而任何加宽转换操作都可以通过一系列倍增步骤来完成;其最终结果是等效的,并且不会触发额外的异常标志。
13.19 压缩浮点/整数类型转换
该系统提供了转换指令集合,旨在将宽度更大的整数和浮点数据类型转换为宽度减半的类型。
vfncvt.xu.f.w vd, vs2, vm # Convert double-width float to unsigned integer.
vfncvt.x.f.w vd, vs2, vm # Convert double-width float to signed integer.
vfncvt.rtz.xu.f.w vd, vs2, vm # Convert double-width float to unsigned integer, truncating.
vfncvt.rtz.x.f.w vd, vs2, vm # Convert double-width float to signed integer, truncating.
vfncvt.f.xu.w vd, vs2, vm # Convert double-width unsigned integer to float.
vfncvt.f.x.w vd, vs2, vm # Convert double-width signed integer to float.
vfncvt.f.f.w vd, vs2, vm # Convert double-width float to single-width float.
vfncvt.rod.f.f.w vd, vs2, vm # Convert double-width float to single-width float,
#rounding towards odd.
此类指令规定了向量寄存器重叠时必须满足的条件,并与缩减向量算术指令的功能一致(参见缩减向量算术指令)。
不能将浮点缩小转换作为一个完整的单指令集合来处理。完成转换的过程可通过逐步减半的方式进行。若在执行所有中间减半步骤时采用向奇数舍入(vfncvt.rod.f.f.w)的方式,则最终结果会被等效地处理,并导致相同的异常标志出现。而最终一步必须采用指定的精度控制方式才能确保计算正确性。
