$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2007-09-11 06:43:45
Michael Marcin wrote:
> Phil Endecott wrote:
>> Guillaume Melquiond wrote:
>>> #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?
$ arm-linux-gnu-g++ --version
arm-linux-gnu-g++ (GCC) 4.1.2 20061028 (prerelease) (Debian 4.1.1-19)
It looks like your compiler is not inlining full_add inside
no_overflow, and is doing a lot of spurious argument save/restore.
There's also some strange store-as-word/load-as-byte going on for the
bool. But the core is this
> ADD r2,r1,r2
> CMP r2,r1
> MOVCS r1,#0
> MOVCC r1,#1
which compares with
>> adds r2, r1, r2
>> movcc r1, #0
>> movcs r1, #1
So either it doesn't know that the add and compare can be merged into
an adds (a peephole optimisation I would think) or it is confused by
the inversion of the carry bit.
Regards,
Phil.