无论如何,是否会使GCC生成额外的NOP指令以使指令执行与特定块大小对齐?

问题描述

上下文:您好,我最近正在构建具有16位,32位和48位指令长度的自定义cpucpu提取64位数据块,直到在两条数据块之间捕获指令为止,一切都很好。这使我的cpu提取了两个数据块,这会影响其性能

问题: 我想知道是否有任何方法可以通过在编译过程中添加附加参数来使gcc将带有nopS的指令对齐到64位块。或者使GCC与nopS对齐指令的正确方法是什么。

这是一条指令被夹在两个块之间的方式。

          +---------------+ 
          |Unaligned ins  |
          +---------------+
 +---------------+ +---------------+
 |     64Bits    | |     64Bits    |
 +---------------+ +---------------+

我希望GCC实现16位和48位执行的理想方法。每个空块代表一个16位指令,但最后一个大的空块代表一个48位指令。如果后面跟随另一条48位或32位指令,它将使未对齐的后一条指令陷入两个数据块之间。我希望GCC生成nop指令以防止未对齐的指令执行。如最后一个空块所示。


+---+---+---+---+ +-----------+---+
|   |   |   |   | |           |   |
+---+---+---+---+ +-----------+---+
+---------------+ +---------------+
|     64Bits    | |     64Bits    |
+---------------+ +---------------+

我已经尝试过的方法: 我尝试向GCC添加参数,例如-falign-loops=## -falign-functions=## -falign-jumps= ##,但它们并没有达到我想要的目的。

解决方法

可以在每条48位指令之前打印.p2align 3,4,在每条32位指令之前打印.p2align 3,2吗?我不知道确切地在哪里可以修改GCC的源代码来做到这一点,但是它避免了实际跟踪指令大小和当前对齐的麻烦。

这将填充以对齐2 ^ 3字节(64位)边界,但前提是它最多需要填充4字节(或2字节)。

有了这些限制,如果它在块边界之前6个字节(因此可以容纳),则它不会在6字节指令之前填充。相同于4字节指令。

更优化的方法是知道边界的指令调度,并尝试重新排序以打包成块,而不会留下很大的空白来填充NOP。


如果您的GAS本身不知道如何生成2或4字节的NOP,那么糟糕的简单方法就是使用.p2alignw 3,0x1234,4告诉它填充2字节的0x1234序列。 (其中0x1234是2字节NOP指令编码的占位符。)

教导GAS发出2字节或4字节的NOP指令,而不是2个2字节的2字节NOP,情况会稍差一些,但这只是不修改GAS即可采取的肮脏手段。