ARM: Implement setjmp/longjmp.

* lib/arm-mes-gcc/setjmp.c (setjmp): Implement.
(longjmp): Implement.
This commit is contained in:
Danny Milosavljevic 2019-03-14 18:46:06 +01:00 committed by Jan Nieuwenhuizen
parent 21bf8a0d92
commit fbe90fb293
No known key found for this signature in database
GPG Key ID: F3C1A0D9C1D65273
1 changed files with 24 additions and 17 deletions

View File

@ -21,34 +21,41 @@
#include <setjmp.h> #include <setjmp.h>
#include <stdlib.h> #include <stdlib.h>
/* This assumes that both longjmp and setjmp either have frames, or both have no frames. */
void void
longjmp (jmp_buf env, int val) longjmp (jmp_buf env, int val)
{ {
val = val == 0 ? 1 : val;
// *INDENT-OFF* // *INDENT-OFF*
#if 1
#warning LONGJMP not implemented
#else
asm ( asm (
"mov 0x8(%ebp),%ebp\n\t" // env* "mov r0, %0\n\t"
"mov r1, %1\n\t"
"mov 0x4(%ebp),%ebx\n\t" // env->__pc "cmp r1, #0\n\t"
"mov 0x8(%ebp),%esp\n\t" // env->__sp "moveq r1, #1\n\t" /* returning 0 is not allowed, even when the user wanted to. */
"mov 0x0(%ebp),%ebp\n\t" // env->__bp "ldr r13, [r0], #4\n\t" /* stack pointer (sp) */
"jmp *%ebx\n\t" // jmp *PC "ldr r14, [r0], #4\n\t" /* link register (lr) */
); "ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11}\n\t"
#endif // TODO: If using VFP, vldmia r0!, {d8-d15}
"mov r0, r1\n\t"
:
: "r" (env), "r" (val));
// *INDENT-ON* // *INDENT-ON*
// not reached // not reached
exit (42);
} }
int int
setjmp (jmp_buf env) setjmp (jmp_buf env)
{ {
long *p = (long *) &env; // *INDENT-OFF*
env[0].__bp = p[-2]; asm (
env[0].__pc = p[-1]; "mov r0, %0\n\t"
env[0].__sp = (long) &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"
// TODO: If using VFP, vstmia r0!, {d8-d15}
:
: "r" (env)
: "r0");
// *INDENT-ON*
return 0; return 0;
} }