Re: Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update
Re: Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update
- Subject: Re: Inline Assembly: Assembling ARM/Thumb-16 ADDS or ADD with status update
- From: Jeffrey Walton <email@hidden>
- Date: Thu, 23 Jun 2011 21:26:08 -0400
On Tue, Jun 21, 2011 at 2:03 AM, Jeffrey Walton <email@hidden> wrote:
> 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....
> [SNIP]
Finished with the knob turning, and wanted to post results in case
someone else stumbles across this.
According to the Thumb-16 Quick Reference Guide [1], the ADDS
instruction should be available. This appears to be a bug in the
assembler (ie, rejecting a valid sentence of the language). Unless of
course, spurious rejections are OK and expected....
To work around AS's unwillingness to assemble certain mnemonics, one
can emit the bytes via a directive. For example, in the following code
the `.short 0x1809` is actually `ADDS R1, R1, R0`.
Jeff
int add_u32(u32t a, u32t b, u32t* r)
{
volatile int no_carry;
volatile u32t result;
__asm__ volatile
(
// Per the ARM ABI, A and B are in R0 and R1.
// R (a pointer) is in R2. R0 will be used for return.
"mov r3, #1 ;" // R3 = no_carry = TRUE
// "adds r1, r1, r0 ;" // Nope - assembler error
".short 0x1809 ;" // Same as ADDS R1, R1, R0
"bcc 1f ;"
"mov r3, #0 ;" // R3 = no_carry = FALSE
"1: ;"
"str r1, %[xr] ;" // result = R1
"str r3, %[xc] ;" // no_carry = R3
: [xr] "=m" (result), [xc] "=m" (no_carry)
:
: "r1", "r3"
);
if(r)
*r = result;
return no_carry;
}
[1] http://infocenter.arm.com/help/topic/com.arm.doc.qrc0006d/QRC0006_UAL16.pdf
_______________________________________________
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