
Phil Endecott wrote:
Guillaume Melquiond wrote:
Le samedi 08 septembre 2007 ? 23:10 -0400, Daryle Walker a ?crit :
Maybe we should add a header to our detail (and/or pending) folder encapsulating the full versions of built-in integer arithmetic operations, that most(?) processors have, but neither C nor C++ let us access. I'm talking about functions like:
std::pair<unsigned, bool> full_add( unsigned a1, unsigned a2 );
The processor has a "carry" flag whenever an integer addition overflows, but we can't access it (without assembly-language hacks). Is it really worth it? Nowadays, compilers are smart enough. They generate better code when details are not obfuscated by hand-crafted assembly code. I tested the following code with GCC:
#include <algorithm>
std::pair<unsigned, bool> full_add(unsigned a, unsigned b) { return std::make_pair(a + b, a + b < a); }
bool no_overflow(unsigned a, unsigned b) { return !full_add(a, b).second; }
Here's what I get on ARM:
_Z8full_addjj: adds r2, r1, r2 movcc r1, #0 movcs r1, #1 str r2, [r0, #0] strb r1, [r0, #4] mov pc, lr
_Z11no_overflowjj: cmn r0, r1 movcs r0, #0 movcc r0, #1 mov pc, lr
RVCT 2.2 with --arm and -O2 Gives: _Z8full_addjj PROC PUSH {r2,r3,lr} ADD r2,r1,r2 CMP r2,r1 MOVCS r1,#0 MOVCC r1,#1 STR r1,[sp,#0] STR r2,[sp,#4] STR r2,[r0,#0] LDRB r1,[sp,#0] STRB r1,[r0,#4] POP {r3,r12,pc} ENDP _Z11no_overflowjj PROC PUSH {r0-r3,lr} MOV r2,r1 MOV r1,r0 ADD r0,sp,#8 BL _Z8full_addjj LDR r0,[sp,#8] LDR r1,[sp,#0xc] STM sp,{r0,r1} LDRB r0,[sp,#4] RSBS r0,r0,#1 MOVCC r0,#0 POP {r1-r3,r12,pc} ENDP Seems just a tad worse than what you got :) What GCC did you use? Thanks, Michael Marcin