On Tue, Jun 21, 2011 at 4:50 AM, Andrew Haley <aph@xxxxxxxxxx> wrote: > On 21/06/11 06:21, Jeffrey Walton wrote: >> Hi All, >> >> ARMv6, -mthumb, and Apple's AS (1.38, probably modified). >> >> I've got a routine to add two unsigned ints and then check the carry >> flag in the CPSR. To perform the add, I use the Thumb-16 ADD >> instruction (ADDS is not available). >> >> __asm__ volatile >> ( >> "ldr r4, %[xa] ;" // R4 = a >> "ldr r5, %[xb] ;" // R5 = b >> "add r6, r4, r5 ;" // R6 = R4 + R5, set status >> "bcc 1f ;" // jump if carry is clear >> "mov r5, #0 ;" // set overflow >> "str r5, %[xc] ;" // write it to memory >> "1: ;" // jump label >> "str r6, %[xr] ;" // result = R6 >> : [xr] "=m" (result), [xc] "=m" (no_carry) >> : [xa] "m" (a), [xb] "m" (b) >> : "r4", "r5", "r6" >> ); >> >> According to 'ARM® Developer Suite, v1.2', Section 2.2.8, page 2-9, >> the status flags are set with ADD under Thumb-16: >> >> The conditional branch instruction is the only Thumb >> instruction that can be executed conditionally on the >> value of the ALU status flags in the CPSR. All data >> processing instructions update these flags, except >> when one or more high registers are specified as >> operands to the MOV or ADD instructions. In these >> cases the flags cannot be updated. >> >> Unfortunately, the status flags are not being updated. > > Yes they are, as you'll see when you step through. > > This is a logic failure: your asm declares that it writes no_carry, but > it only does so if carry is set. Your asm must also write to no_carry > when carry is clear. Then your asm will work. Thanks Andrew. My bad - what you did not see was the C language prologue which initialized no_carry. I believe the problem is the ADD on Thumb-16 does not set the flags (despite the ARM manual cited - perhaps it applies to Thumb-2). When I followed the ADD with a CMN, the flags were set. Off topic: I find that x86/x64 can sometimes benefit form inline assembly. But the same does not appear to be true with ARM: you should do it in C, or do it in ASM, but don't mix C with inline ASM. Jeff