Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update
Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update
- Subject: Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update
- From: Jeffrey Walton <email@hidden>
- Date: Tue, 21 Jun 2011 02:03:18 -0400
Hi All,
Please forgive me if this is off topic. The are not a lot of choices
at http://lists.apple.com/mailman/listinfo. Xcode seemed the closest
to compile/assemble/link.
I've got a routine to add two unsigned ints and then check the carry
flag in the CPSR on an ARMV6 (Thumb-16 mode). Thumb-16 is enabled by
default in Xcode. To perform the add, I use the ADD instruction (ADDS
is not available in Thumb mode).
__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:
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'm getting
incorrect results. To remediate, 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
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden