xtensa架构--指令汇总(加载指令/存储指令/跳转和调用指令/条件分支指/移动指令令/算术指令/位逻辑指令/移位指令/处理器控制指令/内存顺序指令)

目录

一 xtensa架构指令汇总

二  加载指令

1. l32i 指令

示例

2. l8i 指令

示例

3. l16i 指令

示例

4. ld 指令

示例

5 总结

三 存储指令

3.1  存储指令概述

3.2 存储指令详述

S8I (RR8): 8位存储(8位偏移)

S16I (RR8): 16位存储(8位移位偏移)

S32I (RR8): 32位存储(8位移位偏移)

四  内存顺序指令

4.1 内存顺序指令概述

4.2 内存顺序指令详述

指令格式

指令实例

注意事项

五 跳转和调用指令

5.1  跳转和调用指令概述

5.2  跳转和调用指令详述

1 CALL0:

2 CALLX0

3 J

4 JX:

5 RET:

六 条件分支指令

6.1 条件分支指令概述

条件分支指令(一)

解释

条件分支指令(二)

解释

注意事项

总结

6.2 条件指令(一)概述

1. BEQZ (Branch if Equal to Zero)

示例

2. BNEZ (Branch if Not Equal to Zero)

示例

3. BGEZ (Branch if Greater or Equal to Zero)

示例

4. BLTZ (Branch if Less Than Zero)

示例

5. BEQI (Branch if Equal to Immediate)

示例

逐行解释

6. BNEI (Branch if Not Equal to Immediate)

示例

逐行解释

7. BGEI (Branch if Greater or Equal to Immediate)

示例

逐行解释

8. BLTI (Branch if Less Than Immediate)

示例

逐行解释

6.3 条件指令(二)概述

1. BLTUI (Branch if Less than Unsigned Immediate)

示例

2. BBCI (Branch if Bit Clear Immediate)

示例

3. BBSI (Branch if Bit Set Immediate)

示例

4. BEQ (Branch if Equal)

示例

5. BNE (Branch if Not Equal)

示例

6. BGE (Branch if Greater or Equal)

示例

7. BLT (Branch if Less Than)

示例

8. BGEU (Branch if Greater or Equal Unsigned)

示例

七  移动指令

6.1 移动指令概述

移动指令

解释

示例

注意事项

6.2 指令详解

1 MOVI

指令格式

示例

逐行解释

注意事项

2 MOVEQZ

指令格式

示例

逐行解释

注意事项

3 MOVNEZ

指令格式

示例

注意事项

4 MOVTZ

指令格式

示例

注意事项

5 MOVGEZ

指令格式

示例

八  算术指令

8.1 算术指令概述

8.2 算术指令详述

1 ADD (Add two registers)

2 ADDX2 (Add register shifted by 1)

3 ADDX4 (Add register shifted by 2)

4 ADDX8 (Add register shifted by 3)

5 SUB (Subtract two registers)

6 SUBX2 (Subtract register from register shifted by 1)

7 SUBX4 (Subtract register from register shifted by 2)

8 SUBX8 (Subtract register from register shifted by 3)

9 NEG (Negate)

10 ABS (Absolute value)

11 ADDI (Add signed constant)

12 ADDMI (Add signed constant shifted by 8)

13 SALT (Set AR if Less Than)

14 SALTU (Set AR if Less Than Unsigned)

九 位逻辑指令

9.1 位逻辑指令概述

9.2 位逻辑指令详述

AND(逻辑与)

OR(逻辑或)

XOR(逻辑异或)

9.3 注意事项

十 移位指令

10.1 移位指令概述

10.2 指令详述

1. EXTUI (Extract Unsigned Immediate Field)

2. SLLI (Shift Left Logical Immediate)

3. SRRLI (Shift Right Logical Immediate)

4. SRAI (Shift Right Arithmetic Immediate)

5. SRC (Shift Right Combined)

6. SRA (Shift Right Arithmetic)

7. SLL (Shift Left Logical)

8. SRL (Shift Right Logical)

9. SSA8B (Set Shift Amount for Big Endian)

10. SSA8L (Set Shift Amount for Little Endian)

11. SSR (Set Shift Right Register)

12. SSL (Set Shift Left Register)

13. SSAI (Set Shift Amount Immediate)

10.3 注意事项:

十一 处理器控制指令

11.1 处理器控制指令概述

11.2 处理器控制指令详述

1 指令格式

2 指令使用实例

11.3 注意事项

十二 内存顺序指令

12.1 内存顺序指令概述

12.2 内存顺序指令详述

指令格式

指令实例

12.3 注意事项


一 xtensa架构指令汇总

表1汇总了Xtensa架构所有版本中包含的核心指令。

表1. 核心指令总结

指令类别指令
加载L8UI, L16SI, L16UI, L32I, L32R
存储S8I, S16I, S32I
内存顺序MEMW, EXTW
跳转,调用CALL0, CALLX0, RET J, JX
条件分支BALL, BNALL, BANY, BNONE BBC, BBCI, BBS, BBSI BEQ, BEQI, BEQZ BNE, BNEI, BNEZ BGE, BGEI, BGEU, BGEUI, BGEZ BLT, BLTI, BLTU, BLTUI, BLTZ
移动MOVNI, MOVEQZ, MOVGEZ, MOVLTZ, MOVNZE
算术ADDI, ADDMI, ADD, ADDX2, ADDX4, ADDX8, SUB, SUBX2, SUBX4, SUBX8, NEG, ABS, SALT, SALTU
位逻辑运算AND, OR, XOR
移位EXTUI, SRLI, SRAI, SLLI SRC, SLL, SRL, SRA SSL, SSR, SSAI, SSA8B, SSA8L
处理器控制RSR, WSR, XSR, RUR, WUR, ISYNC, RSYNC, ESYNC, DSYNC, FSYNC, NOP

二  加载指令

在 Xtensa 汇编中,加载指令用于从内存中读取数据并将其加载到寄存器中。这些指令通常用于读取数组元素、结构体成员等。以下是几种常见的加载指令及其用途:

1. l32i 指令

  • 用途:
    • 用于从内存中加载一个 32 位的值到寄存器中。
  • 格式:
    • l32i.n at, bt, imm
      • at: 目标寄存器,用于存储读取的值。
      • bt: 基址寄存器,用于提供内存地址的基础值。
      • imm: 立即数偏移量,用于计算最终的内存地址。

示例

假设您需要从寄存器 a2 指向的内存地址加上偏移量 4 的位置加载一个 32 位的值到寄存器 a1 中。下面是使用 l32i 指令实现这一操作的示例:

asm

深色版本

1l32i.n a1, a2, 4
  • l32i.n a1, a2, 4:
    • 从寄存器 a2 指向的内存地址加上偏移量 4 的位置加载一个 32 位的值到寄存器 a1 中。

2. l8i 指令

  • 用途:
    • 用于从内存中加载一个 8 位的值到寄存器中。
  • 格式:
    • l8i.n at, bt, imm
      • at: 目标寄存器,用于存储读取的值。
      • bt: 基址寄存器,用于提供内存地址的基础值。
      • imm: 立即数偏移量,用于计算最终的内存地址。
