本节介绍如何以最佳方式配对指令,以进一步减少时序开销。
- STR Rx,[Ry,#imm] 始终为一个周期。这是因为地址生成在初始周期中执行,而数据存储操作是与下一条指令的执行同时进行。如果存储操作的目标是写入缓冲区,且写入缓冲区已满或未使能,则下一条指令将被延迟,直至该存储操作完成。如果存储操作的目标不是写入缓冲区(例如存储到代码段),并且该传输发生阻塞,则只有在本次存储操作完成之前执行另一个加载或存储操作时,才会对时序产生明显影响。
- LDR PC,[any] 始终是一个阻塞操作。这意味着加载至少需要两个周期,流水线重新加载至少需要三个周期。因此,该操作至少需要五个周期,如果在加载或获取时停止,则需要更多周期。
- 如果任何加载或存储产生的地址取决于先前数据处理操作的结果,则在寄存器组更新期间,流水线会额外暂停一个周期。这种情况下,没有转发路径。
- LDR Rx,[PC,#IMM] 可能会由于与获取单元的争用而增加一个周期。
- TBB 和 TBH 也是阻塞操作。加载至少需要两个周期,加法至少需要一个周期,流水线重新加载至少需要三个周期。这意味着如果在加载或获取时停止,则至少需要六个或更多周期。
- 如果可能,LDR [any] 会以流水线方式执行。这意味着,如果下一条指令是 LDR 或 STR,并且第一条 LDR 指令的目标未用于计算下一条指令的地址,则从下一条指令的开销中删除一个周期。因此,LDR 后面可能跟一条 STR,以便 STR 将 LDR 加载的数据写入内存。多个 LDR 指令可以一起以流水线方式执行。以下是一些经优化的示例:
- LDR R0,[R1];LDR R1,[R2]:通常总共三个周期
- LDR R0,[R1,R2];STR R0,[R3,#20]:通常总共三个周期
- LDR R0,[R1,R2];STR R1,[R3,R2]:通常总共三个周期
- LDR R0,[R1,R5];LDR R1,[R2];LDR R2,[R3,#4]:通常总共四个周期
- 在带寄存器偏移的 STR 指令执行之后,其他指令无法以流水线方式执行。STR 指令只有在紧跟在 LDR 指令之后时才能以流水线方式执行,但在该存储操作之后无法再流水线执行任何指令。因为存在写入缓冲区,即使发生阻塞,STR 通常也只需要两个周期。
- LDREX 和 STREX 可像 LDR 一样以流水线方式执行。由于 STREX 的处理方式更接近于 LDR,因此可以按照 LDR 的说明进行流水线处理。同样,LDREX 被视为与 LDR 完全相同,因此也可以流水线言方式处理。
- LDRD 和 STRD 无法与前面或后面的指令一起进行流水线处理。但是,这两个字可以一起以流水线方式处理。因此,在未发生阻塞时,该操作需要三个周期。
- LDM 和 STM 无法与前面或后面的指令一起进行流水线处理。但是,第一个元素之后的所有元素都是一起流水线执行。因此,在未发生阻塞时,三个元素的 LDM 需要 2 + 1 + 1 或 5 个周期。同样,在未发生阻塞的情况下,八个元素的存储指令需要九个周期。中断时,LDM 和 STM 指令从返回时中断的位置继续。当启动时,继续操作会为第一个元素添加一个或两个循环。
- 未对齐的字或半字加载或存储会增加罚分周期。按字节对齐的半字加载或存储操作会额外增加一个周期,以作为两个字节的操作来执行。按半字对齐的字加载或存储会额外增加一个周期,以作为两个半字的操作来执行。按字节对齐的字加载或存储会额外增加两个周期,以作为一个字节、一个半字和一个字的操作来执行。如果内存发生阻塞,这些数字还会增加。STR 或 STRH 不能由于写入缓冲区的原因而延迟处理器。