RISC-V矢量指令集学习记录(1)

RISC-V矢量指令集学习记录(1)

原文下载:https://github.com/riscv/riscv-v-spec/releases/tag/v1.0
可以与原文对着看,Note与原文的位置基本一致。

比对v1.0的修改:
https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc
1.将关于非法vtype值的讨论移至配置设置说明部分,并展开解释。
2.如果同一指令将使用两个或多个不同的EEW读取同一矢量寄存器,则保留编码。
3.明确指出vstart和vcsr是XLEN位宽寄存器

1.介绍

本文档是RISC-V矢量扩展的1.1版本。

Note
这个1.0版本被认为是冻结以供公众审查。版本1.0被认为足够稳定,可以开始开发工具链、功能模拟器和实现,包括在上游软件Note项目中,除非在测试期间发现严重的问题,否则预计不会出现不兼容的变化。一旦分级,该规范将提供2.0版本。

该规范包括当前冻结的向量指令的完整集合。在开发过程中考虑过但未在本文件中列出的其他说明不包括在审查和审查过程中,可能会完全修改或放弃。标准向量扩展部分列出了标准向量扩展,以及每个扩展所支持的指令和元素宽度。

2、根据实现而定的常量参数

每个hart支持向量扩展的话,需要定义两个参数:

1.任何操作都可以产生或消耗的向量元素的最大大小ELEN≥8,必须为2的幂。
2.单个向量寄存器中的位数,VLEN≥ELEN,它必须是2的幂,并且不能大于2 16。

标准向量扩展(部分标准向量扩展)和体系结构支持可能会对ELEN和VLEN设置进一步的约束。

Note
未来的扩展可能允许使用多个向量寄存器存储一个元素,即ELEN > VLEN,但是当前的提议不包括此选项。
Note
VLEN的上限允许软件知道索引将变成16位(LMUL=8和VLEN=65,536的SEW=8的最大VLMAX为65,536)。未来任何超过每个向量寄存器64Kib的扩展都需要新的控制指令,这样使用旧的控制指令的软件就不会看到更大的向量长度。

向量扩展支持编写二进制代码,在一定的约束下,可以在VLEN参数的端口上执行,前提是端口支持所需的元素类型和指令。也就是VLEN可以通过参数的方式进行修改。

Note
VLEN可以在实现中进行修改。

Note
通常,在对VLEN或ELEN参数改变期间,不能迁移具有活动向量状态的线程上下文。需要保证没有向量扩展相关内容在执行才能进行VLEN和ELEN的修改。

3、矢量扩展规划器的模型

向量扩展将32个向量寄存器和7个非特权的CSRs(vstart、vxsat、vxrm、vcsr、vtype、vl、vlenb)添加到一个基标量RISC-V ISA中。

地址特权名字描述
0x008URWvstartVector start position
0x009URWvxsatFixed-Point Saturate Flag
0x00AURWvxrmFixed-Point Rounding Mode
0x00FURWvcsrVector control and status register
0xC20UROvlVector length
0xC21UROvtypeVector data type register
0xC22UROvvlenbVLEN/8 (vector register length in bytes)

Note
这四个CSR数字0x00B-0x00E暂时保留在未来的向量CSRs中,其中一些可能会被镜像到vcsr中。

3.1 矢量寄存器

向量扩展将32个架构向量寄存器v0-v31添加到基标量RISC-V ISA中。
每个向量寄存器都有固定的VLEN位。

3.2 在 mstatus中的Vector Context Status

vector context status VS,添加到mstatus[10:9],同时映射到sstatus[10:9]。和floating-point context statusŠFS类似。

当mstatus.VS被设置为OFF时,尝试执行任何矢量指令,或访问矢量CSRs,会引发非法指令异常。

当mstatus.VS被设置为“初始”或“干净”,执行任何改变向量状态的指令,包括向量CSRs,都将改变mstatus.VS到“肮脏”。在任何时候,实现也可能会改变mstatus.VS从“初始”或“干净”到“肮脏”,即使在向量状态没有变化。

Note
准确设置mstatus.VS是一个优化工作。软件通常会使用VS来减少上下文交换的开销。

如果mstatus.VS是脏的,mstatus.SD为1,否则为mstatus.SD根据现有的规格设置。

