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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
.file "asm-Linux-arm.S"
#include "syscall.h"
.text
/*
* void executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg)
*/
.align 2
.global executeonnewstack
.type executeonnewstack, %function
executeonnewstack:
@ args = 0, pretend = 0, frame = 12
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #12
str r0, [fp, #-16] /* store tos */
str r1, [fp, #-20] /* store tramp */
str r2, [fp, #-24] /* store arg */
ldr r0, [fp, #-24] /* get arg */
ldr r2, [fp, #-16] /* get tos */
mov sp, r2 /* set new stack */
mov lr, pc
blx r1 /* call tramp*/
/* if we return here, tramp didn't do it's job */
swi SYS_exit
ldmea fp, {fp, sp, pc}
.size executeonnewstack, .-executeonnewstack
/*
* void unlockandexit(int *key)
*
* NB: the return status may be garbaged if the stack is reused
* between the unlock and the system call, but this should
* not matter since no task is waiting for the result
*/
.align 2
.global unlockandexit
.type unlockandexit, %function
unlockandexit:
@ args = 0, pretend = 0, frame = 4
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #4
mov r1, #0
str r1, [r0]
swi SYS_exit
ldmea fp, {fp, sp, pc}
.size unlockandexit, .-unlockandexit
/*
* ulong umult(ulong m1, ulong m2, ulong *hi)
*/
.align 2
.global umult
.type umult, %function
umult:
@ args = 0, pretend = 0, frame = 12
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #12
str r0, [fp, #-16]
str r1, [fp, #-20]
str r2, [fp, #-24]
ldr r1, [fp, #-16]
ldr r2, [fp, #-20]
umull r0, r3, r1, r2
ldr r1, [fp, #-24]
str r3, [r1]
ldmea fp, {fp, sp, pc}
.size umult, .-umult
/*
* void FPsave(void*);
*/
.align 2
.global FPsave
.type FPsave, %function
FPsave:
@ args = 0, pretend = 0, frame = 4
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #4
str r0, [fp, #-16]
ldmea fp, {fp, sp, pc}
.size FPsave, .-FPsave
/*
* void FPrestore(void*);
*/
.align 2
.global FPrestore
.type FPrestore, %function
FPrestore:
@ args = 0, pretend = 0, frame = 4
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #4
str r0, [fp, #-16]
ldmea fp, {fp, sp, pc}
.size FPrestore, .-FPrestore
/*
* ulong _tas(ulong*);
*/
.align 2
.global _tas
.type _tas, %function
_tas:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
@ lr needed for prologue
mov r3, #1
mov r1, r0
swp r0, r3, [r1]
mov pc, lr
.size _tas, .-_tas
|