Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update
Jeffrey Walton
noloader@gmail.com
Tue Jun 21 08:50:00 GMT 2011
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. So I moved to a
".code 32" directive for ADDS:
__asm__ volatile
(
"ldr r4, %[xa] ;" // R4 = a
"ldr r5, %[xb] ;" // R5 = b
".code 32 ;" // same as ".arm"
"adds r6, r4, r5 ;" // R6 = R4 + R5, set status
".code 16 ;" // same as ".thumb"
"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"
);
EXC_BAD_ACCESS. When I disassemble, 'bcc 1f" is changed
to a "str r5, [r0, #0]" and then a branch into the damn Application
delegate. I've also tried applying ".code 32" to the entire function
(which makes matters worse).
Any ideas how to perform an add *and* update the status flags (ADC is
no joy either)? I know I'm missing something (that much is obvious),
but I have no clue what it might be since I've verified the
instructions and their usage against the ARM manual.
jeff
More information about the Gcc-help
mailing list