具体实现可能有一个可写的misa.V。类似于浮点单元的处理方式,即使misa.V是没有置位的,mstatus.VS仍会存在。

Note
当misa.V是没有置位的,仍允许mstatus.VS存在,可以实现矢量仿真,并简化在具有可写misa.V的系统中对mstatus.VS的处理。
也就是有些具体实现,能对misa寄存器进行改写,在这种情况下,mstatus.VS仍有可能存在,这样就有效应对将misa.V改为1的时候,当misa.V改为0,mstatus.VS仍是存在的,只是访问这些寄存器或者使用矢量指令时会报指令异常。

总结:

  • 支持矢量指令集的情况下,会存在vector context status VS文件,在mstatus[10:9]。
  • mstatus.VS为OFF时,任何矢量操作会造成异常;不为OFF时,会表示当前的使用情况,软件可以通过此位来判断系统是否用起来了矢量指令操作。
  • 当misa为只读且misa.V存在的时候,mstatus.VS必定存在;当misa为只读且misa.V不存在的时候,mstatus.VS必定不存在;当misa为可读可写且misa.V存在时,mstatus.VS必定存在;当misa为可读可写且misa.V不存在时,mstatus.VS可能存在也可能是不存在。

3.3 在vsstatus中的Vector Context Status

当系统监控程序扩展存在时,vector context status VS,添加到vsstatus[10:9]。和floating-point context statusŠFS类似。

当V=1,vsstatus.VS和mstatus.VS都生效:两者其一的VS被设置为OFF时,尝试执行任何矢量指令,或访问矢量CSRs,会引发非法指令异常。

当V=1且vsstatus.VS和mstatus.VS均未设置为“关”时,执行任何改变矢量状态的指令(包括矢量CSR)都会将vsstatus.VS和mstatus.VS都更改为“肮脏”。在任何时候,实现也可能会改变mstatus.VS或vsstatus.VS从“初始”或“干净”到“肮脏”,即使在向量状态没有变化。

如果vsstatus.VS是脏的,vsstatus.SD为1,否则为vsstatus.SD根据现有的规格设置。
如果mstatus.VS是脏的,mstatus.SD为1,否则为mstatus.SD根据现有的规格设置。

具体实现可能有一个可写的misa.V。即使misa.V是没有置位的,vsstatus.VS仍会存在。
Hypervisor mode区别于U/S/M模式,所以会有额外的寄存器内容,具体misa和vsstatus的关系可以参考上面misa和mstatus的关系说明。

3.4 矢量类型寄存器,vtype

vtype是只读的csr寄存器,位宽为XLEN,vtype提供了用于解释向量寄存器内容的默认类型,并且只能通过vset{i}vl{i}指令进行更新。向量类型决定了每个向量寄存器中元素的组织,以及多个向量寄存器如何分组。vtype寄存器还指示如何处理矢量结果中超过当前矢量长度的元素。

Note
仅允许通过vset{i}vl{i}指令简单维护vtype寄存器状态。

vtype寄存器有5个内容,vill,vma,vta,vsew[2:0]和vlmul[2:0]。位vtype[XLEN-2:8]应该写0,并且保留内容中的非零值。

Note
此图显示了RV32系统的布局,而通常vill应该在XLEN-1位。若采用的XLEN不同,则具体位置不同。
在这里插入图片描述

BitsNameDescriptor
XLEN-1villIllegal value if set
XLEN-2:80Reserved if non-zero
7vmaVector mask agnostic
6vtaVector tail agnostic
5:3vsew[2:0]Selected element width(SEW) setting
2:0vlmul[2:0]Vector register group multiplier(LMUL) setting

Note
一个支持ELEN=32的小实现在vtype中只需要7位状态:两位ma和ta,两位vsew[1:0],3位vlmul[2:0]。由vill表示的非法值可以使用vsew[1:0]中的非法64位组合进行内部编码,而不需要额外的存储位来保存vill。

Note
进一步的标准和自定义向量扩展可以扩展这些内容,以支持更多种类的数据类型。

Note
vtype CSR的主要动机是允许向量指令设置为填入一个32位的指令编码空间。在执行向量指令之前,可以使用一个单独的vset{i}vl{i}指令来设置vl和/或vtypeŠ,实现可以选择将这两个指令融合到单个的内部向量微群中。在许多情况下,vl和vtype值可以在多个指令之间重用,从而减少了从vset{i}vl{i}指令中产生的静态和动态指令开销。预计未来扩展的64位指令编码将允许这些内容在指令编码中被静态地指定。

