From 611559a7939c29afeda6bb585fb6ba846e5a8b0e Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 22 Nov 2022 14:53:48 +0100 Subject: [PATCH] amdgcn: Use __builtin_gcn_ in libc/machine/amdgcn/getreent.c Call __builtin_gcn_get_stack_limit and __builtin_gcn_first_call_this_thread_p to reduce dependency on some register/layout assumptions by using the new GCC mainline (GCC 13) builtins, if they are available. If not, the existing code is used. --- newlib/libc/machine/amdgcn/getreent.c | 38 ++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c index be7d2edc9..ef731f649 100644 --- a/newlib/libc/machine/amdgcn/getreent.c +++ b/newlib/libc/machine/amdgcn/getreent.c @@ -29,22 +29,42 @@ typedef struct hsa_kernel_dispatch_packet_s { struct _reent * __getreent (void) { - /* Place the reent data at the top of the stack allocation. - s[0:1] contains a 48-bit private segment base address. + /* Place the reent data at the top of the stack allocation. */ + struct data { + int marker; + struct _reent reent; + } *data; + +#if defined(__has_builtin) \ + && __has_builtin(__builtin_gcn_get_stack_limit) \ + && __has_builtin(__builtin_gcn_first_call_this_thread_p) + unsigned long addr = (((unsigned long) __builtin_gcn_get_stack_limit() + - sizeof(struct data)) & ~7); + data = (struct data *)addr; + + register long sp asm("s16"); + + if (sp >= addr) + goto stackoverflow; + if (__builtin_gcn_first_call_this_thread_p()) + { + data->marker = 12345; + __builtin_memset (&data->reent, 0, sizeof(struct _reent)); + _REENT_INIT_PTR_ZEROED (&data->reent); + } + else if (data->marker != 12345) + goto stackoverflow; +#else + /* s[0:1] contains a 48-bit private segment base address. 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: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"); const register hsa_kernel_dispatch_packet_t *dispatch_ptr asm("s4"); - struct data { - int marker; - struct _reent reent; - } *data; - unsigned long stack_base = private_segment + stack_offset; unsigned long stack_end = stack_base + dispatch_ptr->private_segment_size * 64; unsigned long addr = (stack_end - sizeof(struct data)) & ~7; @@ -69,7 +89,7 @@ __getreent (void) } else if (data->marker != 12345) goto stackoverflow; - +#endif return &data->reent; -- 2.25.1