ARM中按常数进行有符号半字除法
我试着用手臂上的9除以一个结果,非常类似于 除了几件事ARM中按常数进行有符号半字除法,arm,Arm,我试着用手臂上的9除以一个结果,非常类似于 除了几件事 我正在尝试除一个16位数字(半字) 签字了 我现在有以下的实现,将[R8]分成并放入[R1],但是结果是不同于C++实现的,当第十六位被设置并且工作时, LDR r7, =0x1C72 ; 2**16 *(1/9) +1 MUL r9, r8, r7 LSR r9, #16 STRH r9, [r1], #2 如果你明白原因,请告诉我。(PS我也尝试过Sulbb,但是它并
我现在有以下的实现,将[R8]分成并放入[R1],但是结果是不同于C++实现的,当第十六位被设置并且工作时,
LDR r7, =0x1C72 ; 2**16 *(1/9) +1
MUL r9, r8, r7
LSR r9, #16
STRH r9, [r1], #2
如果你明白原因,请告诉我。(PS我也尝试过Sulbb,但是它并没有比任何人好的< < P > > P。不确定是否有人关心,但是我找到了一种解决方案。在查看结果后,我注意到我的技术中的ARM划分比C++少了一个。 因此,使其工作的修改:
TST r8, #32768
SMULBB r8, r8, r7
ASR r8, #16
ADDNE r8, #1
另一个问题是,在九次加法之后,除法出现。当这些结果的结果超出半字范围时,C++仍然设法输出好的结果,因为ARM结果似乎以某种方式饱和。 我必须修改代码,将半字转换为全字,因此必须将乘法改为32位
只要您的起始值在有符号半字范围内(如果是“一个结果”而不是“一对结果”),上述代码就可以工作,sadd16有什么用??诚然,我只是略读,没有详细介绍,但将压缩半字SIMD操作与32位操作混合使用似乎是一种很好的方法,可以意外丢失符号位并使事情出错。@not像我离开[sadd16]是为了清楚地说明[r8]是一个半字,它对代码不重要。我将改变它,除非你正在加载、存储或SIMD,否则没有半字,只有32位寄存器值。是的,它对除法代码本身并不重要,但我的直觉是,它可能对你看到的错误行为至关重要,因为它意味着值传递到
mul
没有正确的符号扩展。因为问题缺少实际问题的任何细节(即输出值是什么以及它们与预期的差异如何)我们只能猜测……我确实在使用LDRSH,因为我正在尝试翻译一个C++代码,它现在使用的是输入和输出。但是,由于代码中有附加的内容,所以要划分的值可以在半字范围之外,C++处理的是精细的,而不是我的ARM代码,所以我可能只从签名半字中进行了一种翻译。加载和存储时签署完整字