diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2015-09-16 01:49:49 +0300 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2015-10-08 20:31:24 +0200 |
commit | e78a0f58f23347c822c182d1c01f6eb9b9866d60 (patch) | |
tree | 723cfbcd2411d889fb4956adb7f2d11a6d766050 /ldso | |
parent | 9fae2ad9937279c9f7f40975ac14cb7b57f4a36d (diff) |
xtensa: support call0 ABI
Most changes are mechanical replacement of 'retw' instruction with
'abi_ret' macro, defined to 'retw' or 'ret' according to ABI.
Assembly code that makes calls is duplicated for call0 ABI with changed
register numbers for parameters/return value and call instruction.
'entry' instructions are replaced with 'abi_entry' macro.
More interesting changes:
- non-leaf assembly functions (e.g. _dl_tlsdesc_dynamic,
_dl_linux_resolve, SYSCALL_ERROR_HANDLER, PSEUDO) now need to preserve
registers around intermediate calls they make, use temporary stack
frame for that;
- setjmp/longjmp only need to save and restore return address, stack
pointer and callee-saved registers in the jmpbuf;
- __clone and syscall functions had hardcoded offsets to parameter
passed on stack, on call0 ABI they don't need stack frame, so the
offset is different. Replace these offsets with FRAMESIZE macro.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/xtensa/dl-startup.h | 12 | ||||
-rw-r--r-- | ldso/ldso/xtensa/dl-tlsdesc.S | 45 | ||||
-rw-r--r-- | ldso/ldso/xtensa/resolve.S | 35 |
3 files changed, 72 insertions, 20 deletions
diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h index 8fe54a3c7..aece0cd96 100644 --- a/ldso/ldso/xtensa/dl-startup.h +++ b/ldso/ldso/xtensa/dl-startup.h @@ -23,6 +23,7 @@ __asm__ ( " .align 4\n" "0: movi a3, _start+3\n" " sub a2, a0, a3\n" +#if defined(__XTENSA_WINDOWED_ABI__) " # Make sure a0 is cleared to mark the top of stack.\n" " movi a0, 0\n" " # user_entry_point = _dl_start(pointer to argument block)\n" @@ -32,6 +33,17 @@ __asm__ ( " callx4 a4\n" " # Save user_entry_point so we can jump to it.\n" " mov a3, a6\n" +#elif defined(__XTENSA_CALL0_ABI__) + " # user_entry_point = _dl_start(pointer to argument block)\n" + " movi a0, _dl_start\n" + " add a0, a0, a2\n" + " mov a2, sp\n" + " callx0 a0\n" + " # Save user_entry_point so we can jump to it.\n" + " mov a3, a2\n" +#else +#error Unsupported Xtensa ABI +#endif " l32i a7, sp, 0 # load argc\n" " # Load _dl_skip_args into a4.\n" " movi a4, _dl_skip_args\n" diff --git a/ldso/ldso/xtensa/dl-tlsdesc.S b/ldso/ldso/xtensa/dl-tlsdesc.S index 0638af439..6f417f61a 100644 --- a/ldso/ldso/xtensa/dl-tlsdesc.S +++ b/ldso/ldso/xtensa/dl-tlsdesc.S @@ -23,16 +23,11 @@ #include "tlsdesc.h" .text - .align 4 - .hidden _dl_tlsdesc_return - .global _dl_tlsdesc_return - .type _dl_tlsdesc_return, @function -_dl_tlsdesc_return: - entry a1, 16 +HIDDEN_ENTRY (_dl_tlsdesc_return) rur.threadptr a3 add a2, a2, a3 - retw - .size _dl_tlsdesc_return, .-_dl_tlsdesc_return + abi_ret +END (_dl_tlsdesc_return) #ifdef SHARED @@ -57,12 +52,7 @@ _dl_tlsdesc_return: } */ - .align 4 - .hidden _dl_tlsdesc_dynamic - .global _dl_tlsdesc_dynamic - .type _dl_tlsdesc_dynamic, @function -_dl_tlsdesc_dynamic: - entry a1, 32 +HIDDEN_ENTRY (_dl_tlsdesc_dynamic) /* dtv_t *dtv = (dtv_t *)THREAD_DTV(); */ rur.threadptr a3 @@ -83,16 +73,31 @@ _dl_tlsdesc_dynamic: + td->tlsinfo.ti_offset - __builtin_thread_pointer(); */ l32i a6, a2, TLSDESC_MODOFF sub a2, a6, a3 - retw + abi_ret /* return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer(); */ .Lslow: - mov a10, a2 - movi a8, __tls_get_addr - callx8 a8 - sub a2, a10, a3 +#if defined(__XTENSA_WINDOWED_ABI__) + mov a6, a2 + movi a4, __tls_get_addr + callx4 a4 + sub a2, a6, a3 retw - .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic +#elif defined(__XTENSA_CALL0_ABI__) + addi a1, a1, -16 + s32i a0, a1, 0 + s32i a3, a1, 4 + movi a0, __tls_get_addr + callx0 a0 + l32i a3, a1, 4 + l32i a0, a1, 0 + sub a2, a2, a3 + addi a1, a1, 16 + ret +#else +#error Unsupported Xtensa ABI +#endif +END (_dl_tlsdesc_dynamic) #endif /* SHARED */ #endif diff --git a/ldso/ldso/xtensa/resolve.S b/ldso/ldso/xtensa/resolve.S index 8061af247..12a554de7 100644 --- a/ldso/ldso/xtensa/resolve.S +++ b/ldso/ldso/xtensa/resolve.S @@ -31,6 +31,7 @@ .global _dl_linux_resolve .type _dl_linux_resolve, @function _dl_linux_resolve: +#if defined(__XTENSA_WINDOWED_ABI__) /* Call the fixup function. */ movi a8, _dl_linux_resolver callx8 a8 @@ -47,4 +48,38 @@ _dl_linux_resolve: /* Jump to the next instruction past the ENTRY. */ addi a10, a10, 3 jx a10 +#elif defined(__XTENSA_CALL0_ABI__) + /* Reserve stack space and save incoming arguments. */ + addi a1, a1, -32 + s32i a0, a1, 0 + s32i a2, a1, 8 + s32i a3, a1, 12 + s32i a4, a1, 16 + s32i a5, a1, 20 + s32i a6, a1, 24 + s32i a7, a1, 28 + + /* Move arguments for the _dl_linux_resolver to proper registers. */ + mov a2, a10 + mov a3, a11 + /* Call the fixup function. */ + movi a0, _dl_linux_resolver + callx0 a0 + mov a10, a2 + + /* Restore incoming arguments from stack and deallocate reservation. */ + l32i a0, a1, 0 + l32i a2, a1, 8 + l32i a3, a1, 12 + l32i a4, a1, 16 + l32i a5, a1, 20 + l32i a6, a1, 24 + l32i a7, a1, 28 + addi a1, a1, 32 + + /* Jump to the target function. */ + jx a10 +#else +#error Unsupported Xtensa ABI +#endif .size _dl_linux_resolve, . - _dl_linux_resolve |