From b7dff2c2a4eecc0502182b2d2b1079afa7e7629e Mon Sep 17 00:00:00 2001 From: "Jan (janneke) Nieuwenhuizen" Date: Mon, 7 Dec 2020 13:03:45 +0100 Subject: [PATCH] mescc: Mes C Library: ARM: setjmp.c: Inline fake asm. * lib/linux/arm-mes-gcc/_exit.c (longjmp, setjmp): Use inline fake asm. --- include/setjmp.h | 2 +- lib/arm-mes-gcc/setjmp.c | 60 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/include/setjmp.h b/include/setjmp.h index 2f79eeb1..5f838ff5 100644 --- a/include/setjmp.h +++ b/include/setjmp.h @@ -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 { diff --git a/lib/arm-mes-gcc/setjmp.c b/lib/arm-mes-gcc/setjmp.c index 147d9066..063c39dc 100644 --- a/lib/arm-mes-gcc/setjmp.c +++ b/lib/arm-mes-gcc/setjmp.c @@ -22,6 +22,10 @@ #include #include +#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__