This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: arm/syscalls.c (get_errno): register constraints [PATCH]


Patch checked in, thanks.

-- Jeff J.

Shaun Jackman wrote:
The following snippet from libgloss/sys/arm/syscalls.c (and
libc/sys/arm/syscalls.c), slightly modified for clarity here, does not
specify an output register in the asm statement producing bad code
when inlined and optimised by gcc.

static int get_errno (void)
{
  asm ("swi %a0" :: "i" (SWI_GetErrno));
}

static int error (int result)
{
  *__errno() = get_errno ();
  return result;
}

gcc generates the following assembler, ...

error:
	push    {r4, r5, lr}
	mov     r4, r0
	bl      __errno
	swi     96
	str     r5, [r0, #0]
	mov     r0, r4
	pop     {r4, r5, pc}

... which clobbers the return value from the __errno call.

This code has the intended effect:

static int get_errno (void)
{
  register r0 asm("r0");
  asm ("swi %a1" : "=r"(r0) : "i" (SWI_GetErrno));
  return r0;
}

error:
	push    {r4, lr}
	mov     r4, r0
	bl      __errno
	mov     r3, r0
	swi     96
	str     r0, [r3, #0]
	mov     r0, r4
	pop     {r4, pc}

The functions _swiread, _swiwrite, _swiclose, _exit (if it were ever
to return), and _kill suffer from the same problem. These functions
are currently static though, so gcc does not inline them and the
problem does not present itself. If these functions were made static
though -- I don't see why they shouldn't be -- the problem could pop
up again.

Cheers,
Shaun

2005-04-23 Shaun Jackman <sjackman@gmail.com>

* libgloss/syscalls.c (get_errno): Add an output register constraint.

--- libgloss/arm/syscalls.c-	2005-04-22 21:26:49.000000000 -0700
+++ libgloss/arm/syscalls.c	2005-04-23 10:20:49.000000000 -0700
@@ -187,7 +187,9 @@
 #ifdef ARM_RDI_MONITOR
   return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
 #else
-  asm ("swi %a0" : "r0" : "i" (SWI_GetErrno));
+  register r0 asm("r0");
+  asm ("swi %a1" : "=r"(r0) : "i" (SWI_GetErrno));
+  return r0;
 #endif
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]