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 /libc/sysdeps/linux/xtensa/crt1.S | |
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 'libc/sysdeps/linux/xtensa/crt1.S')
-rw-r--r-- | libc/sysdeps/linux/xtensa/crt1.S | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S index 025ebd070..efbe264c0 100644 --- a/libc/sysdeps/linux/xtensa/crt1.S +++ b/libc/sysdeps/linux/xtensa/crt1.S @@ -76,6 +76,7 @@ .global _start .type _start, @function _start: +#if defined(__XTENSA_WINDOWED_ABI__) /* Clear a0 to obviously mark the outermost frame. */ movi a0, 0 @@ -104,6 +105,35 @@ _start: But let the libc call main. */ movi a4, __uClibc_main callx4 a4 +#elif defined(__XTENSA_CALL0_ABI__) + /* Setup the shared library termination function. */ + mov a7, a2 + + /* Load up the user's main function. */ + movi a2, main + + /* Extract the arguments as encoded on the stack and set up + the arguments for `main': argc, argv. envp will be determined + later in __uClibc_main. */ + l32i a3, a1, 0 /* Load the argument count. */ + addi a4, a1, 4 /* Compute the argv pointer. */ + + /* Push address of our own entry points to .fini and .init. */ + movi a5, _init + movi a6, _fini + + /* Provide the highest stack address to the user code (for stacks + which grow downwards). Note that we destroy the stack version + of argc here. */ + s32i a1, a1, 0 + + /* Call the user's main function, and exit with its value. + But let the libc call main. */ + movi a0, __uClibc_main + callx0 a0 +#else +#error Unsupported Xtensa ABI +#endif /* Crash if somehow `exit' does return. */ ill |