This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: [PATCH] arm: Update strcpy.c to use UAL syntax.
- From: "Ian Tessier via newlib" <newlib at sourceware dot org>
- To: "Richard Earnshaw (lists)" <Richard dot Earnshaw at arm dot com>
- Cc: newlib at sourceware dot org
- Date: Fri, 21 Jul 2017 14:13:40 -0700
- Subject: Re: [PATCH] arm: Update strcpy.c to use UAL syntax.
- Authentication-results: sourceware.org; auth=none
- References: <20170719210243.8975-1-itessier@google.com> <931f1851-2170-c1f0-2b0c-ee5a4f6e41bd@arm.com> <CAP235ST1nYzhCDsyzE7A6NXjP2hg_sy=4bjzD_3OCXQerLYmnA@mail.gmail.com>
- Reply-to: Ian Tessier <itessier at google dot com>
Oops, I did indeed leave out armv(4|5)t. Thanks for fixing it.
Interestingly, with the non-UAL version of strcpy.c the mov
instruction gets emitted as "adds r3, r0, #0", while in UAL (both
gcc/clang) it's emitted as "movs r3, r0".
On Fri, Jul 21, 2017 at 2:11 PM, Ian Tessier <itessier@google.com> wrote:
> Oops, I did indeed leave out armv(4|5)t. Thanks for fixing it.
>
> Interestingly, with the non-UAL version of strcpy.c the mov instruction gets
> emitted as "adds r3, r0, #0", while in UAL (both gcc/clang) it's emitted as
> "movs r3, r0".
>
> On Fri, Jul 21, 2017 at 3:21 AM, Richard Earnshaw (lists)
> <Richard.Earnshaw@arm.com> wrote:
>>
>> On 19/07/17 22:02, Ian Tessier via newlib wrote:
>> > With this change the arm platform can now be fully compiled with Clang.
>> >
>> > Tested by comparing the output with GCC 4.8.2, and Clang 4.0, using a
>> > variety of arches, big/little endianness, and arm/thumb mode to verify
>> > the generated assembly output matches between GCC vs Clang with UAL, and
>> > also GCC with UAL vs GCC with non-UAL, for all preprocessor code blocks.
>> >
>> > The only difference found is an extra nop at the end of the function
>> > when compiled with GCC using armv7-a/thumb/little-endian/-O2 compared to
>> > Clang. The nop is not emitted when compiled in big-endian mode.
>> > ---
>> > newlib/libc/machine/arm/strcpy.c | 13 +++++++------
>> > 1 file changed, 7 insertions(+), 6 deletions(-)
>> >
>> > diff --git a/newlib/libc/machine/arm/strcpy.c
>> > b/newlib/libc/machine/arm/strcpy.c
>> > index f1205b9c1..154451110 100644
>> > --- a/newlib/libc/machine/arm/strcpy.c
>> > +++ b/newlib/libc/machine/arm/strcpy.c
>> > @@ -42,6 +42,7 @@ char* __attribute__((naked))
>> > strcpy (char* dst, const char* src)
>> > {
>> > asm (
>> > + ".syntax unified\n\t"
>> > #if !(defined(__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED) ||
>> > \
>> > (defined (__thumb__) && !defined (__thumb2__)))
>> > #ifdef _ISA_ARM_7
>> > @@ -127,15 +128,15 @@ strcpy (char* dst, const char* src)
>> > #ifdef __ARMEB__
>> > "tst r2, #0xff00\n\t"
>> > "iteet ne\n\t"
>> > - "strneh r2, [ip], #2\n\t"
>> > + "strhne r2, [ip], #2\n\t"
>> > "lsreq r2, r2, #8\n\t"
>> > - "streqb r2, [ip]\n\t"
>> > + "strbeq r2, [ip]\n\t"
>> > "tstne r2, #0xff\n\t"
>> > #else
>> > "tst r2, #0xff\n\t"
>> > "itet ne\n\t"
>> > - "strneh r2, [ip], #2\n\t"
>> > - "streqb r2, [ip]\n\t"
>> > + "strhne r2, [ip], #2\n\t"
>> > + "strbeq r2, [ip]\n\t"
>> > "tstne r2, #0xff00\n\t"
>> > #endif
>> > "bne 5b\n\t"
>> > @@ -162,9 +163,9 @@ strcpy (char* dst, const char* src)
>> > "mov r3, r0\n\t"
>> > "1:\n\t"
>> > "ldrb r2, [r1]\n\t"
>> > - "add r1, r1, #1\n\t"
>> > + "adds r1, #1\n\t"
>> > "strb r2, [r3]\n\t"
>> > - "add r3, r3, #1\n\t"
>> > + "adds r3, #1\n\t"
>> > "cmp r2, #0\n\t"
>> > "bne 1b\n\t"
>> > "bx lr\n\t"
>> >
>>
>> This doesn't compile on ARMv4t - you've missed the "mov r3, r0"
>> instruction in the final hunk.
>>
>> Fixed thusly (pushed).
>>
>> -------------
>>
>> ARMv4t does not support mov between two low registers. Now we use
>> unified syntax mov instructions need converting to movs.
>> ---
>> newlib/libc/machine/arm/strcpy.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>>
>