有没有办法让 GCC 生成额外的 NOP 指令来将指令执行对齐到特定的块大小?
Is there anyway to make GCC generate extra NOP instruction to align instruction execution to a certain block size?
上下文:您好,我最近一直在构建一个具有 16、32 和 48 位指令长度的自定义 CPU。 CPU 获取 64 位数据块,这一切都很好,直到一条指令被夹在两个数据块之间;这使我的 CPU 获取两个影响其性能的数据块。
问题:
我想知道是否有任何方法可以通过向编译过程添加附加参数来使 gcc 将指令与 NOPS 对齐到 64 位块。或者让 GCC 将指令与 NOPS 对齐的正确方法是什么。
这就是一条指令如何被夹在两个块之间。
+---------------+
|Unaligned ins |
+---------------+
+---------------+ +---------------+
| 64Bits | | 64Bits |
+---------------+ +---------------+
我希望GCC实现的16位执行和48位执行的理想方式。每个空块代表一条16bit指令,但最后一个大空块代表一条48bit指令;如果另一个 48 位或 32 位指令跟随它,这将使后验指令不对齐,它将被夹在两个数据块之间。我希望 GCC 生成一条 NOP 指令以防止未对齐的指令执行。如最后一个空块所示。
+---+---+---+---+ +-----------+---+
| | | | | | | |
+---+---+---+---+ +-----------+---+
+---------------+ +---------------+
| 64Bits | | 64Bits |
+---------------+ +---------------+
我已经尝试过的:
我试图向 GCC 添加参数,例如 -falign-loops=## -falign-functions=## -falign-jumps= ##
但它们没有达到我想要的效果。
您能否让 GCC 在每条 48 位指令之前打印 .p2align 3,,4
,并在每条 32 位指令之前打印 .p2align 3,,2
?我不知道在哪里修改 GCC 的源代码来做到这一点,但它避免了需要实际跟踪指令大小和当前对齐。
这将填充以对齐 2^3 字节(64 位)边界,但前提是它最多需要 4 个字节(或 2 个字节)的填充。
有了这些限制,它 不会 在 6 字节指令之前填充,如果它比块边界提前 6 个字节(因此可以适合)。 4 字节指令也是如此。
更理想的是 instruction-scheduling,它知道边界并尝试 re-order 打包成块而不留下大的间隙来填充 NOP。
如果您的 GAS 不知道如何自己生成 2 或 4 字节的 NOP,那么糟糕的简单方法是使用 .p2alignw 3, 0x1234, 4
告诉它填充 [=13= 的 2 字节序列]. (其中 0x1234
是 2 字节 NOP 指令编码的占位符。)
教 GAS 发出 2 字节或 4 字节 NOP 指令而不是 2x 2 字节 NOP 指令会稍微好一点,但这只是一个肮脏的 hack,你可以在不修改 GAS 的情况下进行。
上下文:您好,我最近一直在构建一个具有 16、32 和 48 位指令长度的自定义 CPU。 CPU 获取 64 位数据块,这一切都很好,直到一条指令被夹在两个数据块之间;这使我的 CPU 获取两个影响其性能的数据块。
问题: 我想知道是否有任何方法可以通过向编译过程添加附加参数来使 gcc 将指令与 NOPS 对齐到 64 位块。或者让 GCC 将指令与 NOPS 对齐的正确方法是什么。
这就是一条指令如何被夹在两个块之间。
+---------------+
|Unaligned ins |
+---------------+
+---------------+ +---------------+
| 64Bits | | 64Bits |
+---------------+ +---------------+
我希望GCC实现的16位执行和48位执行的理想方式。每个空块代表一条16bit指令,但最后一个大空块代表一条48bit指令;如果另一个 48 位或 32 位指令跟随它,这将使后验指令不对齐,它将被夹在两个数据块之间。我希望 GCC 生成一条 NOP 指令以防止未对齐的指令执行。如最后一个空块所示。
+---+---+---+---+ +-----------+---+
| | | | | | | |
+---+---+---+---+ +-----------+---+
+---------------+ +---------------+
| 64Bits | | 64Bits |
+---------------+ +---------------+
我已经尝试过的:
我试图向 GCC 添加参数,例如 -falign-loops=## -falign-functions=## -falign-jumps= ##
但它们没有达到我想要的效果。
您能否让 GCC 在每条 48 位指令之前打印 .p2align 3,,4
,并在每条 32 位指令之前打印 .p2align 3,,2
?我不知道在哪里修改 GCC 的源代码来做到这一点,但它避免了需要实际跟踪指令大小和当前对齐。
这将填充以对齐 2^3 字节(64 位)边界,但前提是它最多需要 4 个字节(或 2 个字节)的填充。
有了这些限制,它 不会 在 6 字节指令之前填充,如果它比块边界提前 6 个字节(因此可以适合)。 4 字节指令也是如此。
更理想的是 instruction-scheduling,它知道边界并尝试 re-order 打包成块而不留下大的间隙来填充 NOP。
如果您的 GAS 不知道如何自己生成 2 或 4 字节的 NOP,那么糟糕的简单方法是使用 .p2alignw 3, 0x1234, 4
告诉它填充 [=13= 的 2 字节序列]. (其中 0x1234
是 2 字节 NOP 指令编码的占位符。)
教 GAS 发出 2 字节或 4 字节 NOP 指令而不是 2x 2 字节 NOP 指令会稍微好一点,但这只是一个肮脏的 hack,你可以在不修改 GAS 的情况下进行。