示例

假设您需要从寄存器 a2 指向的内存地址加载一个 8 位的值到寄存器 a1 中。下面是使用 l8i 指令实现这一操作的示例:

asm

深色版本

1l8i.n a1, a2, 0
  • l8i.n a1, a2, 0:
    • 从寄存器 a2 指向的内存地址加载一个 8 位的值到寄存器 a1 中。

3. l16i 指令

  • 用途:
    • 用于从内存中加载一个 16 位的值到寄存器中。
  • 格式:
    • l16i.n at, bt, imm
      • at: 目标寄存器,用于存储读取的值。
      • bt: 基址寄存器,用于提供内存地址的基础值。
      • imm: 立即数偏移量,用于计算最终的内存地址。
示例

假设您需要从寄存器 a2 指向的内存地址加载一个 16 位的值到寄存器 a1 中。下面是使用 l16i 指令实现这一操作的示例:

asm

深色版本

1l16i.n a1, a2, 0
  • l16i.n a1, a2, 0:
    • 从寄存器 a2 指向的内存地址加载一个 16 位的值到寄存器 a1 中。

4. ld 指令

  • 用途:
    • 用于从内存中加载一个双字(64 位)的值到两个寄存器中。
  • 格式:
    • ld at, bt, imm
      • at: 第一个目标寄存器,用于存储读取的值的高位部分。
      • bt: 第二个目标寄存器,用于存储读取的值的低位部分。
      • imm: 立即数偏移量,用于计算最终的内存地址。
示例

假设您需要从寄存器 a2 指向的内存地址加载一个 64 位的值到寄存器 a1a0 中。下面是使用 ld 指令实现这一操作的示例:

asm

深色版本

1ld a1, a0, a2, 0
  • ld a1, a0, a2, 0:
    • 从寄存器 a2 指向的内存地址加载一个 64 位的值,高位部分存储到寄存器 a1 中,低位部分存储到寄存器 a0 中。

5 总结

  • 在 Xtensa 汇编中,提供了多种加载指令用于从内存中读取不同大小的数据到寄存器中。
  • 这些指令包括 l32il8il16i 和 ld
  • 通过这些指令,您可以实现从内存中读取各种大小的数据,并将其加载到寄存器中以供进一步处理

三 存储指令

3.1  存储指令概述

存储指令 存储指令在地址形成方面类似于加载指令。存储内存错误不是同步异常;预计内存系统将使用中断来指示存储错误。

只有S32I和S32I.N可以访问InstRAM。

表1 显示了核心架构中的加载指令。

指令格式定义
S8IRR88位存储(8位偏移)
S16IRR816位存储(8位移位偏移)
S32IRR832位存储(8位移位偏移)

3.2 存储指令详述

存储指令与加载指令类似,在地址生成方面。存储内存错误不是同步异常;预期内存系统将使用中断来指示存储错误。只有S32I和S32I.N可以访问InstRAM。

以下是每种存储指令的格式、使用示例和注意事项:

  1. S8I (RR8): 8位存储(8位偏移)

    • 格式: S8I Rd, Rs, [Rt]
    • 示例:
      assembly
      1S8I a0, a1, [a2 + 4]
      这条指令将寄存器a1的低8位存储到地址a2+4处。
    • 注意事项: 偏移量必须是8位的倍数。
  2. S16I (RR8): 16位存储(8位移位偏移)

    • 格式: S16I Rd, Rs, [Rt]
    • 示例:
      assembly
      1S16I a0, a1, [a2 + 8]
      这条指令将寄存器a1的低16位存储到地址a2+8处。
    • 注意事项: 偏移量必须是8位的倍数。
  3. S32I (RR8): 32位存储(8位移位偏移)

    • 格式: S32I Rd, Rs, [Rt]
    • 示例:
      assembly
      1S32I a0, a1, [a2 + 12]
      这条指令将寄存器a1存储到地址a2+12处。
    • 注意事项: 偏移量必须是8位的倍数。

这些指令用于将数据从寄存器存储到内存中。偏移量是一个8位的移位,这意味着它可以是0到255之间的任意值。在使用这些指令时,确保偏移量满足要求

四  内存顺序指令

4.1 内存顺序指令概述