3.4.1 矢量选择的元素宽度vsew[2:0]

vsew中的值将设置动态选择的元素宽度(SEW)。默认情况下,一个向量寄存器被视为被划分为VLEN/SEW元素。
在这里插入图片描述在这里插入图片描述

Note
虽然预计较大的vsew[2:0]编码(100-111)将用于编码较大的SEW,但编码在这一点上先保留。
在这里插入图片描述

所支持的元素宽度可能随LMUL而变化。

Note
当前的标准向量扩展集不随LMUL而改变受支持的元素宽度。一些未来的扩展可能只在使用LMUL组合来自多个向量寄存器的位时,才支持更大的sew。在这种情况下,依赖于大型SEW的软件应该尝试使用最大的LMUL,从而使用最少的向量寄存器组,以增加运行代码的实现的数量。在设置vtype后,应检查vtype中的vill位,看看是否支持控制,如果不支持,则应提供替代代码路径。或者,配置文件可以在每个LMUL设置中强制要求最低SEW。

3.4.2 矢量寄存器分组(vlmul[2:0])

多个向量寄存器可以分组在一起,因此单个向量指令可以在多个向量寄存器上操作。这里使用的术语向量寄存器组,是指单个操作的向量指令可以使用一个或多个向量寄存器,即一条向量指令使用一个或多个向量寄存器,将这一个或多个向量寄存器划分一个向量寄存器组。向量寄存器组可以用于为较长的应用程序向量提供更大的执行条件,但包含它们的主要原因是允许使用与单宽元素相同的向量长度来操作双宽或更大的元素。向量长度乘子,LMUL,当大于1时,表示使用多少数量向量寄存器组合成一个向量寄存器组。实现必须支持LMUL整数值1、2、4和8。

Note
向量体系结构包括使用多个具有不同元素宽度,但具有相同元素数量的源和目标向量操作数的指令(即操作相同数量的数据,但数据的位宽不一致)。每个向量操作数的有效LMUL(EMUL)由保存元素所需的寄存器数量决定。例如,对于宽长度的加法操作,如一个32位的值加另一个32位值以产生64位的结果,双宽度的输出结果需要单宽度输入的两倍LMUL(即输入数据为32位,假定32位为一个数据宽度,那么产生的结果为64位,则为输入数据宽度的两倍)。

LMUL也可以是一个分数值,减少了在单个向量寄存器中使用的位数。分数LMUL在混合宽度值上操作时,用于增加有效可用向量寄存器组的数量。假定使用32位的结构,如果LMUL使用分数,那么一个32位的寄存器可以分为1/2/4/8个元素来使用。

Note
如果只有整数LMUL值,在一个大小范围内操作的循环必须为最窄的数据类型分配至少一个整个向量寄存器(LMUL=1),然后消耗多个向量寄存器(LMUL>1)为每个更宽的向量操作数形成一个向量寄存器组。这可以限制可用的向量寄存器组的数量。对于分数LMUL,最宽的值只需要占用一个向量寄存器,而较窄的值可以占用单个向量寄存器的一部分,即使在处理混合宽度值时,也允许在矢量循环中将所有32个矢量寄存器命名为不同值。分数LMUL意味着向量寄存器的部分是未使用的,但在某些情况下,拥有较短的位宽,但寄存器数量多相对于拥有较长的位宽,但寄存器数量少提高了生存效率。

实现必须提供分数LMUL设置,允许最窄支持的类型占据向量寄存器的一部分,对应于最窄支持类型的宽度与最大支持类型的宽度之比。一般来说,要求是支持LMUL≥SEWMIN/ELEN,其中SEWMIN是最窄支持的SEW值,而ELEN是最宽支持的SEW值。在标准扩展中,SEWMIN=8。对于使用ELEN=32的标准向量扩展,必须支持1/2和1/4的分数LMUL。对于使用ELEN=64的标准向量扩展,必须支持1/2、1/4和1/8的分数LMUL。

