VREM.VV

RISC-V VREM.VV 指令详解

指令手册OPMVV (OP-V)

VREM.VV 对活动元素执行 SEW 位有符号求余;非零余数与被除数同号,除零返回被除数。

指令语法

vrem.vv vd, vs2, vs1, vm
操作数说明
语法:vrem.vv vd, vs2, vs1[, v0.t];省略掩码为 vm=1,给出 v0.t 为 vm=0。32 位 OP-V:opcode=1010111、funct3=010(OPMVV)、funct6=100011。
vs2[i] 是被除数,vs1[i] 是除数,按有符号 SEW 整数逐元素求余;非零余数与被除数同号。除数为0返回被除数;最小负数除以-1返回余数0。
活动 body 满足 vstart≤i<vl 且掩码开启;inactive/tail 按 vma/vta 保留或取 agnostic,不应依赖固定值。vl=0 不更新任何目标元素。
同宽源/目标允许重叠;masked vd 不可为 v0;v0 不能同时提供 EEW=1 掩码和 SEW 数据。组起点按 EMUL 对齐,EMUL≤8。
要求 V 1.0、已启用向量状态和合法受支持 vtype/SEW。动画固定 m1、vstart=0、VLEN=4096;教学步骤不表示处理器周期。
V向量整数运算除法/求余

指令行为说明

VREM.VV 是 RISC-V V 扩展的 向量-向量 有符号整数余数指令。每个活动元素以 vs2 为被除数、以vs1 同 lane 元素为除数,按 SEW 位宽计算余数并写回 vd;除数为 0 和有符号溢出特例使用官方定义结果,不产生除零 trap。

VREM.VV 指令解析与执行动画

从 OP-V 编码字段开始,展示 VREM 如何逐元素计算有符号余数,并按官方规则处理除零和有符号溢出特例。

输入的指令
vrem.vv

要求 V 1.0、已启用向量状态及合法受支持 vtype/SEW。固定 LMUL=m1、vstart=0、VLEN=4096,VLMAX=4096/16=256。普通 masked vd 不可为 v0;同宽源/目标可重叠。两个源按 SEW 位有符号整数解释;余数的非零符号与被除数相同。输入使用非负 SEW 位模式。v0 提供 EEW=1 掩码时不可同时作 SEW 数据源。VL=0 不更新任何目标元素;这里只展示 body,不伪造 inactive/tail 的确定值。步骤是教学分解,不是处理器周期。

执行环境
OP-V encodingvrem.vv
funct6
100011
vm
0
vs2
01000
vs1
01100
funct3
010
vd
00100
opcode
1010111
lane
0
1
2
3
4
5
6
7
v8
0x0064
0xffd6
0x8000
0x007f
0xffff
0x0001
0x0064
0xffd6
%
%
%
%
%
%
%
%
v12
0x0009
0x0000
0xffff
0xffff
0x0003
0x0001
0x0009
0x0000
v0.t
1
0
1
1
1
0
1
1
v4
...
-
...
...
...
-
...
...
当前步骤

显示 OP-V 32 位编码字段

vrem.vv 使用 OP-V 编码。动画把固定字段、寄存器字段、vm 和 vs1 字段放在同一条编码带中。

动画展示 OP-V 字段解析、活动元素读取、SEW 宽有符号整数求余、mask 控制和 vd 写回。步骤是教学分解,不表示流水线、缓存或执行时延。

快速理解与检索要点

VREM.VV 不产生除零异常。它在当前 vl 的活动元素上读取 vs2 作为被除数、读取vs1 同 lane 元素作为除数,写回 有符号余数;vm=0 时只执行 v0.t 为 1 的 body 元素。

