おそらく、コンパイラが適切な ARM アセンブリに変換する移植可能な C コードが必要になるでしょう。ARM には条件付きの移動があり、これらはオーバーフローの条件付きにすることができます。アルゴリズムは次のようになります。オーバーフローが検出された場合、宛先を追加し、条件付きで unsigned(-1) に設定します。
uint16_t add16(uint16_t a, uint16_t b)
{
uint16_t c = a + b;
if (c < a) /* Can only happen due to overflow */
c = -1;
return c;
}
これは、オーバーフローを検出するために別の計算に依存するのではなく、オーバーフローを修正するという点で、他のアルゴリズムとは異なることに注意してください。
x86-64 clang 3.7 -O3 adds32 の出力:他のどの回答よりも大幅に優れています:
add edi, esi
mov eax, -1
cmovae eax, edi
ret
ARMv7: gcc 4.8 -O3 -mcpu=cortex-a15 -fverbose-asm
adds32 の出力:
adds r0, r0, r1 @ c, a, b
it cs
movcs r0, #-1 @ conditional-move
bx lr
16bit: ARM の unsigned-saturating add 命令をまだ使用していない ( UADD16
)
add r1, r1, r0 @ tmp114, a
movw r3, #65535 @ tmp116,
uxth r1, r1 @ c, tmp114
cmp r0, r1 @ a, c
ite ls @
movls r0, r1 @,, c
movhi r0, r3 @,, tmp116
bx lr @