Note
当LMUL < SEWMIN/ELEN时,不能保证实现在分数向量寄存器中有足够的位来存储至少一个元素,因为VLEN=ELEN是一个有效的实现选择。例如,对于VLEN=ELEN=32和SEWMIN=8,1/8的LMUL在一个向量寄存器中只提供4位的存储,但最小的单元(SEWMIN=8)需要至少8位的位宽。

如果支持LMUL的分数设置,实现必须支持SEW的可配置范围在SEWMIN和LMUL * ELEN之间。

尝试设置不支持的SEW和LMUL将使得vtype中的vill位拉高。

vtype使用LMUL < SEWMIN/ELEN的编码将被保留,但是如果实现不支持这些配置,则可以设置vill为高,表示有异常。

Note
在这种情况下,要求所有实现设置vill将禁止未来在扩展中使用此情况,因此,为了允许未来对LMUL<SEWMIN/ELEN行为的了解,我们认为保留这种情况的使用。

Note
如果一个vsetvli指令试图编写一个LMUL < SEWMIN/ELEN,则建议汇编程序提供一个警告(而不是一个错误)。

LMUL由vtype中的vlmulŠ设置,且vlmul为有符号数(即LMUL = 2 vlmul[2:0])。

推导值VLMAX = LMUL*VLEN/SEW表示在给定当前SEW和LMUL设置下,可以使用单个向量指令操作的最大元素数量,如下表所示。

在这里插入图片描述

当LMUL=2时,向量寄存器组包含向量寄存器vn和向量寄存器v n+1,提供两倍的向量长度。指定LMUL=2向量寄存器组的说明,假如矢量寄存器总数为奇数,那多出来的会被保留。

当LMUL=4时,向量寄存器组包含4个向量寄存器,指定LMUL=4向量寄存器组的说明,假如矢量寄存器总数不为4的倍数,那多出来的会被保留。

当LMUL=8时,向量寄存器组包含8个向量寄存器,指定LMUL=8向量寄存器组的说明,假如矢量寄存器总数不为8的倍数,那多出来的会被保留。

掩码寄存器总是包含在一个单个向量寄存器中,而不管LMUL如何,即分数的实现情况,屏蔽矢量寄存器的某些位。

总结:

  • SEW:矢量元素的位宽,可配置,暂时只支持864,32位的系统支持832,64位的系统支持8~64;若32位系统,SEW选择32,则一个矢量寄存器就是一个矢量元素值,若SEW选8,则一个矢量寄存器可以包含4个矢量元素值。

  • LMUL:可以将一个或多个矢量寄存器划分到一个组中,一条矢量命令可以操作同一个组的全部寄存器,可以操作同一个组的全部矢量元素,存在分数和整数两个方式;分数的话,必定一个矢量寄存器为一个组,整数的话,可以一个或多个适量寄存器组成一个组;LMUL的设定需要符合LMUL≥SEWMIN/ELEN规则;LUML为分数的时候,会使用矢量寄存器中的某些位,其他位需要屏蔽。
    例如32位的系统,SEW选择为32,LMUL为1,也就是一个矢量元素占用32位,一个矢量元素等于一个矢量寄存器,一个矢量寄存器又被划为一个组,所以一共有32个组,一条矢量指令可以操作的矢量元素为VLMAX = LMULVLEN/SEW=132/32=1;
    例如32位的系统,SEW选择为8,LMUL为1,也就是一个矢量元素占用8位,四个矢量元素等于一个矢量寄存器,一个矢量寄存器又被划为一个组,所以一共有32个组,一条矢量指令可以操作的矢量元素为VLMAX = LMULVLEN/SEW=132/8=4;
    例如32位的系统,SEW选择为8,LMUL为2,也就是一个矢量元素占用8位,四个矢量元素等于一个矢量寄存器,两个矢量寄存器又被划为一个组,所以一共有16个组,一条矢量指令可以操作的矢量元素为VLMAX = LMULVLEN/SEW=232/8=8;
    例如32位的系统,SEW选择为16,LMUL为1/2,也就是一个矢量元素占用16位,两个矢量元素等于一个矢量寄存器,LMUL<1,所以必须一个矢量寄存器又被划为一个组,因此一共有32个组,一条矢量指令可以操作的矢量元素为VLMAX = LMULVLEN/SEW=1/232/16=1,这种情况下矢量寄存器的某16位是无效的,另外16位有效;
    例如32位的系统,SEW选择为8,LMUL为1/2,也就是一个矢量元素占用8位,四个矢量元素等于一个矢量寄存器,LMUL<1,所以必须一个矢量寄存器又被划为一个组,因此一共有32个组,一条矢量指令可以操作的矢量元素为VLMAX = LMULVLEN/SEW=1/232/8=2,这种情况下矢量寄存器的某16位是无效的,另外16位有效;
    必须要符合LMUL≥SEWMIN/ELEN的关系,不然会出现不匹配的情况,例如32位的系统,SEW选择为8,LMUL为1/8,也就是一个矢量元素占用8位,四个矢量元素等于一个矢量寄存器,1/8个矢量寄存器又被划为一个组,所以一共有32个组,一条矢量指令可以操作的矢量元素为VLMAX = LMULVLEN/SEW=1/832/8=1/2,也就是说一条矢量指令只能操作一个矢量寄存器中的4位,而矢量元素的最低位宽为8位,造成了不匹配的现象,这种情况下协议中是保留的,但实现中如果不支持的话,需要遇到这种情况的时候使vtype的vill置1,以此报出配置异常。

  • VLMAX:一条矢量指令操作矢量元素的最大数量,VLMAX = LMUL*VLEN/SEW。

  • 矢量寄存器:矢量寄存器为32个,和通用寄存器类似,由硬件实现,矢量寄存器的位宽VLEN决定。

  • 矢量元素:矢量运算的最小单位,必须是2的幂,位宽由ELEN决定,且ELEN≥8。

