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
?这永远不会命中,也永远不会被分支回。它最终只是第一次迭代的重复代码。
lea pallet,%a0
movel #7,%d0
1:
movel %a0@+,c00000
dbra %d0,1
我明白,我必须在我的代码中更加明确一些,才能让它以长块的形式编写。我在这里的主要观点是,为什么gcc似乎无法弄清楚我的意图,即我只想将此数据转储到此地址。
另一个观察结果:
我一直在玩GCC和68k代码生成,我发现它不能再为68k系列生成像样的代码,尤其是68000。
代码几乎不正确,但是没有优化(或者我应该说,它似乎是DE优化的?)。您应该首先尝试使用 -Os 而不是 -O2。即使这样,您也会在生成的代码中遇到许多无用的 insns。
我的猜测是,虽然GCC中的实际体系结构支持迅速向前发展,但68k的后端并没有得到适当的维护,只是用最少的努力保持正确。
使用方式如下: 这是有效的解决方案吗?如果删除未使用的“魔术”变量 - 我在返回字符串后有分割错误。做错了什么? $gcc--version gcc(Debian 4.4.5-8)4.4.5 $uname-Linux深度站(挤压)2.6.32-5-686#1 SMP 5月10日星期五08:33:48 UTC 2013 i686 GNU/Linux
问题内容: 我尝试从0.1循环到2.0,然后将输出打印到控制台。但是我得到了如下奇怪的输出: 源代码: 为什么它不打印确切的数字而不是像点呢?另外,使用代替还有什么区别,因为我不知道如何增加0.1? 问题答案: 这是正常的。它是浮点型固有的;像0.3这样的数字不能作为精确值存储在二进制文件中,因此您会逐渐积累错误。参考资料: Python手册,Wikipedia,Princeton CS的技术说明
问题内容: 在分析这里最近一个问题的结果时,我遇到了一个非常奇怪的现象:显然HotSpot的JIT优化的额外一层实际上减慢了我的计算机的执行速度。 这是我用于测量的代码: 该代码非常微妙,所以让我指出一些重要的方面: “普通索引”变体使用直接变量作为数组索引。HotSpot可以轻松确定整个循环的范围并消除数组边界检查; by的“ masked index”变体索引实际上等于,但是通过AND-mas
我刚开始学习Haskell,但是现在没有循环是非常令人沮丧的。我想出了如何为函数编写循环。然而,我的问题是,我想在迭代循环时输出一些结果。似乎我必须使用debug来执行这个简单的任务。 所以现在我只想举一个例子,说明如何在主结构中打印字符串10次。 换句话说,我想这样做10次: 谢谢。我觉得这对我的任务很有启发。
我知道movzx可以用于打破依赖关系,但我偶然发现Clang和GCC都使用了movzx,我真的看不出它们有什么好处。下面是我在godbolt上尝试的一个简单示例: 对于gcc12-O3: 如果我理解正确,这里的第一个movzx打破了对前一个eax值的依赖,但是第二个movzx在做什么?我不认为它可以打破任何依赖,也不应该影响结果。 有了clang14-O3,就更奇怪了: 它在movzx似乎更合理的