mescc: Mes C Library: ARM: setjmp.c: Inline fake asm.

* lib/linux/arm-mes-gcc/_exit.c (longjmp, setjmp): Use inline fake asm.
This commit is contained in:
Jan (janneke) Nieuwenhuizen 2020-12-07 13:03:45 +01:00
parent 6703c33f96
commit b7dff2c2a4
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
2 changed files with 61 additions and 1 deletions

View file

@ -27,7 +27,7 @@
#else // ! SYSTEM_LIBC
#if __arm__
#if __GNUC__
#if __GNUC__ || __TINYC__
#warning "It is not supported to use mes' setjmp implementation together with GCC. Continuing with best-effort implementation."
typedef struct
{

View file

@ -22,6 +22,10 @@
#include <setjmp.h>
#include <stdlib.h>
#ifndef HAVE_FLOAT
#define HAVE_FLOAT 0
#endif
#if !__TINYC__
void
__attribute__ ((noinline))
@ -36,14 +40,24 @@ longjmp (jmp_buf env, int val)
"ldr r13, [r0], #4\n\t" /* stack pointer (sp) */
"ldr r14, [r0], #4\n\t" /* link register (lr) */
"ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11}\n\t"
#if HAVE_FLOAT
// TODO: If using VFP, vldmia r0!, {d8-d15}
#endif
"mov r0, r1\n\t"
:
: "r" (env), "r" (val));
// *INDENT-ON*
// not reached
}
#else //__TINYC__
#ifndef SETJMP_ASM
#define SETJMP_ASM 0
#endif
#if SETJMP_ASM
__asm__ (".global longjmp\n");
__asm__ ("longjmp:\n");
__asm__ (".int 0xe52db004\n"); //push {fp} ; (str fp, [sp, #-4]!)
@ -65,6 +79,26 @@ __asm__ (".int 0xe8b00ff0\n"); //ldm r0!, {r4, r5, r6, r7, r8, r9, sl, fp}
#endif
__asm__ (".int 0xe1a00001\n"); //mov r0, r1
__asm__ (".int 0xe12fff1e\n"); //bx lr
#else //!SETJMP_ASM
void
__attribute__ ((noinline))
longjmp (jmp_buf env, int val)
{
__asm__ (".int 0xe3510000\n"); //cmp r1, #0
__asm__ (".int 0x03a01001\n"); //moveq r1, #1
__asm__ (".int 0xe490d004\n"); //ldr sp, [r0], #4
__asm__ (".int 0xe490e004\n"); //ldr lr, [r0], #4
__asm__ (".int 0xe8b00ff0\n"); //ldm r0!, {r4, r5, r6, r7, r8, r9, sl, fp}
#if HAVE_FLOAT
// TODO: If using VFP, vldmia r0!, {d8-d15}
#endif
__asm__ (".int 0xe1a00001\n"); //mov r0, r1
__asm__ (".int 0xe12fff1e\n"); //bx lr
}
#endif //!SETJMP_ASM
#endif //__TINYC__
#if !__TINYC__
@ -78,7 +112,9 @@ setjmp (jmp_buf env)
"str r13, [r0], #4\n\t" /* stack pointer (sp) */
"str r14, [r0], #4\n\t" /* link register (lr) */
"stmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11}\n\t"
#if HAVE_FLOAT
// TODO: If using VFP, vstmia r0!, {d8-d15}
#endif
:
: "r" (env)
: "r0");
@ -86,6 +122,9 @@ setjmp (jmp_buf env)
return 0;
}
#else //__TINYC__
#if SETJMP_ASM
__asm__ (".global setjmp\n");
__asm__ ("setjmp:\n");
__asm__ (".int 0xe52db004\n"); //push {fp} ; (str fp, [sp, #-4]!)
@ -106,4 +145,25 @@ __asm__ (".int 0xe1a0b00d\n"); //mov fp, sp
__asm__ (".int 0xe3a03000\n"); //mov r3, #0
__asm__ (".int 0xe1a00003\n"); //mov r0, r3
__asm__ (".int 0xe12fff1e\n"); //bx lr
#else //!SETJMP_ASM
int
__attribute__ ((noinline))
setjmp (jmp_buf env)
{
__asm__ (".int 0xe480d004\n"); //str sp, [r0], #4
__asm__ (".int 0xe480e004\n"); //str lr, [r0], #4
//__asm__ (".int 0xe1a0300b\n"); //mov r3, fp
__asm__ (".int 0xe59bb000\n"); //ldr fp, [fp]
__asm__ (".int 0xe8a00ff0\n"); //stmia r0!, {r4, r5, r6, r7, r8, r9, sl, fp}
#if HAVE_FLOAT
// TODO: If using VFP, vstmia r0!, {d8-d15}
#endif
__asm__ (".int 0xe1a0b00d\n"); //mov fp, sp
//__asm__ (".int 0xe1a0b003\n"); //mov fp, r3
__asm__ (".int 0xe3a00000\n"); // mov r0, #0
}
#endif //!SETJMP_ASM
#endif //__TINYC__