ARM中按常数进行有符号半字除法

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,但是它并

我试着用手臂上的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,但是它并没有比任何人好的< < 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代码,所以我可能只从签名半字中进行了一种翻译。加载和存储时签署完整字