我正在构建一个PowerPC解释器,它工作得非常好。在Power架构中,条件寄存器CR0(在x86上的EFLAGS)在几乎所有指令中都会更新。它的设置方式如下:如果上次操作结果为负,则CR0的值为1;如果上次操作结果为正,则其值为2;否则为4。
我最初的天真方法是:
if (n < 0)
cr0 = 1
else if (n > 0)
cr0 = 2;
else
cr0 = 4;
我知道所有这些分支都不会是最优的,因为它们每秒运行数百万次。我在SO上看到了一些位操作,但其中没有一个似乎是合适的。例如,我发现许多示例可以根据符号或0将数字转换为-1、0或1。但如何使-1 = 1,1 = 2,0 = 4呢?我请求位操作专家的帮助......
提前感谢
更新: 首先:谢谢各位,你们太棒了。我会仔细测试你们的代码以获得速度,并且你们会成为第一个知道谁获胜的人。
@jalf:关于你的第一个建议,我实际上并没有在每个指令上计算CR0。我相反是保留了一个lastResult变量,当(如果)随后的指令要求标志时,进行比较。有三个主要动机使我回到“每次”更新:
- 在PPC上,你不像在x86上那样被迫像ADD一样更改EFLAGS,即使不需要,你有两种ADD的口味,一种是更新的。如果编译器选择使用更新的一种,这意味着它在某个点上将使用CR0,所以没有延迟的意义......
- 有一个特别痛苦的指令叫做mtcrf,它可以任意更改CR0。你甚至可以将其设置为7,并且没有算术含义...这只是破坏了保留“lastResult”变量的可能性。