summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/xtensa
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/xtensa')
-rw-r--r--libc/sysdeps/linux/xtensa/__longjmp.S17
-rw-r--r--libc/sysdeps/linux/xtensa/bits/setjmp.h9
-rw-r--r--libc/sysdeps/linux/xtensa/clone.S21
-rw-r--r--libc/sysdeps/linux/xtensa/crt1.S30
-rw-r--r--libc/sysdeps/linux/xtensa/crti.S15
-rw-r--r--libc/sysdeps/linux/xtensa/crtn.S17
-rw-r--r--libc/sysdeps/linux/xtensa/mmap.S2
-rw-r--r--libc/sysdeps/linux/xtensa/setjmp.S17
-rw-r--r--libc/sysdeps/linux/xtensa/syscall.S4
-rw-r--r--libc/sysdeps/linux/xtensa/sysdep.h45
-rw-r--r--libc/sysdeps/linux/xtensa/vfork.S23
-rw-r--r--libc/sysdeps/linux/xtensa/windowspill.S3
12 files changed, 188 insertions, 15 deletions
diff --git a/libc/sysdeps/linux/xtensa/__longjmp.S b/libc/sysdeps/linux/xtensa/__longjmp.S
index 4d55906db..acc0b4ff2 100644
--- a/libc/sysdeps/linux/xtensa/__longjmp.S
+++ b/libc/sysdeps/linux/xtensa/__longjmp.S
@@ -48,6 +48,7 @@
ENTRY (__longjmp)
+#if defined(__XTENSA_WINDOWED_ABI__)
/* Invalidate all but the current window. Reading and writing
special registers WINDOWBASE and WINDOWSTART are
privileged operations, so user processes must call the
@@ -120,6 +121,22 @@ ENTRY (__longjmp)
movnez a2, a3, a3
retw
+#elif defined(__XTENSA_CALL0_ABI__)
+ l32i a0, a2, 0
+ l32i a1, a2, 4
+ l32i a12, a2, 8
+ l32i a13, a2, 12
+ l32i a14, a2, 16
+ l32i a15, a2, 20
+
+ /* Return v ? v : 1. */
+ movi a2, 1
+ movnez a2, a3, a3
+
+ ret
+#else
+#error Unsupported Xtensa ABI
+#endif
END (__longjmp)
libc_hidden_def (__longjmp)
diff --git a/libc/sysdeps/linux/xtensa/bits/setjmp.h b/libc/sysdeps/linux/xtensa/bits/setjmp.h
index 183fa3e64..5d3e5509e 100644
--- a/libc/sysdeps/linux/xtensa/bits/setjmp.h
+++ b/libc/sysdeps/linux/xtensa/bits/setjmp.h
@@ -23,6 +23,7 @@
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
+#if defined(__XTENSA_WINDOWED_ABI__)
/* The jmp_buf structure for Xtensa holds the following (where "proc"
is the procedure that calls setjmp): 4-12 registers from the window
of proc, the 4 words from the save area at proc's $sp (in case a
@@ -30,5 +31,13 @@
proc. Everything else is saved on the stack in the normal save areas. */
typedef int __jmp_buf[17];
+#elif defined(__XTENSA_CALL0_ABI__)
+/* The jmp_buf structure for Xtensa Call0 ABI holds the return address,
+ the stack pointer and callee-saved registers (a12 - a15). */
+
+typedef int __jmp_buf[6];
+#else
+#error Unsupported Xtensa ABI
+#endif
#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/linux/xtensa/clone.S b/libc/sysdeps/linux/xtensa/clone.S
index 34d68a875..88cd6c1c3 100644
--- a/libc/sysdeps/linux/xtensa/clone.S
+++ b/libc/sysdeps/linux/xtensa/clone.S
@@ -51,7 +51,7 @@ ENTRY (__clone)
mov a8, a6 /* use a8 as a temp */
mov a6, a4
mov a4, a8
- l32i a8, a1, 16 /* child_tid */
+ l32i a8, a1, FRAMESIZE /* child_tid */
movi a2, SYS_ify(clone)
/* syscall(NR_clone,clone_flags, usp, parent_tid, child_tls, child_tid)
@@ -65,7 +65,7 @@ ENTRY (__clone)
/* fall through for parent */
.Lpseudo_end:
- retw
+ abi_ret
.Leinval:
movi a2, -EINVAL
@@ -94,17 +94,26 @@ ENTRY (__clone)
/* start child thread */
movi a0, 0 /* terminate the stack frame */
+
+#if defined(__XTENSA_WINDOWED_ABI__)
mov a6, a9 /* load up the 'arg' parameter */
callx4 a7 /* call the user's function */
/* Call _exit. Note that any return parameter from the user's
function in a6 is seen as inputs to _exit. */
-#ifdef PIC
- movi a2, _exit@PLT
+ movi a2, JUMPTARGET(_exit)
+ callx4 a2
+#elif defined(__XTENSA_CALL0_ABI__)
+ mov a2, a9 /* load up the 'arg' parameter */
+ callx0 a7 /* call the user's function */
+
+ /* Call _exit. Note that any return parameter from the user's
+ function in a2 is seen as inputs to _exit. */
+ movi a0, JUMPTARGET(_exit)
+ callx0 a0
#else
- movi a2, _exit
+#error Unsupported Xtensa ABI
#endif
- callx4 a2
PSEUDO_END (__clone)
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
diff --git a/libc/sysdeps/linux/xtensa/crti.S b/libc/sysdeps/linux/xtensa/crti.S
index a01c02c9f..ba804eb45 100644
--- a/libc/sysdeps/linux/xtensa/crti.S
+++ b/libc/sysdeps/linux/xtensa/crti.S
@@ -5,12 +5,25 @@
.global _init
.type _init, @function
_init:
+#if defined(__XTENSA_WINDOWED_ABI__)
entry sp, 48
-
+#elif defined(__XTENSA_CALL0_ABI__)
+ addi sp, sp, -16
+ s32i a0, sp, 0
+#else
+#error Unsupported Xtensa ABI
+#endif
.section .fini
.align 4
.global _fini
.type _fini, @function
_fini:
+#if defined(__XTENSA_WINDOWED_ABI__)
entry sp, 48
+#elif defined(__XTENSA_CALL0_ABI__)
+ addi sp, sp, -16
+ s32i a0, sp, 0
+#else
+#error Unsupported Xtensa ABI
+#endif
diff --git a/libc/sysdeps/linux/xtensa/crtn.S b/libc/sysdeps/linux/xtensa/crtn.S
index ab1a489c5..a3598da1a 100644
--- a/libc/sysdeps/linux/xtensa/crtn.S
+++ b/libc/sysdeps/linux/xtensa/crtn.S
@@ -1,8 +1,23 @@
/* glibc's sysdeps/xtensa/elf/initfini.c used for reference [EPILOG] */
.section .init
+#if defined(__XTENSA_WINDOWED_ABI__)
retw
-
+#elif defined(__XTENSA_CALL0_ABI__)
+ l32i a0, sp, 0
+ addi sp, sp, 16
+ ret
+#else
+#error Unsupported Xtensa ABI
+#endif
.section .fini
+#if defined(__XTENSA_WINDOWED_ABI__)
retw
+#elif defined(__XTENSA_CALL0_ABI__)
+ l32i a0, sp, 0
+ addi sp, sp, 16
+ ret
+#else
+#error Unsupported Xtensa ABI
+#endif
diff --git a/libc/sysdeps/linux/xtensa/mmap.S b/libc/sysdeps/linux/xtensa/mmap.S
index c05036aae..b4dd7c53b 100644
--- a/libc/sysdeps/linux/xtensa/mmap.S
+++ b/libc/sysdeps/linux/xtensa/mmap.S
@@ -48,7 +48,7 @@ ENTRY (__mmap)
bltz a2, SYSCALL_ERROR_LABEL
.Lpseudo_end:
- retw
+ abi_ret
PSEUDO_END (__mmap)
diff --git a/libc/sysdeps/linux/xtensa/setjmp.S b/libc/sysdeps/linux/xtensa/setjmp.S
index bf4691294..862bf6729 100644
--- a/libc/sysdeps/linux/xtensa/setjmp.S
+++ b/libc/sysdeps/linux/xtensa/setjmp.S
@@ -88,6 +88,7 @@ END (setjmp)
ENTRY (__sigsetjmp)
1:
+#if defined(__XTENSA_WINDOWED_ABI__)
/* Flush registers. */
movi a4, __window_spill
callx4 a4
@@ -146,6 +147,22 @@ ENTRY (__sigsetjmp)
callx4 a3
mov a2, a6
retw
+#elif defined(__XTENSA_CALL0_ABI__)
+ s32i a0, a2, 0
+ s32i a1, a2, 4
+ s32i a12, a2, 8
+ s32i a13, a2, 12
+ s32i a14, a2, 16
+ s32i a15, a2, 20
+ mov a12, a2
+ movi a0, __sigjmp_save
+ callx0 a0
+ l32i a0, a12, 0
+ l32i a12, a12, 8
+ ret
+#else
+#error Unsupported Xtensa ABI
+#endif
END(__sigsetjmp)
weak_extern(_setjmp)
diff --git a/libc/sysdeps/linux/xtensa/syscall.S b/libc/sysdeps/linux/xtensa/syscall.S
index 0e1a5d0be..790a8d018 100644
--- a/libc/sysdeps/linux/xtensa/syscall.S
+++ b/libc/sysdeps/linux/xtensa/syscall.S
@@ -26,7 +26,7 @@
*/
ENTRY (syscall)
- l32i a9, a1, 16 /* load extra argument from stack */
+ l32i a9, a1, FRAMESIZE/* load extra argument from stack */
mov a8, a7
mov a7, a3 /* preserve a3 in a7 */
mov a3, a4
@@ -37,5 +37,5 @@ ENTRY (syscall)
movi a4, -4095
bgeu a2, a4, SYSCALL_ERROR_LABEL
.Lpseudo_end:
- retw
+ abi_ret
PSEUDO_END (syscall)
diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h
index 4873a413d..ce2b0a0d6 100644
--- a/libc/sysdeps/linux/xtensa/sysdep.h
+++ b/libc/sysdeps/linux/xtensa/sysdep.h
@@ -28,13 +28,24 @@
#define ASM_TYPE_DIRECTIVE(name, typearg) .type name, typearg
#define ASM_SIZE_DIRECTIVE(name) .size name, . - name
+#if defined(__XTENSA_WINDOWED_ABI__)
+#define abi_entry(reg, frame_size) entry reg, frame_size
+#define abi_ret retw
+#elif defined(__XTENSA_CALL0_ABI__)
+#define abi_entry(reg, frame_size)
+#define abi_ret ret
+#else
+#error Unsupported Xtensa ABI
+#endif
+
+
#define ENTRY(name) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \
.align ALIGNARG(2); \
LITERAL_POSITION; \
C_LABEL(name) \
- entry sp, FRAMESIZE; \
+ abi_entry(sp, FRAMESIZE); \
CALL_MCOUNT
#define HIDDEN_ENTRY(name) \
@@ -44,7 +55,7 @@
.align ALIGNARG(2); \
LITERAL_POSITION; \
C_LABEL(name) \
- entry sp, FRAMESIZE; \
+ abi_entry(sp, FRAMESIZE); \
CALL_MCOUNT
#undef END
@@ -73,7 +84,13 @@
#endif
#ifndef FRAMESIZE
+#if defined(__XTENSA_WINDOWED_ABI__)
#define FRAMESIZE 16
+#elif defined(__XTENSA_CALL0_ABI__)
+#define FRAMESIZE 0
+#else
+#error Unsupported Xtensa ABI
+#endif
#endif
#define CALL_MCOUNT /* Do nothing. */
@@ -118,7 +135,7 @@
END (name)
#undef ret_NOERRNO
-#define ret_NOERRNO retw
+#define ret_NOERRNO abi_ret
/* The function has to return the error code. */
#undef PSEUDO_ERRVAL
@@ -133,7 +150,7 @@
END (name)
#undef ret_ERRVAL
-#define ret_ERRVAL retw
+#define ret_ERRVAL abi_ret
#if defined _LIBC_REENTRANT
# if defined USE___THREAD
@@ -151,6 +168,8 @@
movi a2, -1; \
j .Lpseudo_end;
# else /* !USE___THREAD */
+
+#if defined(__XTENSA_WINDOWED_ABI__)
# define SYSCALL_ERROR_HANDLER \
0: neg a2, a2; \
mov a6, a2; \
@@ -159,6 +178,24 @@
s32i a2, a6, 0; \
movi a2, -1; \
j .Lpseudo_end;
+#elif defined(__XTENSA_CALL0_ABI__)
+# define SYSCALL_ERROR_HANDLER \
+0: neg a2, a2; \
+ addi a1, a1, -16; \
+ s32i a0, a1, 0; \
+ s32i a2, a1, 4; \
+ movi a0, __errno_location@PLT; \
+ callx0 a0; \
+ l32i a0, a1, 0; \
+ l32i a3, a1, 4; \
+ addi a1, a1, 16; \
+ s32i a3, a2, 0; \
+ movi a2, -1; \
+ j .Lpseudo_end;
+#else
+#error Unsupported Xtensa ABI
+#endif
+
# endif /* !USE___THREAD */
#else /* !_LIBC_REENTRANT */
#define SYSCALL_ERROR_HANDLER \
diff --git a/libc/sysdeps/linux/xtensa/vfork.S b/libc/sysdeps/linux/xtensa/vfork.S
index 6aced0a50..b8db5c1a1 100644
--- a/libc/sysdeps/linux/xtensa/vfork.S
+++ b/libc/sysdeps/linux/xtensa/vfork.S
@@ -51,6 +51,8 @@
HIDDEN_ENTRY (__vfork)
+
+#if defined(__XTENSA_WINDOWED_ABI__)
.literal .Ljumptable, 0, .L4, .L8, .L12
mov a3, a0 # move return address out of the way
@@ -163,6 +165,27 @@ HIDDEN_ENTRY (__vfork)
PSEUDO_END (__vfork)
.Lpseudo_end:
retw
+#elif defined(__XTENSA_CALL0_ABI__)
+ SAVE_PID(a5, a8, a3, a4)
+
+ /* Use syscall 'clone'. Set new stack pointer to the same address. */
+ movi a2, SYS_ify (clone)
+ movi a3, 0
+ movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD
+ syscall
+
+ RESTORE_PID(a5, a8, a2)
+
+ movi a3, -4096
+ bgeu a2, a3, 1f
+ ret
+1:
+ PSEUDO_END (__vfork)
+.Lpseudo_end:
+ ret
+#else
+#error Unsupported Xtensa ABI
+#endif
weak_alias (__vfork, vfork)
libc_hidden_def(vfork)
diff --git a/libc/sysdeps/linux/xtensa/windowspill.S b/libc/sysdeps/linux/xtensa/windowspill.S
index 4167b2877..013025648 100644
--- a/libc/sysdeps/linux/xtensa/windowspill.S
+++ b/libc/sysdeps/linux/xtensa/windowspill.S
@@ -18,6 +18,7 @@
#include <bits/xtensa-config.h>
+#ifdef __XTENSA_WINDOWED_ABI__
.text
.align 4
.literal_position
@@ -93,3 +94,5 @@ __window_spill:
#endif
#endif
retw
+
+#endif