Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux