SC.W¶
说明¶
条件存入字(Store-Conditional Word)
本指令执行如下的原子操作:如果以右源操作数为地址的内存上存在加载保留,将左源操作数的低位4个字节的数据存入该地址。如果存入成功,将0写入目的寄存器;否则写入一个非0的错误码。
汇编语法¶
编码格式¶
汇编符号¶
- SrcL:左源寄存器,可以索引全局寄存器R0-R23和前序1-4条输出至T队列或U队列的指令结果。
- SrcR:右源寄存器,可以索引全局寄存器R0-R23和前序1-4条输出至T队列或U队列的指令结果。
- .aq,.rl:内存访问限制,详见原子指令介绍。
- .f:指令可选后缀,表示内存访问发生在远端Cache中。
- ->:用于指示目的寄存器。
- {t,u,Rd}:表示三种可选的目的寄存器,编码于RegDst域。其中:
- t,u:分别表示块内的T和U寄存器队列。
- Rd:可以索引全局寄存器R1-R23。
执行方式¶
- 转换为十进制数:UInt()
- 通用寄存器读写:R[]
- 条件存储:StoreConditonal()-把值写到目标地址之前,会先判断目标内存地址是否有设置保留标记,如果设置了,则把值正常写入到目标内存地址里,并把目的寄存器设置成 0,表示保存成功。如果目的内存地址没有设置保留标记,则不保存,并把目的寄存器设置成非 0 表示保存失败。不管成功还是失败,sc指令都会把当前保留的所有标记清除。
integer d = UInt(RegDst);
integer m = UInt(SrcL);
integer n = UInt(SrcR);
integer datawidth = 64;
bits(datawidth) operand = R[m, datawidth];
bits(datawidth) address = R[n, datawidth];
bits(datawidth) result = StoreConditonal(Mem[address], operand[31:0]);
R[d, datawidth] = result;
汇编示例¶
用 lr/sc 实现内存字 Mem[a0]的比较-交换操作:预期的旧值在a1中;所需的新值在a2中。
0 : lr.w [a0], ->t /* 加载旧的值 */
4 : b.ne t#1, a1, 60 /* 比较旧的值与a1是否相等 */
8 : sc.w a2, [a0], ->t /* 相等则存入新的值 */
c : b.ne t#1, zero, 0 /* 如果存入失败,重新尝试 */
... /* 比较交换成功之后执行的指令 */
...
60: /* 比较交换不成功 */
汇编索引模式¶
指令输出到块内t寄存器:
sc.w a1, [a2], ->t /* 双寄存器绝对索引 */
sc.w a1, [t#2], ->t /* 双寄存器混合索引 */
sc.w a1, [u#2], ->t /* 双寄存器混合索引 */
sc.w t#1, [a2], ->t /* 双寄存器混合索引 */
sc.w t#1, [t#2], ->t /* 双寄存器相对索引 */
sc.w t#1, [u#2], ->t /* 双寄存器相对索引 */
sc.w u#1, [a2], ->t /* 双寄存器混合索引 */
sc.w u#1, [t#2], ->t /* 双寄存器相对索引 */
sc.w u#1, [u#2], ->t /* 双寄存器相对索引 */
sc.w.aq a1, [a2], ->t /* 后序访存指令限制 */
sc.w.rl a1, [t#2], ->t /* 前序访存指令限制 */
sc.w.aqrl a1, [u#2], ->t /* 前序和后序访存指令限制 */
指令输出到块内u寄存器:
sc.w a1, [a2], ->u /* 双寄存器绝对索引 */
sc.w a1, [t#2], ->u /* 双寄存器混合索引 */
sc.w a1, [u#2], ->u /* 双寄存器混合索引 */
sc.w t#1, [a2], ->u /* 双寄存器混合索引 */
sc.w t#1, [t#2], ->u /* 双寄存器相对索引 */
sc.w t#1, [u#2], ->u /* 双寄存器相对索引 */
sc.w u#1, [a2], ->u /* 双寄存器混合索引 */
sc.w u#1, [t#2], ->u /* 双寄存器相对索引 */
sc.w u#1, [u#2], ->u /* 双寄存器相对索引 */
sc.w.aq a1, [a2], ->u /* 后序访存指令限制 */
sc.w.rl a1, [t#2], ->u /* 前序访存指令限制 */
sc.w.aqrl a1, [u#2], ->u /* 前序和后序访存指令限制 */
指令输出到全局寄存器R1-R23:
sc.w a1, [a2], ->a3 /* 双寄存器绝对索引 */
sc.w a1, [t#2], ->a3 /* 双寄存器混合索引 */
sc.w a1, [u#2], ->a3 /* 双寄存器混合索引 */
sc.w t#1, [a2], ->a3 /* 双寄存器混合索引 */
sc.w t#1, [t#2], ->a3 /* 双寄存器相对索引 */
sc.w t#1, [u#2], ->a3 /* 双寄存器相对索引 */
sc.w u#1, [a2], ->a3 /* 双寄存器混合索引 */
sc.w u#1, [t#2], ->a3 /* 双寄存器相对索引 */
sc.w u#1, [u#2], ->a3 /* 双寄存器相对索引 */
sc.w.aq a1, [a2], ->a3 /* 后序访存指令限制 */
sc.w.rl a1, [t#2], ->a3 /* 前序访存指令限制 */
sc.w.aqrl a1, [u#2], ->a3 /* 前序和后序访存指令限制 */
约束¶
- 本指令属于系统块指令集,仅允许在系统块内使用。
- 本指令要求内存访问地址必须4字节对齐,否则触发地址不对齐异常。
- LR.W与SC.W指令成对出现性能会比较好,单独出现会导致监视器阻塞。