gpt4 book ai didi

c - gcc:为简单循环生成的奇怪 asm

转载 作者:行者123 更新时间:2023-12-02 02:39:25 24 4
gpt4 key购买 nike

m68k-linux-gnu-gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
CFLAGS = -Wall -Werror -ffreestanding -nostdlib -O2 -m68000 -mshort

我很困惑为什么 gcc 会为 const 数组上的简单 for 循环生成这种(看似)非最佳代码。

const unsigned int pallet[16] = {
0x0000,
0x00E0,
0x000E,
...
0x0000
};

...

volatile unsigned long * const VDP_DATA = (unsigned long *) 0x00C00000;

...

for(int i = 0; i < 16; i++) {
*VDP_DATA = pallet[i];
}

结果:

 296:   41f9 0000 037e  lea 37e <pallet+0x2>,%a0
29c: 223c 0000 039c movel #924,%d1
2a2: 4240 clrw %d0
2a4: 0280 0000 ffff andil #65535,%d0
2aa: 23c0 00c0 0000 movel %d0,c00000 <_etext+0xbffc2c>
2b0: b288 cmpl %a0,%d1
2b2: 6712 beqs 2c6 <main+0x46>
2b4: 3018 movew %a0@+,%d0
2b6: 0280 0000 ffff andil #65535,%d0
2bc: 23c0 00c0 0000 movel %d0,c00000 <_etext+0xbffc2c>
2c2: b288 cmpl %a0,%d1
2c4: 66ee bnes 2b4 <main+0x34>

我主要担心的是:

为什么无用的第一个元素在 2b0 进行比较?这永远不会命中,也永远不会分支回。它最终只是第一次迭代的重复代码。

  • 有没有更好的方法来编写这个极其简单的循环,使 gcc 不会产生这个奇怪的代码?
  • 是否有任何我可以利用的编译器标志/优化? O3 只是展开循环,我也不希望这样做,因为在这部分代码中空间比速度更受关注。
  • 也许我太谨慎了,但我只是认为这不是最难生成的代码。我期待更多的东西(可能是错误的,但你明白了):
lea pallet,%a0
movel #7,%d0
1:
movel %a0@+,c00000
dbra %d0,1

我知道我必须在我的代码中更明确一点才能让它写成长 block 。我的主要观点是 gcc 为什么似乎无法理解我的意图,即我只想将这些数据转储到这个地址。

另一个观察:

clrw %d0andil #65535,%d0movel %d0,c00000。为什么不只是 clrl 并移动?

最佳答案

我一直在研究 GCC 和 68k 代码生成,我发现它无法再为 68k 系列生成像样的代码,尤其是 68000。

代码勉强正确,但是没有优化(或者我应该说,它似乎是去优化的?)。您应该首先尝试使用 -Os 而不是 -O2。即使这样,您也会在生成的代码中遇到很多无用的 insn。

我的猜测是,虽然 GCC 中的实际架构支持迅速向前发展,但 68k 的后端没有得到适当维护,只是以最小的努力保持正确。

关于c - gcc:为简单循环生成的奇怪 asm,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60699720/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com