跳转至

原子指令

原子指令,也称为原子操作或者是原子性指令,是指在多处理器系统或多线程环境中执行时不会被中断的操作,即操作要么完全执行,要么完全不执行。因为这些环境中可能有多个处理器或线程同时访问共享资源。原子指令可以确保这些操作不会被打断或部分执行,从而避免数据不一致和出现不可预测的结果。一条原子指令往往包含一组操作,这样可以提高指令集的效率、简化编程模型、减少指令流水线的开销、以及提高处理器的吞吐量。

系统块中原子指令目前主要包含以下几种:

LOAD.OP类指令

LOAD.OP类指令从左源寄存器SrcL指定的内存位置读出32或64位的值,将其写入目的寄存器。然后将这个读出的值与右源寄存器SrcR的值执行相应的操作(例如相加,按位与等),计算结果存入SrcL寄存器指定的内存中,并且保证这些步骤都是原子的。

微指令 汇编格式 描述
LW.ADD lw.add<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 加内存字写回,输出原内存字
LW.AND lw.and<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 与内存字写回,输出原内存字
LW.OR lw.or<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 或内存字写回,输出原内存字
LW.XOR lw.xor<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 异或内存字写回,输出原内存字
LW.SMAX lw.smax<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存字比较有符号最大值写回,输出原内存字
LW.UMAX lw.umax<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存字比较无符号最大值写回,输出原内存字
LW.SMIN lw.smin<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存字比较有符号最小值写回,输出原内存字
LW.UMIN lw.umin<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存字比较无符号最小值写回,输出原内存字
LD.ADD ld.add<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 加内存双字写回,输出原内存双字
LD.AND ld.and<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 与内存双字写回,输出原内存双字
LD.OR ld.or<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 或内存双字写回,输出原内存双字
LD.XOR ld.xor<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 异或内存双字写回,输出原内存双字
LD.SMAX ld.smax<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存双字比较有符号最大值写回,输出原内存双字
LD.UMAX ld.umax<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存双字比较无符号最大值写回,输出原内存双字
LD.SMIN ld.smin<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存双字比较有符号最小值写回,输出原内存双字
LD.UMIN ld.umin<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存双字比较无符号最小值写回,输出原内存双字

LOAD.OP类原子指令可以通过"aq"和"rl"两个后缀来添加额外的内存访问顺序限制,以保证内存访问的一致性。具体定义请见“内存访问限制参数表”。

AtomicLoad

STORE.OP类指令

STORE.OP类指令与LOAD.OP类指令基本功能相同,只不过没有目的寄存器,不会返回指定内存位置上没有修改之前的值。

微指令 汇编格式 描述
SW.ADD sw.add<{.rl}> [SrcL], SrcR 加内存字写回
SW.AND sw.and<{.rl}> [SrcL], SrcR 与内存字写回
SW.OR sw.or<{.rl}> [SrcL], SrcR 或内存字写回
SW.XOR sw.xor<{.rl}> [SrcL], SrcR 异或内存字写回
SW.SMAX sw.smax<{.rl}> [SrcL], SrcR 内存字比较有符号最大值写回
SW.UMAX sw.umax<{.rl}> [SrcL], SrcR 内存字比较无符号最大值写回
SW.SMIN sw.smin<{.rl}> [SrcL], SrcR 内存字比较有符号最小值写回
SW.UMIN sw.umin<{.rl}> [SrcL], SrcR 内存字比较无符号最小值写回
SD.ADD sd.add<{.rl}> [SrcL], SrcR 加内存双字写回
SD.AND sd.and<{.rl}> [SrcL], SrcR 与内存双字写回
SD.OR sd.or<{.rl}> [SrcL], SrcR 或内存双字写回
SD.XOR sd.xor<{.rl}> [SrcL], SrcR 异或内存双字写回
SD.SMAX sd.smax<{.rl}> [SrcL], SrcR 内存双字比较有符号最大值写回
SD.UMAX sd.umax<{.rl}> [SrcL], SrcR 内存双字比较无符号最大值写回
SD.SMIN sd.smin<{.rl}> [SrcL], SrcR 内存双字比较有符号最小值写回
SD.UMIN sd.umin<{.rl}> [SrcL], SrcR 内存双字比较无符号最小值写回
SW.SUB sw.sub<{.rl}> [SrcL], SrcR 减内存字写回(v0.58 新增)
SD.SUB sd.sub<{.rl}> [SrcL], SrcR 减内存双字写回(v0.58 新增)

