有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 sky 于 2020-9-28 16:04 编辑
关于这篇文章:
由于译者水平有限,本文可能存在谬误或不当之处,欢迎指正。
以下为正文(连载中):
11 向量算术指令格式向量的算术指令使用与 OP-FP 相邻的新的主要操作码(
)。
funct3 字段的三位用于定义向量指令的子类。
11.1 向量算术指令编码funct3字段对操作数类型和源位置进行编码。 表13. funct3
根据操作码,使用无符号或二进制补码有符号整数算法进行整数运算。
所有的标准向量浮点算术运算都遵循 IEEE-754/2008 标准。所有的向量浮点运算都在 frm 寄存器中使用动态舍入模式。如果 frm字段包含无效的舍入模式,当执行任何向量浮点指令时,即使不依赖舍入模式,或者vl = 0再或者vstart≥vl的,都将引发非法指令异常。
Note:所有向量浮点代码都依赖于frm中的有效值。 当舍入模式无效时,会使得所有向量 FP 指令均异常,从而简化控制逻辑。
向量和向量之间的运算采用由 vs2 和 vs1 指定的向量寄存器组中的两个操作数向量进行计算。
向量与标量之间的运算可以采取三种可能的形式,但无论采取哪种形式,都要从 vs2 指定的向量寄存器组中获取一个操作数向量,并从三个替代源之一获取第二个标量源操作数。
- 对于整数运算,标量可以是编码在 rs1 字段中5位立即数。该值通过符号扩展或加零扩展到SEW 位。
- 对于整数运算,可以从rs1 指定的标量寄存器x中提取标量。如果 XLEN > SEW,则使用x的最低有效SEW位。如果 XLEN < SEW,则x 寄存器的值通过符号扩展到 SEW 位。
- 对于浮点运算,可以从标量寄存器f中获取标量。如果 FLEN> SEW,则检查f寄存器中的值是否为有效的 NaN-boxed 值,如果是,则使用f寄存器的最低有效SEW位,否则将使用规范的 NaN 值。如果执行向量指令时,任何浮点向量操作数的 EEW 都不是支持的浮点类型宽度(包括 FLEN <SEW 时),则会引发非法指令异常。
向量算术指令在vm 字段下被掩码。
- # Assembly syntax pattern for vector binary arithmetic instructions
- # Operations returning vector results, masked by vm (v0.t, <nothing>)
- vop.vv vd, vs2, vs1, vm # integer vector-vector vd[i] = vs2[i] op vs1[i]
- vop.vx vd, vs2, rs1, vm # integer vector-scalar vd[i] = vs2[i] op x[rs1]
- vop.vi vd, vs2, imm, vm # integer vector-immediate vd[i] = vs2[i] op imm
- vfop.vv vd, vs2, vs1, vm # FP vector-vector operation vd[i] = vs2[i] fop vs1[i]
- vfop.vf vd, vs2, rs1, vm # FP vector-scalar operation vd[i] = vs2[i] fop f[rs1]4
复制代码
Note: 在编码中,vs2是第一个操作数,rs1/simm5 而是第二个操作数。这和标准标量排序相反。这种安排保留了现有的编码约定,即仅读取一个标量寄存器,从rs1中读取该指令以及从该rs1字段中获取5位立即数的指令。
- # Assembly syntax pattern for vector ternary arithmetic instructions (multiply-add)
- # Integer operations overwriting sum input
- vop.vv vd, vs1, vs2, vm # vd[i] = vs1[i] * vs2[i] + vd[i]
- vop.vx vd, rs1, vs2, vm # vd[i] = x[rs1] * vs2[i] + vd[i]
- # Integer operations overwriting product input
- vop.vv vd, vs1, vs2, vm # vd[i] = vs1[i] * vd[i] + vs2[i]
- vop.vx vd, rs1, vs2, vm # vd[i] = x[rs1] * vd[i] + vs2[i]
- # Floating-point operations overwriting sum input
- vfop.vv vd, vs1, vs2, vm # vd[i] = vs1[i] * vs2[i] + vd[i]
- vfop.vf vd, rs1, vs2, vm # vd[i] = f[rs1] * vs2[i] + vd[i]
- # Floating-point operations overwriting product input
- vfop.vv vd, vs1, vs2, vm # vd[i] = vs1[i] * vd[i] + vs2[i]
- vfop.vf vd, rs1, vs2, vm # vd[i] = f[rs1] * vd[i] + vs2[i]
复制代码
Note: 对于三进制乘法加法运算,汇编语法始终将目标向量寄存器放在第一位,然后是rs1 或vs1,再然后是vs2。这种顺序为这些三元运算提供了更自然的汇编语言信息,因为乘法运算数始终彼此相邻。
11.2 Widening向量算术指令
一些矢量算术指令被定义为加宽(widening) 操作,其中 EEW = 2 * SEW ,EMUL = 2 * LMUL。
第一个操作数可以是单宽度或双宽度。这些通常在操作码上具有前缀 vw*,或对于矢量浮点运算具有前缀 vfw*。
- Assembly syntax pattern for vector widening arithmetic instructions
- # Double-width result, two single-width sources: 2*SEW = SEW op SEW
- vwop.vv vd, vs2, vs1, vm # integer vector-vector vd[i] = vs2[i] op vs1[i]
- vwop.vx vd, vs2, rs1, vm # integer vector-scalar vd[i] = vs2[i] op x[rs1]
- # Double-width result, first source double-width, second source single-width: 2*SEW = 2*SEW op SEW
- vwop.wv vd, vs2, vs1, vm # integer vector-vector vd[i] = vs2[i] op vs1[i]
- vwop.wx vd, vs2, rs1, vm # integer vector-scalar vd[i] = vs2[i] op x[rs1]
复制代码
Note: 最初,在操作码上使用了后缀 w,但是这可能与使用w后缀来表示双字整数中的字长操作混淆,因此将w其移至前缀。
Note: 浮点加宽操作vfw* 已改为vwf*。
11.3 Narrowing向量算术指令
一些指令可以将双宽度源向量转换为单宽度目标向量。这些指令将 EEW/EMUL = 2 * SEW / 2 * LMUL 的向量寄存器组转换为具有当前 LMUL/SEW 向量/元素的向量寄存器组。
如果 EEW> ELEN 或 EMUL> 8,则会引发非法指令异常。
Note: 一种替代的设计方案是将 LMUL 视为定义源向量寄存器组的大小。
必须使用对源和目标 EMUL 值均合法的向量寄存器数量来指定源向量寄存器组和目标向量寄存器组,否则会引发非法指令异常。
在有第二个源向量寄存器组(由 vs1指定)的地方,其宽度与结果相同(较窄)(即EEW = SEW)。
Note:可以覆写具有相同LMUL和元素宽度的第二个源向量寄存器组。
操作码前缀vn*用于区分汇编器中的这些指令,vfn*前缀用于缩窄浮点操作码。源操作数后缀中的w表示双倍宽度的源向量寄存器组(例如vnsra.wv)
Note: 设置掩码寄存器的比较操作也是一种隐式缩小操作。
完
|