Stash reent marker in upper bits of s1 on AMD GCN

Message ID 1573166801-36378-1-git-send-email-kcy@codesourcery.com
State Accepted
Commit d14714c690c0b11b0aa7e6d09c930a321eeac7f9
Headers show
Series
  • Stash reent marker in upper bits of s1 on AMD GCN
Related show

Commit Message

Kwok Cheung Yeung Nov. 7, 2019, 10:46 p.m.
s[0:3] contain a descriptor used to set up the initial value of the
stack, but only the lower 48 bits of s[0:1] are currently used.
The reent marker is currently set in s3, but by stashing it in the
upper 16 bits of s[0:1] instead, s3 can be freed up for other purposes.
---
 newlib/libc/machine/amdgcn/getreent.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

-- 
2.8.1

Comments

Corinna Vinschen Nov. 8, 2019, 9:35 a.m. | #1
On Nov  7 14:46, Kwok Cheung Yeung wrote:
> s[0:3] contain a descriptor used to set up the initial value of the

> stack, but only the lower 48 bits of s[0:1] are currently used.

> The reent marker is currently set in s3, but by stashing it in the

> upper 16 bits of s[0:1] instead, s3 can be freed up for other purposes.

> ---

>  newlib/libc/machine/amdgcn/getreent.c | 20 ++++++++++----------

>  1 file changed, 10 insertions(+), 10 deletions(-)

> 

> diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c

> index bc50ca0..be7d2ed 100644

> --- a/newlib/libc/machine/amdgcn/getreent.c

> +++ b/newlib/libc/machine/amdgcn/getreent.c

> @@ -34,7 +34,7 @@ __getreent (void)

>       s11 contains the offset to the base of the stack.

>       s[4:5] contains the dispatch pointer.

>       

> -     WARNING: this code will break if s[0:3] is ever used for anything!  */

> +     WARNING: this code will break if s[0:1] is ever used for anything!  */

>    const register unsigned long buffer_descriptor asm("s0");

>    unsigned long private_segment = buffer_descriptor & 0x0000ffffffffffff;

>    const register unsigned int stack_offset asm("s11");

> @@ -54,20 +54,20 @@ __getreent (void)

>    if (sp >= addr)

>      goto stackoverflow;

>  

> -  /* Place a marker in s3 to indicate that the reent data is initialized.

> -     The register is known to hold part of an unused buffer descriptor

> -     when the kernel is launched.  This may not be unused forever, but

> -     we already used s0 and s1 above, so this doesn't do extra harm.  */

> -  register int s3 asm("s3");

> -  if (s3 != 123456)

> +  /* Stash a marker in the unused upper 16 bits of s[0:1] to indicate that

> +     the reent data is initialized.  */

> +  const register unsigned int s1 asm("s1");

> +  unsigned int marker = s1 >> 16;

> +  if (marker != 12345)

>      {

> -      asm("s_mov_b32 s3, 123456");

> -      data->marker = 123456;

> +      asm("s_and_b32\ts1, s1, 0xffff");

> +      asm("s_or_b32\ts1, s1, (12345 << 16)");

> +      data->marker = 12345;

>  

>        __builtin_memset (&data->reent, 0, sizeof(struct _reent));

>        _REENT_INIT_PTR_ZEROED (&data->reent);

>      }

> -  else if (data->marker != 123456)

> +  else if (data->marker != 12345)

>      goto stackoverflow;

>  

>  

> -- 

> 2.8.1


Pushed.


Thanks,
Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
Red Hat

Patch

diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c
index bc50ca0..be7d2ed 100644
--- a/newlib/libc/machine/amdgcn/getreent.c
+++ b/newlib/libc/machine/amdgcn/getreent.c
@@ -34,7 +34,7 @@  __getreent (void)
      s11 contains the offset to the base of the stack.
      s[4:5] contains the dispatch pointer.
      
-     WARNING: this code will break if s[0:3] is ever used for anything!  */
+     WARNING: this code will break if s[0:1] is ever used for anything!  */
   const register unsigned long buffer_descriptor asm("s0");
   unsigned long private_segment = buffer_descriptor & 0x0000ffffffffffff;
   const register unsigned int stack_offset asm("s11");
@@ -54,20 +54,20 @@  __getreent (void)
   if (sp >= addr)
     goto stackoverflow;
 
-  /* Place a marker in s3 to indicate that the reent data is initialized.
-     The register is known to hold part of an unused buffer descriptor
-     when the kernel is launched.  This may not be unused forever, but
-     we already used s0 and s1 above, so this doesn't do extra harm.  */
-  register int s3 asm("s3");
-  if (s3 != 123456)
+  /* Stash a marker in the unused upper 16 bits of s[0:1] to indicate that
+     the reent data is initialized.  */
+  const register unsigned int s1 asm("s1");
+  unsigned int marker = s1 >> 16;
+  if (marker != 12345)
     {
-      asm("s_mov_b32 s3, 123456");
-      data->marker = 123456;
+      asm("s_and_b32\ts1, s1, 0xffff");
+      asm("s_or_b32\ts1, s1, (12345 << 16)");
+      data->marker = 12345;
 
       __builtin_memset (&data->reent, 0, sizeof(struct _reent));
       _REENT_INIT_PTR_ZEROED (&data->reent);
     }
-  else if (data->marker != 123456)
+  else if (data->marker != 12345)
     goto stackoverflow;