结合矢量元素、矢量寄存器、VLMAX、LMUL和SEW的说明,就很好理解上面的表格。

3.4.3 Vector Tail Agnostic and Vector Mask Agnostic vta and vma

这两个位分别在执行矢量指令的过程中修改了目标尾部元素和目标非活动掩码元素的行为。尾部和非活动集包含在向量操作期间不接收新结果的元素位置,如在预启动、活动、非活动、主体和尾部元素分段中定义的那样。

所有系统必须支持所有四个选项:

无论vta的设置如何,掩码目标尾部元素总是被视为尾部不可知的。

当一个集合被标记为未受干扰时(undisturbed),向量寄存器组中相应的目标元素集将保留它们以前持有的值。

当一个集合被标记为不可知(agnostic)时,任何向量目标操作数中相应的目标元素集既可以保留它们以前保留的值,也可以用1覆盖。在单个向量指令中,每个目标元素既可以不受干扰,也可以用1s覆盖,在任意组合,当使用相同的输入执行指令时,未受干扰或用1s覆盖的模式不需要是确定性的。

Note
添加了不可知策略以适应向量寄存器重命名的机器。使用不受干扰的策略,必须从旧的物理目标向量寄存器中读取所有元素,以便复制到新的物理目标向量寄存器中。当后续计算不需要这些非活动值或尾部值时,这就会导致初始状态。

Note
重写值选择了全1而不是全0的值,以阻止软件开发人员依赖所写的值。

Note
一个简单的有序实现可以忽略设置,只需使用未受干扰的策略执行所有矢量指令。为了兼容性和支持线程迁移,vta和vma状态位仍必须在vtype中提供。

Note
无序的实现可以选择使用尾部不可知+掩码不受干扰来实现尾部不可知和掩码不可知,以降低实现的复杂性。

Note
不可知结果策略的定义是宽松的,以适应在小的有序核心上的hart(这可能会使不可知区域不受干扰)和较大的无序核心上的带有寄存器重命名的hart之间迁移应用程序线程(这可能用1覆盖不可知元素)。由于可能需要在中间重新启动,我们允许在单个向量指令中任意混合不可知策略。这种允许的策略混合还允许实现可能更改向量寄存器的不同颗粒的策略,例如,在主动操作的颗粒内使用未受干扰的策略,但将尾部的颗粒重命名为全1。

此外,除了掩码加载指令外,掩码结果尾部的任何元素也可以用vl=VLMAX计算的值写入。此外,对于掩码逻辑指令和vmsbf.m、vmsif.m、vmsof.m掩码操作指令,结果尾部的任何元素都可以用vl=VLEN、SEW=8和LMUL=8计算的值来写入(即,可以覆盖掩码寄存器的所有位)。