STORE.OP类原子指令需要通过"rl"后缀来添加额外的内存访问顺序限制,以保证内存访问的一致性。详细定义请见“内存访问限制参数表”。

SX 尺寸覆盖扩展(v0.58)

v0.58 起,atomic 主类(6..4=000)的最高 5 位(31..27)统一为 op5 字段:

  • b30..27 为操作码/尺寸码(b27 原为 far,现并入操作码作最低位):操作码 0000=ADD、0001=AND、0010=OR、0011=XOR、0100=SMAX、0101=SMIN、0110=UMAX、0111=UMIN、1000=SUB(新增);LR/SC/SWAP 的尺寸码 0000=B、0001=H、0010=W、0011=D;
  • b31 为标志位:store-op(SW/SD 槽)为尺寸覆盖位(0=字/双字原宽度,1=缩小一档:SW 槽 14..12=011 覆盖为字节 SB,SD 槽 14..12=101 覆盖为半字 SH);LR/SC/SWAP 及 load-op(LW.*/LD.*)为 far 远端访问标志(自 b27 迁至 b31,语义不变);
  • 因此 store-op 类指令不再支持 .f 后缀(b31 已被覆盖位占用);其余家族 .f 后缀保留。

由此新增 4 条尺寸覆盖的原子存储指令:

微指令 汇编格式 描述
SB.ADD sb.add<{.rl}> [SrcL], SrcR 加内存字节写回(SW 槽覆盖)
SB.SUB sb.sub<{.rl}> [SrcL], SrcR 减内存字节写回(SW 槽覆盖)
SH.ADD sh.add<{.rl}> [SrcL], SrcR 加内存半字写回(SD 槽覆盖)
SH.SUB sh.sub<{.rl}> [SrcL], SrcR 减内存半字写回(SD 槽覆盖)

AtomicStore

原子交换指令

原子交换指令从寄存器SrcL指定的内存位置读取8,16,32或64位的值,将其写入目的寄存器。然后再将寄存器SrcR中8,16,32或64位的值存入寄存器SrcL指定的内存中,并且保证这些步骤都是原子的。

微指令 汇编格式 描述
SWAPB swapb<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存与寄存器交换字节
SWAPH swaph<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存与寄存器交换半字
SWAPW swapw<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存与寄存器交换字
SWAPD swapd<{.aq,.rl,.aqrl}> [SrcL], SrcR, ->{t, u, Rd} 内存与寄存器交换双字

原子交换操作指令可以通过"aq"和"rl"两个后缀来添加额外的内存访问顺序限制,以保证内存访问的一致性。具体定义请见“内存访问限制参数表”。

AtomicSwap

原子比较交换指令

原子比较交换指令从寄存器SrcL指定的内存位置读取8,16,32或64位的值,然后再用这个读出的值和寄存器SrcR比较,如果它们相同的话,就把寄存器SrcD中8,16,32或64位的值存入寄存器SrcL指定的内存中。最后不管前面比较的结果相不相同,都把从内存读取的原始值写入目的寄存器中,并且保证这些步骤都是原子的。

32 位编码的 CAS 指令支持 .aq/.rl 排序限制,不支持 .f 远端访问后缀;如需远端访问请使用 48 位的 HL.CAS* 系列指令。

微指令 汇编格式 描述
CASB casb<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} 内存与寄存器比较交换字节
CASH cash<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} 内存与寄存器比较交换半字
CASW casw<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} 内存与寄存器比较交换字
CASD casd<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} 内存与寄存器比较交换双字

AtomicCompareandSwap

原子比较交换指令可以通过"aq"和"rl"两个后缀来添加额外的内存访问顺序限制,以保证内存访问的一致性。具体定义请见“内存访问限制参数表”。

内存访问限制参数表

aq rl 含义
0 0 没有顺序限制
0 1 表示该指令的前序所有访问内存的指令的结果必须在该指令执行之前被观察到
1 0 表示该指令的后序所有访问内存的指令必须等该指令执行完成后才开始执行
1 1 表示该指令的前序所有访问内存的指令的结果必须在该指令执行之前被观察到,该指令的后序所有访问内存的指令必须等该指令执行完成后才开始执行