mirror of
https://github.com/google/pebble.git
synced 2025-05-01 15:51:40 -04:00
77 lines
2.2 KiB
C
77 lines
2.2 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
///////////////////////////////////////
|
|
// Implements:
|
|
// int setjmp(jmp_buf env);
|
|
// void longjmp(jmp_buf buf, int value);
|
|
///////////////////////////////////////
|
|
// Notes:
|
|
// This is entirely non-portable. It will need to be rewritten if we stop using ARM.
|
|
// Unfortunately, there is no portable way to define these.
|
|
// This means unit tests can't use our setjmp/longjmp either.
|
|
|
|
#include <include/setjmp.h>
|
|
|
|
#if __ARM_ARCH_ISA_THUMB >= 2
|
|
// Valid for anything with THUMB2
|
|
|
|
int __attribute__((__naked__)) setjmp(jmp_buf env) {
|
|
__asm volatile (
|
|
// move SP to a register we can store from and don't need to save
|
|
"mov %ip, %sp\n"
|
|
// store all the registers
|
|
"stmia %r0!, {%r4-%r9, %sl, %fp, %ip, %lr}\n"
|
|
// using real FPU
|
|
#if defined(__VFP_FP__) && !defined(__SOFTFP__)
|
|
// store FP registers
|
|
"vstmia %r0!, {%s16-%s31}\n"
|
|
// store FPSCR
|
|
"vmrs %r1, fpscr\n"
|
|
"str %r1, [%r0], #4\n"
|
|
#endif
|
|
// return 0
|
|
"mov %r0, #0\n"
|
|
"bx lr\n"
|
|
);
|
|
}
|
|
|
|
void __attribute__((__naked__)) longjmp(jmp_buf buf, int value) {
|
|
__asm volatile (
|
|
// load all the registers
|
|
"ldmia %r0!, {%r4-%r9, %sl, %fp, %ip, %lr}\n"
|
|
// load SP from a register we could load to and don't need to restore
|
|
"mov %sp, %ip\n"
|
|
// using real FPU
|
|
#if defined(__VFP_FP__) && !defined(__SOFTFP__)
|
|
// load FP registers
|
|
"vldmia %r0!, {%s16-%s31}\n"
|
|
// load FPSCR
|
|
"ldr %r2, [%r0], #4\n"
|
|
"vmsr fpscr, %r2\n"
|
|
#endif
|
|
// return value
|
|
"movs %r0, %r1\n"
|
|
// unless it's 0, in which case, return 1.
|
|
"it eq\n"
|
|
"moveq %r0, #1\n"
|
|
"bx lr\n"
|
|
);
|
|
}
|
|
#else
|
|
// Undefined implementations, don't implement!
|
|
// That way we get a link-time error.
|
|
#endif
|