Note
掩码尾部总是被视为不可知的,以降低管理掩码数据的复杂性,掩码数据可以以位粒度写入。似乎没有什么软件需要支持尾不受干扰的掩码寄存器值。允许掩码生成指令回写指令的结果避免了逻辑屏蔽尾部的需要,除了掩码加载不能将内存值写入目标掩码尾部,因为这意味着访问内存超过了软件意图。

程序集语法向vsetvli指令添加了两个强制标志:
在这里插入图片描述

Note
在v0.9之前,当vsetvli上没有指定这些标志时,它们默认为屏蔽未受干扰/尾部未受干扰。然而,不赞成使用没有这些标志的vsetvli,现在必须指定标志设置。默认值可能是尾部不可知/掩码不可知,因此软件必须指定何时关心非参与元素,但考虑到引入这些标志之前指令的历史意义,决定在未来的汇编代码中始终需要它们。

3.4.4 Vector Type Illegal vill

vill位用于指示之前的一条vset{i}vl{i}指令试图将一个不受支持的值写入vtype。
也就是使用vset{i}vl{i}指令试图将一个不受支持的值写入vtype时,会使vill置1,若vill为0,则写入vtype的值是被支持的。

Note
vill位保存在CSR的XLEN-1位,以支持在符号位上的分支检查非法值。

在确定实现是否支持该值时,必须考虑vtype参数的所有位。
通过vill位来反映配置的vtype值是否被实现(芯片/系统)所支持,而vill位是由vtype的其他所有bit的比对结果来判断是否符合要求的,vtype的其他所有bit都需要纳入考虑范围。

Note
必须检查所有位,以确保新代码在vtype陷阱中具有不受支持的矢量特征,而不是在旧的实现中错误执行。

在配置vtype的时候,将vill位置1是不被支持的,不能通过配置vtype的方式使vill置1。

如果设置了vill位,则任何执行取决于vtype的矢量指令的尝试都将引发非法指令异常。

Note
vset{i}vl{i} 整个寄存器的加载、存储和移动不依赖于vtype。

当vill位被设置时,vtype中的其他XLEN-1位应为零。

总结:

  • vset{i}vl{i}指令可以实现矢量CSR寄存器的loads, stores, and moves,且不受vtype的影响。
  • 在配置vtpye的时候,全部bit需要考虑是否支持该配置,若不支持则需要置位vill,支持则vill为0。
  • 如果vill置1了,则执行任何与vtype相关的矢量指令时均会引起非法指令异常。
  • 当vill置1时,vtype的其他31bits都需要为0。

3.5 Vector Length Register vl

XLEN位宽的只读vl CSR只能通过vset{i}vl{i}指令和fault-only- rst vector load相关指令进行更新。

vl寄存器包含一个无符号整数,指定要用向量指令的结果更新的元素的数量(一条矢量指令操作矢量元素的最大数量),在预启动、活动、非活动、主体和尾部元素删除部分中进一步详细说明。

Note
vl中实现的位数取决于支持的最小类型(一个矢量元素)的最大矢量长度(VLMAX,与LMUL、SEW和VLEN相关),即一条矢量指令操作矢量元素的最大数量。VLEN=32且支持SEW=8的最小矢量实现将需要vl中的至少六个bit来保持值0-32(VLEN=32,LMUL=8且SEW=8,产生VLMAX=32)。

总结:

  • vl填的就是VLMAX,VLMAX说明可以看3.4.2的总结。

3.6 Vector Byte Length vlenb

XLEN位宽的只读CSR vlenb包含值VLEN/8,即以字节为单位的向量寄存器长度。

Note
vlenb中的值是任何实现在设计阶段时确定的常数。

Note
如果没有这个CSR,需要几个指令来计算以字节为单位的VLEN,并且代码必须干扰当前的vl和vtype设置,这需要保存和恢复它们。

3.7 Vector Start Index CSR vstart

vstart,一个可读可写的CSR寄存器,指定向量指令执行的第一个元素的索引,如预启动、活动、非活动、主体和尾部元素等部分所述。

Normally, vstart is only written by hardware on a trap on a vector instruction, with the vstart value representing the element on which the trap was taken (either a synchronous exception or an asynchronous interrupt), and at which execution should resume after a resumable trap is handled.