Xtensa实现可以在任何顺序执行普通加载和存储操作,只要加载返回最后(如程序执行顺序所定义)单个处理器和简单内存中每个负载地址字节的最后一个值。这种灵活性是适当的,因为大多数内存访问只需要这些语义,并且一些实现可能能够通过利用非程序顺序内存访问来显著更快地执行程序。尽管许多实现采用更严格的排序,但Xtensa ISA仅要求实现遵循一种简化版本的发布一致性模型[的内存访问顺序。

然而,有些加载和存储指令不仅用于读取和写入存储,还会影响系统其他部分(例如,另一个处理器或I/O设备)的一些副作用。必须在程序顺序中执行此类位置的加载和存储。因此,Xtensa ISA提供了一个指令,可以用来给定程序顺序中的加载和存储内存访问顺序。

MEMW指令导致所有内存和缓存访问(加载、存储、获取、释放、预取和缓存操作,但不包括指令获取)在其自身之前,在程序顺序中访问内存的所有内存和缓存访问(但不包括指令获取)之后。应在每次加载或存储到volatile变量之间至少执行一次MEMW。多处理器同步选项提供了一些额外的指令,也以更集中的方式影响内存顺序。MEMW的应用范围比这些其他指令更广(例如,在读取和写入设备寄存器时),但它也可能比同步指令影响性能更大。

EXTW指令类似于MEMW,但在程序顺序中将所有外部效果与EXTW之前的指令分开,与EXTW之后的所有外部效果。EXTW是MEMW的超集,它包含程序顺序中的内存访问。

表1显示了核心体系结构中的内存顺序指令。

表1. 内存顺序指令

指令格式定义
MEMWRRR在内存访问前排序
EXTWRRR在所有外部效果前排序

4.2 内存顺序指令详述

指令格式

  • MEMW: 这是一个三操作数指令,格式为 RRR。
  • EXTW: 同样也是一个三操作数指令,格式也为 RRR。

指令实例

  • MEMW指令的例子可能是:
    • MEMW r0, r1, r2 这条指令表示将r1寄存器的内容作为内存地址,将r2寄存器的内容写入该地址,然后确保在此之后的所有内存访问(包括其他处理器的访问)都能看到这次写入。
  • EXTW指令的例子可能是:
    • EXTW r0, r1, r2 这条指令表示将r1寄存器的内容作为内存地址,将r2寄存器的内容写入该地址,然后确保在此之后的所有外部效应(包括I/O设备交互)能看到这次写入。

注意事项

  • 使用MEMWEXTW指令时,应确保它们只应用于需要严格内存访问顺序的地方,否则可能会降低性能。
  • 对于MEMW,它主要用于涉及volatile变量的内存访问,因为它确保了在volatile变量的加载或存储操作前后,内存访问都是有序的。
  • 对于EXTW,它除了确保内存访问的顺序外,还确保所有外部效应(如I/O设备交互)也是有序的,因此更适合用于复杂的多处理器环境和I/O操作。
  • 在编写多处理器程序或涉及I/O设备交互的程序时,应该仔细考虑何时使用这些指令,以确保程序的正确性和效率。

总之,MEMWEXTW指令是Xtensa架构中用于确保内存访问顺序的重要工具,它们能帮助开发者在复杂环境中保持程序的一致性和正确性

五 跳转和调用指令

5.1  跳转和调用指令概述

跳转和调用指令 无条件分支指令J具有比条件分支更长的范围(与PC相关)。调用具有稍长的范围,因为它们针对32位对齐的地址。此外,跳转和间接调用指令提供了对案例分派、函数变量和动态链接的支持。 表3-15显示了跳转和调用指令。

指令格式定义
CALL0CALL调用子例程,与PC相关
CALLX0CALLX调用子例程,地址在寄存器中
JCALL无条件跳转,与PC相关
JXCALLX无条件跳转,地址在寄存器中
RETCALLX子例程返回——跳转到返回地址。用于从由CALL0/CALLX0调用的例程返回。

5.2  跳转和调用指令详述

以下是关于Xtensa汇编中的跳转和调用指令的一些信息:

1 CALL0:

  1. CALL0: 这是一种与PC相关的调用子例程的指令。它将当前PC值保存到返回地址寄存器,并跳转到目标地址执行子例程。格式如下:

assembly

深色版本

1CALL0 target_label

这里的target_label是子例程的标签。注意,CALL0只适用于短距离跳转,适合于在同一函数或附近函数之间跳转。

CALLX0

  1. CALLX0: 这是一种调用子例程的指令,地址在寄存器中。它将当前PC值保存到返回地址寄存器,并跳转到寄存器中的地址执行子例程。格式如下:

assembly

深色版本

1CALLX0 reg

这里的reg是要跳转的地址所在的寄存器。

J

  1. J: 这是一种无条件跳转指令,与PC相关。它跳转到目标地址继续执行。格式如下:

assembly

深色版本

1J target_label

这里的target_label是跳转的目标标签。J指令的跳转范围比CALL0更大,适合于较远距离的跳转。

JX:

  1. JX: 这是一种无条件跳转指令,地址在寄存器中。它跳转到寄存器中的地址继续执行。格式如下:

assembly

深色版本

1JX reg

这里的reg是要跳转的地址所在的寄存器。JX指令允许更大的跳转范围,适合于非常远的距离。

5 RET:

  1. RET: 这是一种子例程返回指令。它从返回地址寄存器中取出地址,跳转到那里继续执行。格式如下:

assembly

深色版本

1RET

RET指令用于从子例程返回到调用者。它通常用于CALL0CALLX0后的返回。

注意事项:

  • 所有这些指令都涉及跳转或调用另一个子例程,所以在使用它们之前,确保已经正确设置了所需的参数和保存了必要的状态。
  • 当使用CALL0CALLX0时,目标地址必须在一定范围内,否则会导致错误。JJX的范围更广,但仍然有限制。
  • CALL0CALLX0会保存当前PC值到返回地址寄存器,以便在子例程结束后能够返回。JJX不会保存返回地址,因此不能直接用来调用子例程。
  • RET指令用于从子例程返回,它期望返回地址寄存器中有正确的地址。如果没有调用CALL0CALLX0,使用RET可能会导致未定义的行为。

模板:

assembly

深色版本

1; 使用CALL0调用子例程
2call_subroutine:
3    ; 子例程代码...
4    RET
5
6main:
7    ; ...
8    CALL0 call_subroutine
9    ; 继续执行主程序...

assembly

深色版本

1; 使用CALLX0调用子例程
2call_subroutine:
3    ; 子例程代码...
4    RET
5
6main:
7    ; ...
8    MOVI a0, &call_subroutine
9    CALLX0 a0
10    ; 继续执行主程序...

assembly

深色版本

1; 使用J跳转
2label:
3    ; 目标代码...
4
5main:
6    ; ...
7    J label
8    ; 不会到达这里...

assembly

深色版本

1; 使用JX跳转
2label:
3    ; 目标代码...
4
5main:
6    ; ...
7    MOVI a0, &label
8    JX a0
9    ; 不会到达这里...

assembly

深色版本

1; 使用RET返回
2call_subroutine:
3    ; 子例程代码...
4    RET
5
6main:
7    ; ...
8    CALL0 call_subroutine
9    ; 继续执行主程序...

六 条件分支指令

6.1 条件分支指令概述

条件分支指令(一)

表 3-16 列出了 Xtensa 汇编中的条件分支指令。这些指令用于比较一个寄存器操作数与零、立即数或者另一个寄存器值,并基于比较的结果进行条件分支。相比于其他 ISA,这些分支指令可以提高代码密度和性能。所有分支都是 PC 相对的;立即字段包含了 PC 相对的偏移量,范围从负三到零,这个区域被保留给未来的使用。

指令格式定义
BEQZBR12如果等于零则分支
BNEZBR12如果不等于零则分支
BGEZBR12如果大于或等于零则分支
BLTZBR12如果小于零则分支
BEQIBR8如果等于立即数则分支
BNEIBR8如果不等于立即数则分支
BGEIBR8如果大于或等于立即数则分支
BLTIBR8如果小于立即数则分支
BGEUIBR8如果大于或等于无符号立即数则分支

解释

  • BEQZ: 如果寄存器操作数等于零,则分支。
  • BNEZ: 如果寄存器操作数不等于零,则分支。
  • BGEZ: 如果寄存器操作数大于或等于零,则分支。
  • BLTZ: 如果寄存器操作数小于零,则分支。
  • BEQI: 如果寄存器操作数等于立即数,则分支。
  • BNEI: 如果寄存器操作数不等于立即数,则分支。
  • BGEI: 如果寄存器操作数大于或等于立即数,则分支。
  • BLTI: 如果寄存器操作数小于立即数,则分支。
  • BGEUI: 如果寄存器操作数大于或等于无符号立即数,则分支。

注意:表格中的脚注表示了编码有符号和无符号立即数的详细信息可以在表 3-17 和表 3-18 找到。

条件分支指令(二)

指令格式定义
BLTUIRR8如果小于无符号立即数则分支
BBCIRR8如果位清零则分支
BBSIRR8如果位设置则分支
BEQRR8如果等于则分支
BNERR8如果不等于则分支
BGERR8如果大于或等于则分支
BLTRR8如果小于则分支
BGEURR8如果大于或等于无符号则分支
BLTURR8如果小于无符号则分支
BANYRR8如果任意掩码位设置则分支
BNONERR8如果没有掩码位设置(全清零)则分支
BALLRR8如果所有掩码位设置则分支
BNALLRR8如果并非所有掩码位设置则分支
BBCRR8如果位清零则分支
BBSRR8如果位设置则分支

注意:表格中的脚注表示了编码有符号和无符号立即数的详细信息可以在表 3-17 和表 3-18 找到。

解释
  • BLTUI: 如果寄存器操作数小于无符号立即数则分支。
  • BBCI: 如果寄存器操作数的某个位清零则分支。
  • BBSI: 如果寄存器操作数的某个位设置则分支。
  • BEQ: 如果寄存器操作数等于则分支。
  • BNE: 如果寄存器操作数不等于则分支。
  • BGE: 如果寄存器操作数大于或等于则分支。
  • BLT: 如果寄存器操作数小于则分支。
  • BGEU: 如果寄存器操作数大于或等于无符号则分支。
  • BLTU: 如果寄存器操作数小于无符号则分支。
  • BANY: 如果寄存器操作数的任意掩码位设置则分支。
  • BNONE: 如果寄存器操作数的所有掩码位未设置(全清零)则分支。
  • BALL: 如果寄存器操作数的所有掩码位设置则分支。
  • BNALL: 如果寄存器操作数的并非所有掩码位设置则分支。
  • BBC: 如果寄存器操作数的某个位清零则分支。
  • BBS: 如果寄存器操作数的某个位设置则分支。
注意事项
  • 这些指令提供了额外的条件分支选项,比如针对位测试和掩码操作。
  • 在编写汇编代码时,应根据实际需要选择合适的指令。

总结

  • 表格 续列出了 Xtensa 汇编中的条件分支指令。
  • 这些指令包括 bltuibbcibbsibeqbnebgebltbgeubltubanybnoneballbnallbbc 和 bbs
  • 这些指令提供了丰富的条件判断和流程控制功能。

6.2 条件指令(一)概述

1. BEQZ (Branch if Equal to Zero)

  • 格式:
    • beqz reg, label
      • reg: 寄存器。
      • label: 跳转的目标标签。
示例

假设您需要检查寄存器 a1 是否等于零,如果是,则跳转到标签 .zero。下面是使用 beqz 指令实现这一操作的示例:

asm

深色版本

1beqz a1, .zero
  • beqz a1, .zero:
    • 如果寄存器 a1 的值等于零,则跳转到标签 .zero

2. BNEZ (Branch if Not Equal to Zero)

  • 格式:
    • bnez reg, label
      • reg: 寄存器。
      • label: 跳转的目标标签。
示例

假设您需要检查寄存器 a1 是否不等于零,如果不是,则跳转到标签 .non_zero。下面是使用 bnez 指令实现这一操作的示例:

asm

深色版本

1bnez a1, .non_zero
  • bnez a1, .non_zero:
    • 如果寄存器 a1 的值不等于零,则跳转到标签 .non_zero

3. BGEZ (Branch if Greater or Equal to Zero)

  • 格式:
    • bgez reg, label
      • reg: 寄存器。
      • label: 跳转的目标标签。
示例

假设您需要检查寄存器 a1 是否大于或等于零,如果是,则跳转到标签 .greater_or_equal_zero。下面是使用 bgez 指令实现这一操作的示例:

asm

深色版本

1bgez a1, .greater_or_equal_zero
  • bgez a1, .greater_or_equal_zero:
    • 如果寄存器 a1 的值大于或等于零,则跳转到标签 .greater_or_equal_zero

4. BLTZ (Branch if Less Than Zero)

  • 格式:
    • bltz reg, label
      • reg: 寄存器。
      • label: 跳转的目标标签。
示例

假设您需要检查寄存器 a1 是否小于零,如果是,则跳转到标签 .less_than_zero。下面是使用 bltz 指令实现这一操作的示例:

asm

深色版本

1bltz a1, .less_than_zero
  • bltz a1, .less_than_zero:
    • 如果寄存器 a1 的值小于零,则跳转到标签 .less_than_zero

5. BEQI (Branch if Equal to Immediate)

  • 格式:
    • beqi reg, imm, label
      • reg: 寄存器。
      • imm: 立即数。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1 和立即数 10,如果它们相等,则跳转到标签 .equal_to_10。下面是使用 beqi 指令实现这一操作的示例:

asm

深色版本

1beqi a1, 10, .equal_to_10

逐行解释

  • beqi a1, 10, .equal_to_10:
    • 如果寄存器 a1 的值等于立即数 10,则跳转到标签 .equal_to_10

6. BNEI (Branch if Not Equal to Immediate)

  • 格式:
    • bnei reg, imm, label
      • reg: 寄存器。
      • imm: 立即数。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1 和立即数 10,如果它们不相等,则跳转到标签 .not_equal_to_10。下面是使用 bnei 指令实现这一操作的示例:

asm

深色版本

1bnei a1, 10, .not_equal_to_10
逐行解释
  • bnei a1, 10, .not_equal_to_10:
    • 如果寄存器 a1 的值不等于立即数 10,则跳转到标签 .not_equal_to_10

7. BGEI (Branch if Greater or Equal to Immediate)

  • 格式:
    • bgei reg, imm, label
      • reg: 寄存器。
      • imm: 立即数。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1 和立即数 10,如果 a1 大于或等于 10,则跳转到标签 .greater_or_equal_to_10。下面是使用 bgei 指令实现这一操作的示例:

asm

深色版本

1bgei a1, 10, .greater_or_equal_to_10
逐行解释
  • bgei a1, 10, .greater_or_equal_to_10:
    • 如果寄存器 a1 的值大于或等于立即数 10,则跳转到标签 .greater_or_equal_to_10

8. BLTI (Branch if Less Than Immediate)

  • 格式:
    • blti reg, imm, label
      • reg: 寄存器。
      • imm: 立即数。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1 和立即数 10,如果 a1 小于 10,则跳转到标签 .less_than_10。下面是使用 blti 指令实现这一操作的示例:

asm

深色版本

1blti a1, 10, .less_than_10
逐行解释
  • blti a1, 10, .less_than_10:
    • 如果寄存器 a1 的值小于立即数 10,则跳转到标签 `.less_than_10

6.3 条件指令(二)概述

1. BLTUI (Branch if Less than Unsigned Immediate)

  • 格式:
    • bltui at, imm, label
      • at: 寄存器。
      • imm: 立即数。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1 和立即数 10,如果 a1 小于 10,则跳转到标签 .less_than_10。下面是使用 bltui 指令实现这一操作的示例:

asm

深色版本

1bltui a1, 10, .less_than_10
  • bltui a1, 10, .less_than_10:
    • 如果寄存器 a1 的值小于立即数 10,则跳转到标签 .less_than_10

2. BBCI (Branch if Bit Clear Immediate)

  • 格式:
    • bbci at, bitnum, label
      • at: 寄存器。
      • bitnum: 位编号。
      • label: 跳转的目标标签。
示例

假设您需要检查寄存器 a1 的第 3 位是否清零,如果是,则跳转到标签 .bit_clear_3。下面是使用 bbci 指令实现这一操作的示例:

asm

深色版本

1bbci a1, 3, .bit_clear_3
  • bbci a1, 3, .bit_clear_3:
    • 如果寄存器 a1 的第 3 位清零,则跳转到标签 .bit_clear_3

3. BBSI (Branch if Bit Set Immediate)

  • 格式:
    • bbsi at, bitnum, label
      • at: 寄存器。
      • bitnum: 位编号。
      • label: 跳转的目标标签。
示例

假设您需要检查寄存器 a1 的第 4 位是否设置,如果是,则跳转到标签 .bit_set_4。下面是使用 bbsi 指令实现这一操作的示例:

asm

深色版本

1bbsi a1, 4, .bit_set_4
  • bbsi a1, 4, .bit_set_4:
    • 如果寄存器 a1 的第 4 位设置,则跳转到标签 .bit_set_4

4. BEQ (Branch if Equal)

  • 格式:
    • beq at, bt, label
      • at: 第一个寄存器。
      • bt: 第二个寄存器。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1a2 的值,如果它们相等,则跳转到标签 .equal。下面是使用 beq 指令实现这一操作的示例:

asm

深色版本

1beq a1, a2, .equal
  • beq a1, a2, .equal:
    • 如果寄存器 a1 和 a2 的值相等,则跳转到标签 .equal

5. BNE (Branch if Not Equal)

  • 格式:
    • bne at, bt, label
      • at: 第一个寄存器。
      • bt: 第二个寄存器。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1a2 的值,如果它们不相等,则跳转到标签 .not_equal。下面是使用 bne 指令实现这一操作的示例:

asm

深色版本

1bne a1, a2, .not_equal
  • bne a1, a2, .not_equal:
    • 如果寄存器 a1 和 a2 的值不相等,则跳转到标签 .not_equal

6. BGE (Branch if Greater or Equal)

  • 格式:
    • bge at, bt, label
      • at: 第一个寄存器。
      • bt: 第二个寄存器。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1a2 的值,如果 a1 大于或等于 a2,则跳转到标签 .greater_or_equal。下面是使用 bge 指令实现这一操作的示例:

asm

深色版本

1bge a1, a2, .greater_or_equal
  • bge a1, a2, .greater_or_equal:
    • 如果寄存器 a1 的值大于或等于寄存器 a2 的值,则跳转到标签 .greater_or_equal

7. BLT (Branch if Less Than)

  • 格式:
    • blt at, bt, label
      • at: 第一个寄存器。
      • bt: 第二个寄存器。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1a2 的值,如果 a1 小于 a2,则跳转到标签 .less_than。下面是使用 blt 指令实现这一操作的示例:

asm

深色版本

1blt a1, a2, .less_than
  • blt a1, a2, .less_than:
    • 如果寄存器 a1 的值小于寄存器 a2 的值,则跳转到标签 .less_than

8. BGEU (Branch if Greater or Equal Unsigned)

  • 格式:
    • bgeu at, bt, label
      • at: 第一个寄存器。
      • bt: 第二个寄存器。
      • label: 跳转的目标标签。
示例

假设您需要比较寄存器 a1a2 的无符号值,如果 a1 大于或等于 a2,则跳转到标签 .greater_or_equal_unsigned

七  移动指令

6.1 移动指令概述

移动指令

MOVI 设置寄存器为指令编码的常数。表 3-19 中列出的条件移动指令用于分支避免。

表 3-19. 移动指令

指令格式定义
MOVIRRI8加载寄存器为 12 位带符号常数
MOVEQZRRR非零条件移动
MOVNEZRRR不等于零条件移动
MOVTZRRR小于零条件移动
MOVGEZRRR大于或等于零条件移动
解释
  • MOVI 指令设置寄存器为 12 位带符号常数。
  • MOVEQZ 在非零条件下移动。
  • MOVNEZ 在不等于零条件下移动。
  • MOVTZ 在小于零条件下移动。
  • MOVGEZ 在大于或等于零条件下移动。
示例

假设您希望在寄存器 a0 的值不为零时将 1 加载到寄存器 a1,可以使用以下指令:

asm

深色版本

1moveqz a0, a1, 1
  • moveqz a0, a1, 1:
    • 如果 a0 的值不为零,则将 1 加载到 a1
注意事项
  • 条件移动指令用于避免不必要的分支。
  • 条件移动指令依赖于寄存器的值。

6.2 指令详解

1 MOVI

指令格式

MOVI 指令用于将 12 位带符号常数加载到寄存器。

asm

深色版本

1moVi rd, imm
示例

假设您希望将 -128 加载到寄存器 a0,可以使用以下指令:

asm

深色版本

1moVi a0, -128
逐行解释
  • moVi a0, -128:
    • 将 -128 加载到寄存器 a0
注意事项
  • MOVI 指令支持 12 位带符号常数。
  • 常数范围为 -2^11 至 2^11 - 1

2 MOVEQZ

指令格式

MOVEQZ 指令用于在非零条件下移动。

asm

深色版本

1moveqz rs, rt, imm
示例

假设您希望在寄存器 a0 的值不为零时将 1 加载到寄存器 a1,可以使用以下指令:

asm

深色版本

1moveqz a0, a1, 1
逐行解释
  • moveqz a0, a1, 1:
    • 如果 a0 的值不为零,则将 1 加载到 a1
注意事项
  • MOVEQZ 指令仅在非零条件下执行。

3 MOVNEZ

指令格式

MOVNEZ 指令用于在不等于零条件下移动。

asm

深色版本

1movnez rs, rt, imm
示例

假设您希望在寄存器 a0 的值不等于零时将 2 加载到寄存器 a1,可以使用以下指令:

asm

深色版本

1movnez a0, a1, 2
  • movnez a0, a1, 2:
    • 如果 a0 的值不等于零,则将 2 加载到 a1
注意事项
  • MOVNEZ 指令仅在不等于零条件下执行。

4 MOVTZ

指令格式

MOVTZ 指令用于在小于零条件下移动。

asm

深色版本

1movtz rs, rt, imm
示例

假设您希望在寄存器 a0 的值小于零时将 3 加载到寄存器 a1,可以使用以下指令:

asm

深色版本

1movtz a0, a1, 3
  • movtz a0, a1, 3:
    • 如果 a0 的值小于零,则将 3 加载到 a1
注意事项
  • MOVTZ 指令仅在小于零条件下执行。

5 MOVGEZ

指令格式

MOVGEZ 指令用于在大于或等于零条件下移动。

asm

深色版本

1movgez rs, rt, imm
示例

假设您希望在寄存器 a0 的值大于或等于零时将 4 加载到寄存器 a1,可以使用以下指令:

asm

深色版本

1movgez a0, a1, 4
  • movgez a0, a1, 4:
    • 如果 a0 的值大于或等于零,则将 4 加载到 a1

八  算术指令

8.1 算术指令概述

算术指令,包括带有少量移位的加法和减法,用于地址计算和合成常数乘法。ADDMI指令用于扩展加载和存储指令的范围。

表3.20. 算术指令

指令格式定义
ADDRRR两个寄存器相加
ADDX2RRR寄存器加上寄存器右移一位
ADDX4RRR寄存器加上寄存器右移两位
ADDX8RRR寄存器加上寄存器右移三位
SUBRRR两个寄存器相减
SUBX2RRR寄存器减去寄存器右移一位
SUBX4RRR寄存器减去寄存器右移两位
SUBX8RRR寄存器减去寄存器右移三位
NEGRRR取反
ABSRRR绝对值
ADDIRR8i加上带符号的立即数
ADDMIRR8i加上带符号的立即数右移八位
SALTRRR设置AR,如果小于则置零
SALTURRR设置AR,如果无符号小于则置零

Chapter 3. Core Architecture

Table 3.20. Arithmetic Instructions (continued)

指令格式定义
ADDIRR8i加上带符号的立即数
ADDMIRR8i加上带符号的立即数右移八位
SALTRRR如果小于则设置AR为0
SALTURRR如果无符号小于则设置AR为0

8.2 算术指令详述

1 ADD (Add two registers)

格式: ADD Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: ADD R0, R1, R2

  • 将R1和R2的内容相加并将结果存储到R0。

注意事项:

  • 注意溢出情况。

2 ADDX2 (Add register shifted by 1)

格式: ADDX2 Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: ADDX2 R0, R1, R2

  • 将R1的内容右移1位并与R2相加,结果存储到R0。

注意事项:

  • 注意溢出情况。

3 ADDX4 (Add register shifted by 2)

格式: ADDX4 Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: ADDX4 R0, R1, R2

  • 将R1的内容右移2位并与R2相加,结果存储到R0。

注意事项:

  • 注意溢出情况。

4 ADDX8 (Add register shifted by 3)

格式: ADDX8 Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: ADDX8 R0, R1, R2

  • 将R1的内容右移3位并与R2相加,结果存储到R0。

注意事项:

  • 注意溢出情况。

5 SUB (Subtract two registers)

格式: SUB Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: SUB R0, R1, R2

  • 计算R1和R2之差并将结果存储到R0。

注意事项:

  • 注意溢出情况。

6 SUBX2 (Subtract register from register shifted by 1)

格式: SUBX2 Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: SUBX2 R0, R1, R2

  • 计算R1减去R2右移1位的结果,结果存储到R0。

注意事项:

  • 注意溢出情况。

7 SUBX4 (Subtract register from register shifted by 2)

格式: SUBX4 Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: SUBX4 R0, R1, R2

  • 计算R1减去R2右移2位的结果,结果存储到R0。

注意事项:

  • 注意溢出情况。

8 SUBX8 (Subtract register from register shifted by 3)

格式: SUBX8 Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: SUBX8 R0, R1, R2

  • 计算R1减去R2右移3位的结果,结果存储到R0。

注意事项:

  • 注意溢出情况。

9 NEG (Negate)

格式: NEG Rd, Rs

  • Rd: 目标寄存器
  • Rs: 源寄存器

实例: NEG R0, R1

  • 将R1的内容取反并存储到R0。

注意事项:

  • 注意溢出情况。

10 ABS (Absolute value)

格式: ABS Rd, Rs

  • Rd: 目标寄存器
  • Rs: 源寄存器

实例: ABS R0, R1

  • 将R1的内容取绝对值并存储到R0。

注意事项:

  • 注意溢出情况。

11 ADDI (Add signed constant)

格式: ADDI Rd, Rs, #imm

  • Rd: 目标寄存器
  • Rs: 源寄存器
  • #imm: 带符号的立即数

实例: ADDI R0, R1, #10

  • 将R1的内容加上10并存储到R0。

注意事项:

  • 立即数必须在-128至+127之间。

12 ADDMI (Add signed constant shifted by 8)

格式: ADDMI Rd, Rs, #imm

  • Rd: 目标寄存器
  • Rs: 源寄存器
  • #imm: 带符号的立即数右移8位

实例: ADDMI R0, R1, #10

  • 将R1的内容加上10右移8位并存储到R0。

注意事项:

  • 立即数必须在-128至+127之间。

13 SALT (Set AR if Less Than)

格式: SALT Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: SALT R0, R1, R2

  • 如果R1小于R2,则将R0设为全零;否则不变。

注意事项:

  • 此指令仅考虑带符号比较。

14 SALTU (Set AR if Less Than Unsigned)

格式: SALTU Rd, Rs, Rt

  • Rd: 目标寄存器
  • Rs: 第一个源寄存器
  • Rt: 第二个源寄存器

实例: SALTU R0, R1, R2

  • 如果R1无符号小于R2,则将R0设为全零;否则不变

九 位逻辑指令

9.1 位逻辑指令概述

表1中的位逻辑指令提供了一个核心集,可以从中合成其他逻辑门电路。这些指令的立即形式不提供,因为立即值只能有四位。

表1. 位逻辑指令

指令格式定义
RRR位逻辑与AND
RRR位逻辑或OR
RRR位逻辑异或XOR

说明:

  • "RRR" 指的是寄存器-寄存器-寄存器(Register-Register-Register)格式,表示操作涉及三个寄存器。
  • "and" 表示逻辑与操作。
  • "or" 表示逻辑或操作。
  • "xor" 表示逻辑异或操作。
  • "AR[r] ← AR[s] and AR[t]" 表示将寄存器 AR[s] 和 AR[t] 进行逻辑与操作的结果存回寄存器 AR[r]。
  • 类似地,"AR[r] ← AR[s] or AR[t]" 和 "AR[r] ← AR[s] xor AR[t]" 分别表示逻辑或和逻辑异或操作。

9.2 位逻辑指令详述

位逻辑指令在表格中均标记为“RRR”格式,这表示它们是寄存器-寄存器-寄存器(Register-Register-Register)类型的指令。在这种格式中,指令操作涉及三个寄存器:两个源寄存器(通常标记为s和t)和一个目标寄存器(通常标记为r)。指令从两个源寄存器中读取值,执行指定的逻辑操作,然后将结果存储到目标寄存器中。

指令使用实例

  1. AND(逻辑与)

    • 格式:AND r, s, t
    • 指令使用实例:AND a1, a2, a3
      • 这将执行 a1 ← a2 and a3 操作,即将寄存器a2和a3中的值进行逻辑与操作,结果存储在寄存器a1中。
  2. OR(逻辑或)

    • 格式:OR r, s, t
    • 指令使用实例:OR b1, b2, b3
      • 这将执行 b1 ← b2 or b3 操作,即将寄存器b2和b3中的值进行逻辑或操作,结果存储在寄存器b1中。
  3. XOR(逻辑异或)

    • 格式:XOR r, s, t
    • 指令使用实例:XOR c1, c2, c3
      • 这将执行 c1 ← c2 xor c3 操作,即将寄存器c2和c3中的值进行逻辑异或操作,结果存储在寄存器c1中。

9.3 注意事项

  1. 寄存器选择:确保在指令中使用的寄存器是有效的,并且符合处理器架构的要求。

  2. 操作结果:逻辑操作的结果将存储在目标寄存器中,确保该寄存器在后续操作前不会被意外修改。

  3. 性能考虑:虽然位逻辑操作通常很快,但在设计算法时仍应考虑其对整体性能的影响。

  4. 立即值不可用:表格中特别提到,这些位逻辑指令没有立即值形式,因为立即值通常只提供有限的位数(例如四位)。如果需要与立即值进行逻辑操作,可能需要先将立即值加载到寄存器中。

  5. 依赖关系:在执行依赖于先前位逻辑操作结果的指令时,请确保前面的操作已经完成并更新了目标寄存器的值。

  6. 应用场景:位逻辑指令在处理位掩码、位字段、位标志和进行条件测试时非常有用。了解它们的应用场景可以帮助更有效地使用这些指令

十 移位指令

10.1 移位指令概述

表1中的移位指令提供了一组丰富的操作,同时避免了关键的定时路径。参阅第25页的第3.3.2节以获得更多信息。

表1. 移位指令

指令格式定义
EXTUIRRR提取无符号字段立即数(右移0...31位,AND掩码为1...16个1)
SLLIRRR左移逻辑立即数1...31位(参阅第744页的立即数编码)。
SRRLIRRR右移逻辑立即数0...15位位置
SRAIRRR右移算术立即数0...31位位置
SRCRRR右移组合(从SAR提取的通道移位)
SRARRR右移算术(从SAR移位数量)
SLLRRR左移逻辑(从SAR移位数量的通道移位)
SRLRRR右移逻辑(从SAR移位数量的通道移位)
SSA8BRRR设置大端字节对齐的移位量寄存器(SAR)
SSA8LRRR设置小端字节对齐的移位量寄存器(SAR)
SSRRRR设置右移逻辑的移位量寄存器(SAR),该指令不同于WSSRtoSAR,只使用寄存器的五位最不重要位
SSLRRR设置左移逻辑的移位量寄存器(SAR)
SSAIRRR设置移位量寄存器(SAR)的立即数

10.2 指令详述

这些指令是用于处理器中数据操作的一些基本命令,主要用于位移操作。下面我将根据指令的格式、使用实例和注意事项来逐一介绍这些指令。

1. EXTUI (Extract Unsigned Immediate Field)

格式: EXTUI Rd, Rn, #imm, #mask

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • #imm: 右移的位数(0-31)
  • #mask: AND掩码(1-16个连续的1)

实例: EXTUI R0, R1, #4, #0x0F

  • 将R1的内容右移4位后与0x0F进行AND操作,结果存储到R0。

注意事项:

  • 确保掩码的长度与右移后的位宽匹配。
  • 移位后的结果会被截断到指定的位宽。

2. SLLI (Shift Left Logical Immediate)

格式: SLLI Rd, Rn, #imm

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • #imm: 左移位数(1-31)

实例: SLLI R0, R1, #2

  • 将R1的内容左移2位,结果存储到R0。

注意事项:

  • 确保移位不会导致溢出。

3. SRRLI (Shift Right Logical Immediate)

格式: SRRLI Rd, Rn, #imm

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • #imm: 右移位数(0-15)

实例: SRRLI R0, R1, #3

  • 将R1的内容右移3位(逻辑),结果存储到R0。

注意事项:

  • 移位位数不能超过15位。

4. SRAI (Shift Right Arithmetic Immediate)

格式: SRAI Rd, Rn, #imm

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • #imm: 右移位数(0-31)

实例: SRAI R0, R1, #2

  • 将R1的内容右移2位(算术),结果存储到R0。

注意事项:

  • 算术移位会保持符号位。

5. SRC (Shift Right Combined)

格式: SRC Rd, Rn, SAR

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • SAR: 移位量寄存器

实例: SRC R0, R1, SAR

  • 将R1的内容根据SAR寄存器中的值进行右移(逻辑/算术,取决于实现),结果存储到R0。

注意事项:

  • 确保SAR寄存器的值符合预期。

6. SRA (Shift Right Arithmetic)

格式: SRA Rd, Rn, SAR

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • SAR: 移位量寄存器

实例: SRA R0, R1, SAR

  • 将R1的内容根据SAR寄存器中的值进行算术右移,结果存储到R0。

注意事项:

  • 确保SAR寄存器的值不超过最大移位位数。

7. SLL (Shift Left Logical)

格式: SLL Rd, Rn, SAR

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • SAR: 移位量寄存器

实例: SLL R0, R1, SAR

  • 将R1的内容根据SAR寄存器中的值进行逻辑左移,结果存储到R0。

注意事项:

  • 确保SAR寄存器的值不超过最大移位位数。

8. SRL (Shift Right Logical)

格式: SRL Rd, Rn, SAR

  • Rd: 目标寄存器
  • Rn: 源寄存器
  • SAR: 移位量寄存器

实例: SRL R0, R1, SAR

  • 将R1的内容根据SAR寄存器中的值进行逻辑右移,结果存储到R0。

注意事项:

  • 确保SAR寄存器的值不超过最大移位位数。

9. SSA8B (Set Shift Amount for Big Endian)

格式: SSA8B SAR, Rn

  • SAR: 移位量寄存器
  • Rn: 源寄存器

实例: SSA8B SAR, R1

  • 将R1的内容的大端字节对齐值写入SAR寄存器。

注意事项:

  • 适用于大端模式。

10. SSA8L (Set Shift Amount for Little Endian)

格式: SSA8L SAR, Rn

  • SAR: 移位量寄存器
  • Rn: 源寄存器

实例: SSA8L SAR, R1

  • 将R1的内容的小端字节对齐值写入SAR寄存器。

注意事项:

  • 适用于小端模式。

11. SSR (Set Shift Right Register)

格式: SSR SAR, Rn

  • SAR: 移位量寄存器
  • Rn: 源寄存器

实例: SSR SAR, R1

  • 将R1的低五位写入SAR寄存器作为移位量。

注意事项:

  • 只使用源寄存器的最低五位。

12. SSL (Set Shift Left Register)

格式: SSL SAR, Rn

  • SAR: 移位量寄存器
  • Rn: 源寄存器

实例: SSL SAR, R1

  • 将R1的内容写入SAR寄存器作为移位量。

注意事项:

  • 通常用于设置左移的移位量。

13. SSAI (Set Shift Amount Immediate)

格式: SSAI SAR, #imm

  • SAR: 移位量寄存器
  • #imm: 立即数移位量

实例: SSAI SAR, #4

  • 将4写入SAR寄存器作为移位量。

10.3 注意事项:

  • 确保立即数符合指令要求的范围

十一 处理器控制指令

11.1 处理器控制指令概述

表1. 处理器控制指令

指令格式定义
RSRRSR读取特殊寄存器
WSRRSR写入特殊寄存器
RSR-交换特殊寄存器(此行为合并项,应为XSR,且在T1030及早期处理器中不存在)
XSR(组合的RSR和wSR)不存在于T1030及早期处理器中
RRR-指令获取同步:等待所有之前获取的、影响指令获取的加载、存储、缓存和ISYNC特殊寄存器写入指令完成后再获取下一条指令。
RRRRSYNC指令寄存器同步:等待所有之前获取的wSR和XSR指令完成后再解释下一条指令的寄存器字段。此操作也是ISYNC的一部分。
RRRESYNC寄存器值同步:等待所有之前获取的wSR和xSR指令完成后再在下一条指令中使用任何寄存器值。此操作也是ISYNC、RSYNC和ESYNC的一部分。
RRRDSYNC加载/存储同步:等待所有之前获取的wSR和xSR指令完成后再解释下一条加载或存储指令的虚拟地址。此操作也是ISYNC、RSYNC和ESYNC的一部分。
FSYNCRRR获取同步:实现定义。
NOPRRR无操作

11.2 处理器控制指令详述

1 指令格式

对于处理器控制指令,指令格式通常取决于具体的处理器架构和指令集。不过,我们可以根据常见的RISC(精简指令集计算机)架构风格来概括这些指令的格式。在Xtensa处理器中,指令格式可能包括操作码(opcode)字段,以及一个或多个寄存器字段(用于指定源操作数、目标操作数或特殊寄存器)。

  1. RSR(读取特殊寄存器)
    • 格式:RSR <目标寄存器>, <特殊寄存器号>
    • 示例:RSR a2, SCOMPARE1(假设SCOMPARE1是特殊寄存器号,且a2是目标寄存器)
  2. WSR(写入特殊寄存器)
    • 格式:WSR <源寄存器>, <特殊寄存器号>
    • 示例:WSR a1, SCOMPARE1(假设a1包含要写入的值,SCOMPARE1是特殊寄存器号)
  3. XSR(交换特殊寄存器与AR[t])
    • 格式:XSR <源寄存器>, <特殊寄存器号>, <AR[t]寄存器号>(假设格式,具体取决于实现)
    • 示例:无直接示例,因为此指令在T1030及早期处理器中不存在,且格式可能因实现而异。
  4. ISYNC、RSYNC、ESYNC、DSYNC
    • 格式:指令名(这些指令通常不直接操作寄存器,因此没有标准的“寄存器, 寄存器”格式)
    • 示例:ISYNCRSYNCESYNCDSYNC(直接作为指令使用)
  5. NOP(无操作)
    • 格式:NOP(无操作数)
    • 示例:NOP

2 指令使用实例

  1. 读取特殊寄存器
    • 示例:读取性能计数器到寄存器a2

      assembly

      RSR a2, PERFCOUNT1
  2. 写入特殊寄存器
    • 示例:将寄存器a1的值写入到中断使能寄存器

      assembly

      WSR a1, INTENABLE
  3. 同步指令
    • 示例:在执行了一系列写入特殊寄存器的操作后,确保所有写入完成

      assembly

      WSR a1, SCOMPARE1
      WSR a2, SAR
      ESYNC

11.3 注意事项

  1. 寄存器号:确保在RSR、WSR和XSR指令中使用的特殊寄存器号是有效的,并且符合处理器文档中的规定。

  2. 同步需求:在写入特殊寄存器后,如果需要确保这些写入对后续指令可见,应使用适当的同步指令(如ESYNC)。

  3. 指令顺序:注意指令的执行顺序,特别是在需要同步操作的场景中。

  4. 性能影响:某些同步指令(如ISYNC、RSYNC、ESYNC、DSYNC)可能会对性能产生影响,因为它们可能导致处理器暂停执行以等待内部操作的完成。

  5. 处理器版本:注意不同版本的Xtensa处理器可能支持不同的指令集和功能。例如,XSR指令在T1030及早期处理器中不存在。

  6. 上下文保存与恢复:在中断处理或任务切换时,可能需要使用RSR和WSR指令来保存和恢复特殊寄存器的值。

  7. 权限问题:在某些情况下,写入特殊寄存器可能需要特定的权限或处于特定的处理器模式(如特权模式)

十二 内存顺序指令

12.1 内存顺序指令概述

Xtensa实现可以在任何顺序执行普通加载和存储操作,只要加载返回最后(如程序执行顺序所定义)单个处理器和简单内存中每个负载地址字节的最后一个值。这种灵活性是适当的,因为大多数内存访问只需要这些语义,并且一些实现可能能够通过利用非程序顺序内存访问来显著更快地执行程序。尽管许多实现采用更严格的排序,但Xtensa ISA仅要求实现遵循一种简化版本的发布一致性模型[的内存访问顺序。

然而,有些加载和存储指令不仅用于读取和写入存储,还会影响系统其他部分(例如,另一个处理器或I/O设备)的一些副作用。必须在程序顺序中执行此类位置的加载和存储。因此,Xtensa ISA提供了一个指令,可以用来给定程序顺序中的加载和存储内存访问顺序。

MEMW指令导致所有内存和缓存访问(加载、存储、获取、释放、预取和缓存操作,但不包括指令获取)在其自身之前,在程序顺序中访问内存的所有内存和缓存访问(但不包括指令获取)之后。应在每次加载或存储到volatile变量之间至少执行一次MEMW。多处理器同步选项提供了一些额外的指令,也以更集中的方式影响内存顺序。MEMW的应用范围比这些其他指令更广(例如,在读取和写入设备寄存器时),但它也可能比同步指令影响性能更大。

EXTW指令类似于MEMW,但在程序顺序中将所有外部效果与EXTW之前的指令分开,与EXTW之后的所有外部效果。EXTW是MEMW的超集,它包含程序顺序中的内存访问。

表1显示了核心体系结构中的内存顺序指令。

表1. 内存顺序指令

指令格式定义
MEMWRRR在内存访问前排序
EXTWRRR在所有外部效果前排序

12.2 内存顺序指令详述

指令格式

  • MEMW: 这是一个三操作数指令,格式为 RRR。
  • EXTW: 同样也是一个三操作数指令,格式也为 RRR。

指令实例

  • MEMW指令的例子可能是:
    • MEMW r0, r1, r2 这条指令表示将r1寄存器的内容作为内存地址,将r2寄存器的内容写入该地址,然后确保在此之后的所有内存访问(包括其他处理器的访问)都能看到这次写入。
  • EXTW指令的例子可能是:
    • EXTW r0, r1, r2 这条指令表示将r1寄存器的内容作为内存地址,将r2寄存器的内容写入该地址,然后确保在此之后的所有外部效应(包括I/O设备交互)能看到这次写入。

12.3 注意事项

  • 使用MEMWEXTW指令时,应确保它们只应用于需要严格内存访问顺序的地方,否则可能会降低性能。
  • 对于MEMW,它主要用于涉及volatile变量的内存访问,因为它确保了在volatile变量的加载或存储操作前后,内存访问都是有序的。
  • 对于EXTW,它除了确保内存访问的顺序外,还确保所有外部效应(如I/O设备交互)也是有序的,因此更适合用于复杂的多处理器环境和I/O操作。
  • 在编写多处理器程序或涉及I/O设备交互的程序时,应该仔细考虑何时使用这些指令,以确保程序的正确性和效率。

总之,MEMWEXTW指令是Xtensa架构中用于确保内存访问顺序的重要工具,它们能帮助开发者在复杂环境中保持程序的一致性和正确性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值