mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[liba] Add setjmp and longjmp
Change-Id: I3a57787199308900de8e7c6ce5961b2a26f6d38e
This commit is contained in:
4
Makefile
4
Makefile
@@ -113,6 +113,10 @@ endif
|
||||
@echo "CC $@"
|
||||
@$(CC) $(SFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
@echo "AS $@"
|
||||
@$(CC) $(SFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
@echo "CXX $@"
|
||||
@$(CXX) $(SFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
@@ -3,6 +3,8 @@ SFLAGS += -Iliba/include
|
||||
liba/src/external/sqlite/mem5.o: CFLAGS += -w
|
||||
|
||||
objs += $(addprefix liba/src/, \
|
||||
armv7m/setjmp.o \
|
||||
armv7m/longjmp.o \
|
||||
assert.o \
|
||||
bzero.o \
|
||||
ctype.o \
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
#ifndef LIBA_SETJMP_H
|
||||
#define LIBA_SETJMP_H
|
||||
|
||||
/* We are preseving registers:
|
||||
* - sp & lr -> 2x4 bytes
|
||||
* - General purpose registers: r4-r9, r10 = sl, r11 = fp -> 8x4 bytes
|
||||
* - Floating point registers: s16-s31 -> 8x8 bytes
|
||||
* - VFP status register: fpscr ->1x4 bytes
|
||||
* The buffer size has to include room for setjmp implementation: 4x4 bytes.
|
||||
* (See C Library ABI for the ARM architecture documentation)
|
||||
* The minimum buffer size is then (2+8+16+1+4)xsizeof(int64_t). */
|
||||
|
||||
typedef int jmp_buf[31];
|
||||
void longjmp(jmp_buf env, int val);
|
||||
int setjmp(jmp_buf env);
|
||||
|
||||
#endif
|
||||
|
||||
24
liba/src/armv7m/longjmp.s
Normal file
24
liba/src/armv7m/longjmp.s
Normal file
@@ -0,0 +1,24 @@
|
||||
.syntax unified
|
||||
|
||||
.section .text
|
||||
.align 2
|
||||
.thumb
|
||||
.global longjmp
|
||||
longjmp:
|
||||
/* Restore all the regsiters to get back in the original state (whenever the
|
||||
matching setjmp was called. */
|
||||
// General purpose registers
|
||||
ldmia r0!, { r4-r11, ip, lr }
|
||||
// Floating point registers
|
||||
vldmia r0!, { s16-s31 }
|
||||
// Special case for VFP status register
|
||||
ldr r0, [r0, #4]
|
||||
vmsr fpscr, r0
|
||||
mov sp, ip
|
||||
/* Put the return value in the integer result register, but return 1 if it is
|
||||
in fact zero. */
|
||||
movs r0, r1
|
||||
it eq
|
||||
moveq r0, #1
|
||||
bx lr
|
||||
.type longjmp, function
|
||||
20
liba/src/armv7m/setjmp.s
Normal file
20
liba/src/armv7m/setjmp.s
Normal file
@@ -0,0 +1,20 @@
|
||||
.syntax unified
|
||||
|
||||
.section .text
|
||||
.align 2
|
||||
.thumb
|
||||
.global setjmp
|
||||
setjmp:
|
||||
/* Save all the registers into the jump buffer */
|
||||
mov ip, sp
|
||||
// storing r4-r9, r10=sl, r11=fp, ip=sp, lr
|
||||
stmia r0!, { r4-r11, ip, lr}
|
||||
// storing floating point registers
|
||||
vstmia r0!, {s16-s31}
|
||||
// Special storing: fpscr
|
||||
vmrs r1, fpscr
|
||||
str r1, [r0, #4]
|
||||
/* And then return 0 */
|
||||
mov a1, #0
|
||||
bx lr
|
||||
.type setjmp, function
|
||||
Reference in New Issue
Block a user