VREM.VV 使用 32 位 OP-V 编码:opcode=1010111、funct3=010(OPMVV)、funct6=100011。
vs2 是被除数;除数来自vs1 同 lane 元素;每个 lane 独立计算,不跨 lane 组合。
源操作数按有符号二进制补码 SEW 整数解释,结果是余数。
除数为 0 时,余数结果为被除数的 SEW 位模式。
有符号最小负数除以 -1 的溢出特例:VDIV 写回被除数,VREM 写回 0。
vm=0 使用 v0.t 执行掩码;mask-off 与 tail 元素按当前 vtype 策略处理。
有符号除法的商向零舍入;非零余数与被除数同号。要求已启用向量状态、合法受支持 vtype/SEW;vl=0 不更新任何目标元素。

向量执行上下文

语法:vrem.vv vd, vs2, vs1[, v0.t];省略掩码为 vm=1,给出 v0.t 为 vm=0。32 位 OP-V:opcode=1010111、funct3=010(OPMVV)、funct6=100011。

vs2[i] 是被除数,vs1[i] 是除数,按有符号 SEW 整数逐元素求余;非零余数与被除数同号。除数为0返回被除数;最小负数除以-1返回余数0。

活动 body 满足 vstart≤i<vl 且掩码开启;inactive/tail 按 vma/vta 保留或取 agnostic,不应依赖固定值。vl=0 不更新任何目标元素。

同宽源/目标允许重叠;masked vd 不可为 v0;v0 不能同时提供 EEW=1 掩码和 SEW 数据。组起点按 EMUL 对齐,EMUL≤8。

要求 V 1.0、已启用向量状态和合法受支持 vtype/SEW。动画固定 m1、vstart=0、VLEN=4096;教学步骤不表示处理器周期。

The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture — Version 20260120, Chapter 31

常见使用场景

逐元素有符号求余

假定 V/VS 已启用、合法 m1、支持 SEW、VLEN≥128、vl=4、vstart=0、v0.mask[0..3]=1111,源已初始化。SEW=8, v12=[249(-7),7,128(-128),5], v4=[3,253(-3),255(-1),0] → v8=[255(-1),1,0,5]。逐元素求余;inactive/tail 按 vma/vta。vl=0 不更新目标。

带掩码的向量求余

假定 V/VS 已启用、合法 m1、支持 SEW、VLEN≥128、vl=4、vstart=0、v0.mask[0..3]=1111,源已初始化。SEW=8, v12=[249(-7),7,128(-128),5], v4=[3,253(-3),255(-1),0] → v8=[255(-1),1,0,5]。逐元素求余;inactive/tail 按 vma/vta。vl=0 不更新目标。

使用前检查清单

语法检查
  • 语法:vrem.vv vd, vs2, vs1[, v0.t];省略掩码为 vm=1,给出 v0.t 为 vm=0。32 位 OP-V:opcode=1010111、funct3=010(OPMVV)、funct6=100011。
  • vs2[i] 是被除数,vs1[i] 是除数,按有符号 SEW 整数逐元素求余;非零余数与被除数同号。除数为0返回被除数;最小负数除以-1返回余数0。
语义检查
  • 活动 body 满足 vstart≤i<vl 且掩码开启;inactive/tail 按 vma/vta 保留或取 agnostic,不应依赖固定值。vl=0 不更新任何目标元素。
  • 同宽源/目标允许重叠;masked vd 不可为 v0;v0 不能同时提供 EEW=1 掩码和 SEW 数据。组起点按 EMUL 对齐,EMUL≤8。
  • 要求 V 1.0、已启用向量状态和合法受支持 vtype/SEW。动画固定 m1、vstart=0、VLEN=4096;教学步骤不表示处理器周期。

容易混淆 / 常见误区

除数为 0 不会 trap;需要错误路径的软件必须显式检测除数。
有符号最小负数除以 -1 是官方定义的溢出特例:除法写回被除数,余数写回 0。
第二源来自 vs1 的同 lane 元素;没有标量除以向量的反向形式。

常见问题

VREM.VV 除零会产生异常吗?

不会。官方 V 扩展为除零定义了确定结果:余数写回被除数,指令本身不产生除零 trap。

VREM.VV 和 VDIV 的关系是什么?

VREM.VV 写回余数;配套的 VDIV 形式写回同一除法关系下的商。两者都使用相同的除零和有符号溢出特例规则。