通常,vstart只能由硬件在向量指令触发的陷阱中进行修改,vstart值表示陷阱使用的元素(陷阱有同步异常或异步中断),在处理了可恢复的陷阱后应该恢复其状态。

所有向量指令都被定义为以vstart CSR中给定的元素编号开始执行,使目标向量中较早的元素不受干扰,并在执行结束时将vstart CSR重置为零。

Note
所有向量指令,包括vset{i}vl{i},将vstart CSR重置为零。

vstart is not modified by vector instructions that raise illegal-instruction exceptions.

vstart不会被引发非法指令异常的向量指令修改。

vstart CSR被定义为只有足够的可写位来保存最大的元素索引(比最大VLMAX少1)。

Note
最大矢量长度是通过最大LMUL设置(8)和最小SEW设置(8”)获得的,因此VLMAX_max=8*VLEN/8=VLEN。例如,对于VLEN=256,vstart将具有8个比特来表示从0到255的索引。

保留使用大于当前SEW设置的最大元素索引的vstart值。

Note
如果vstart超出界限,建议实现陷阱。不需要陷阱,因为未来可能使用较高的vstart位来存储不精确的陷阱信息。

vstart CSR可由非特权代码写入,但非零的vstart值可能会导致矢量指令在某些实现中运行速度明显较慢,因此应用程序不应使用vstart。少数矢量指令不能使用非零vstart值执行,并且会引发如下定义的非法指令异常。

Note
使vstart对非特权代码可见,支持用户级线程库。

Implementations are permitted to raise illegal instruction exceptions when attempting to execute a vector instruction with a value of vstart that the implementation can never produce when executing that same instruction with the same vtype setting.

少数矢量指令不能使用非零vstart值执行,当试图执行值为vstart的矢量指令时,允许实现引发非法指令异常,而当执行具有相同vtype设置的同一指令时,该实现永远无法产生该异常。(个人感觉这里需要区分不同的模式,这里针对的是非特权模式,使用vtype的是特权模式)

Note
例如,一些实现在执行矢量算术指令期间永远不会接受中断,而是等到指令完成后再接受中断。当vstart为非零时,当尝试执行向量算术指令时,允许此类实现引发非法指令异常。

Note
在具有不同微体系结构的两个hart之间迁移软件线程时,新hart微体系结构可能不支持vstart值。然后,接收hart上的运行时可能必须模拟指令执行,直到下一个支持的vstart元素位置。或者,可以将迁移事件限制为仅发生在相互支持的vstart位置。

3.8 Vector Fixed-Point Rounding Mode Register vxrm

矢量定点舍入模式寄存器在最低有效位(vxrm[1:0])中保持两位读写舍入模式字段。高位vxrm[XLEN-1:2]应写为零。

向量定点舍入模式被赋予一个单独的CSR地址以允许独立访问,但也反映为vcsr中的字段。

Note
可以在使用单个csrwi指令保存原始舍入模式的同时设置新的舍入模式。

定点舍入算法指定如下。假设舍入前结果是v,这个结果的d位将被四舍五入。则取整结果为(v>>d)+r,其中r取决于下表中指定的取整模式。
在这里插入图片描述
舍入函数:
在这里插入图片描述

用于在下面的指令描述中表示此操作。

3.9 Vector Fixed-Point Saturation Flag vxsat

vxsat CSR有一个读写最低有效位(vxsat[0]),指示定点指令是否必须使输出值饱和才能适应目标格式。位vxsat[XLEN-1:1]应写为零。
vxsat位在vcsr中镜像。

3.10 Vector Control and Status Register vcsr

vxrm和vxsat单独的CSR也可以通过矢量控制和状态CSR、vcsr中的字段访问。

3.11 State of Vector Extension at Reset

矢量扩展在重置时必须具有一致的状态。特别是,vtype和vl必须具有可以通过单个vsetvl指令读取然后恢复的值。

Note
建议在重置时,设置vtype.vill为1,vtype中的剩余位为零,vl设置为零。

vstart、vxrm、vxsatcsr在重置时可以有任意的值。

矢量单元的大多数使用都需要一条初始vset{i}vl{i}命令,来重置vstart。使用前,应在软件中明确重置vxrm和vxsat字段。

矢量寄存器在重置时可以有任意的值。

后续进行中…

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值