summaryrefslogtreecommitdiffstats
path: root/usr/klibc/arch/arm/setjmp.S
blob: 9f96274de6d9e750d0c8034094a614ad25c79527 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#
# arch/arm/setjmp.S
#
# setjmp/longjmp for the ARM architecture
#

#include <klibc/asmmacros.h>

#ifndef	__thumb__

#
# "Pure ARM" version
#
# The jmp_buf is assumed to contain the following, in order:
#		r4
#		r5
#		r6
#		r7
#		r8
#		r9
#		r10
#		fp
#		sp
#		lr
#

	.text
	.balign 4
	.globl setjmp
	.type setjmp, #function
setjmp:
	stmia	r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
	mov	r0, #0
	BX(lr)
	.size setjmp,.-setjmp

	.text
	.balign 4
	.globl longjmp
	.type longjmp, #function
longjmp:
	ldmia	r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
	movs	r0, r1
	moveq	r0, #1
	BX(lr)
	.size longjmp,.-longjmp

#else /* __thumb__ */

#
# Thumb version
#
# The jmp_buf is assumed to contain the following, in order:
#		lr
#		r4
#		r5
#		r6
#		r7
#		r8
#		r9
#		r10
#		fp
#		sp
#

	.text
	.balign 4
	.globl setjmp
	.type setjmp, #function
	.thumb_func
setjmp:
	mov	r2, r0
	mov	r3, lr
	stmia	r0!, {r3, r4, r5, r6, r7}
	mov	r3, r8
	mov	r4, r9
	mov	r5, r10
	mov	r6, fp
	mov	r7, sp
	stmia	r0!, {r3, r4, r5, r6, r7}
	/* Do not trash r4 .. r7 */
	ldmia	r2!, {r3, r4, r5, r6, r7}
	mov	r0, #0
	BX(lr)
	.size setjmp,.-setjmp

	.text
	.balign 4
	.globl longjmp
	.type longjmp, #function
	.thumb_func
longjmp:
	mov	r2, r0
	add	r0, #5*4
	ldmia	r0!, {r3, r4, r5, r6, r7}
	mov	r8, r3
	mov	r9, r4
	mov	r10, r5
	mov	fp, r6
	mov	sp, r7
	ldmia	r2!, {r3, r4, r5, r6, r7}
	mov	r0, r1
	bne	1f
	mov	r0, #1
1:	BX(r3)
	.size longjmp,.-longjmp

#endif /* __thumb__ */