]> Cypherpunks repositories - gostls13.git/blob
4961045
[gostls13.git] /
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "arm/asm.h"
6
7 // using frame size $-4 means do not save LR on stack.
8 TEXT _rt0_arm(SB),7,$-4
9         MOVW $setR12(SB), R12
10
11         // copy arguments forward on an even stack
12         // use R13 instead of SP to avoid linker rewriting the offsets
13         MOVW    0(R13), R0              // argc
14         MOVW    $4(R13), R1             // argv
15         SUB     $128, R13               // plenty of scratch
16         AND     $~7, R13
17         MOVW    R0, 120(R13)            // save argc, argv away
18         MOVW    R1, 124(R13)
19
20         // set up m and g registers
21         // g is R10, m is R9
22         MOVW    $g0(SB), g
23         MOVW    $m0(SB), m
24
25         // save m->g0 = g0
26         MOVW    g, m_g0(m)
27
28         // create istack out of the OS stack
29         MOVW    $(-8192+104)(R13), R0
30         MOVW    R0, g_stackguard(g)     // (w 104b guard)
31         MOVW    R13, g_stackbase(g)
32         BL      emptyfunc(SB)   // fault if stack check is wrong
33
34         BL      check(SB)
35
36         // saved argc, argv
37         MOVW    120(R13), R0
38         MOVW    R0, 4(R13)
39         MOVW    124(R13), R1
40         MOVW    R1, 8(R13)
41         BL      args(SB)
42         BL      osinit(SB)
43         BL      schedinit(SB)
44
45         // create a new goroutine to start program
46         MOVW    $mainstart(SB), R0
47         MOVW.W  R0, -4(R13)
48         MOVW    $8, R0
49         MOVW.W  R0, -4(R13)
50         MOVW    $0, R0
51         MOVW.W  R0, -4(R13)     // push $0 as guard
52         BL      ·newproc(SB)
53         MOVW    $12(R13), R13   // pop args and LR
54
55         // start this M
56         BL      mstart(SB)
57
58         MOVW    $1234, R0
59         MOVW    $1000, R1
60         MOVW    R0, (R1)        // fail hard
61         B       _dep_dummy(SB)  // Never reached
62
63
64 TEXT mainstart(SB),7,$4
65         BL      main·init(SB)
66         BL      initdone(SB)
67         BL      main·main(SB)
68         MOVW    $0, R0
69         MOVW    R0, 4(SP)
70         BL      exit(SB)
71         MOVW    $1234, R0
72         MOVW    $1001, R1
73         MOVW    R0, (R1)        // fail hard
74         RET
75
76 // TODO(kaib): remove these once i actually understand how the linker removes symbols
77 // pull in dummy dependencies
78 TEXT _dep_dummy(SB),7,$0
79         BL      _div(SB)
80         BL      _divu(SB)
81         BL      _mod(SB)
82         BL      _modu(SB)
83         BL      _modu(SB)
84         BL      _sfloat(SB)
85
86 TEXT    breakpoint(SB),7,$0
87         BL      abort(SB)
88 //      BYTE $0xcc
89 //      RET
90
91 /*
92  *  go-routine
93  */
94
95 // uintptr gosave(Gobuf*)
96 // save state in Gobuf; setjmp
97 TEXT gosave(SB), 7, $-4
98         MOVW    0(FP), R0
99         MOVW    SP, gobuf_sp(R0)
100         MOVW    LR, gobuf_pc(R0)
101         MOVW    g, gobuf_g(R0)
102         MOVW    $0, R0                  // return 0
103         RET
104
105 // void gogo(Gobuf*, uintptr)
106 // restore state from Gobuf; longjmp
107 TEXT    gogo(SB), 7, $-4
108         MOVW    0(FP), R1                       // gobuf
109         MOVW    4(FP), R0               // return 2nd arg
110         MOVW    gobuf_g(R1), g
111         MOVW    0(g), R2                // make sure g != nil
112         MOVW    gobuf_sp(R1), SP        // restore SP
113         MOVW    gobuf_pc(R1), PC
114
115 // void gogocall(Gobuf*, void (*fn)(void))
116 // restore state from Gobuf but then call fn.
117 // (call fn, returning to state in Gobuf)
118 // using frame size $-4 means do not save LR on stack.
119 TEXT gogocall(SB), 7, $-4
120         MOVW    0(FP), R0
121         MOVW    4(FP), R1               // fn
122         MOVW    gobuf_g(R0), g
123         MOVW    0(g), R2                // make sure g != nil
124         MOVW    gobuf_sp(R0), SP        // restore SP
125         MOVW    gobuf_pc(R0), LR
126         MOVW    R1, PC
127
128 /*
129  * support for morestack
130  */
131
132 // Called during function prolog when more stack is needed.
133 // R1 frame size
134 // R2 arg size
135 // R3 prolog's LR
136 // NB. we do not save R0 because the we've forced 5c to pass all arguments
137 // on the stack.
138 // using frame size $-4 means do not save LR on stack.
139 TEXT ·morestack(SB),7,$-4
140         // Cannot grow scheduler stack (m->g0).
141         MOVW    m_g0(m), R4
142         CMP     g, R4
143         BNE     2(PC)
144         BL      abort(SB)
145
146         // Save in m.
147         MOVW    R1, m_moreframe(m)
148         MOVW    R2, m_moreargs(m)
149
150         // Called from f.
151         // Set m->morebuf to f's caller.
152         MOVW    R3, (m_morebuf+gobuf_pc)(m) // f's caller's PC
153         MOVW    SP, (m_morebuf+gobuf_sp)(m) // f's caller's SP
154         MOVW    SP, m_morefp(m) // f's caller's SP
155         MOVW    g, (m_morebuf+gobuf_g)(m)
156
157         // Set m->morepc to f's PC.
158         MOVW    LR, m_morepc(m)
159
160         // Call newstack on m's scheduling stack.
161         MOVW    m_g0(m), g
162         MOVW    (m_sched+gobuf_sp)(m), SP
163         B       newstack(SB)
164
165 // Called from reflection library.  Mimics morestack,
166 // reuses stack growth code to create a frame
167 // with the desired args running the desired function.
168 //
169 // func call(fn *byte, arg *byte, argsize uint32).
170 TEXT reflect·call(SB), 7, $-4
171         // Save our caller's state as the PC and SP to
172         // restore when returning from f.
173         MOVW    LR, (m_morebuf+gobuf_pc)(m)     // our caller's PC
174         MOVW    SP, (m_morebuf+gobuf_sp)(m)     // our caller's SP
175         MOVW    g,  (m_morebuf+gobuf_g)(m)
176
177         // Set up morestack arguments to call f on a new stack.
178         // We set f's frame size to 1, as a hint to newstack
179         // that this is a call from reflect·call.
180         // If it turns out that f needs a larger frame than
181         // the default stack, f's usual stack growth prolog will
182         // allocate a new segment (and recopy the arguments).
183         MOVW    4(SP), R0       // fn
184         MOVW    8(SP), R1       // arg frame
185         MOVW    12(SP), R2      // arg size
186
187         MOVW    R0, m_morepc(m) // f's PC
188         MOVW    R1, m_morefp(m) // argument frame pointer
189         MOVW    R2, m_moreargs(m)       // f's argument size
190         MOVW    $1, R3
191         MOVW    R3, m_moreframe(m)      // f's frame size
192
193         // Call newstack on m's scheduling stack.
194         MOVW    m_g0(m), g
195         MOVW    (m_sched+gobuf_sp)(m), SP
196         B       newstack(SB)
197
198 // Return point when leaving stack.
199 // using frame size $-4 means do not save LR on stack.
200 TEXT ·lessstack(SB), 7, $-4
201         // Save return value in m->cret
202         MOVW    R0, m_cret(m)
203
204         // Call oldstack on m's scheduling stack.
205         MOVW    m_g0(m), g
206         MOVW    (m_sched+gobuf_sp)(m), SP
207         B       oldstack(SB)
208
209 // void jmpdefer(fn, sp);
210 // called from deferreturn.
211 // 1. grab stored LR for caller
212 // 2. sub 4 bytes to get back to BL deferreturn
213 // 3. B to fn
214 TEXT jmpdefer(SB), 7, $0
215         MOVW    0(SP), LR
216         MOVW    $-4(LR), LR     // BL deferreturn
217         MOVW    4(SP), R0               // fn
218         MOVW    8(SP), R1
219         MOVW    $-4(R1), SP     // correct for sp pointing to arg0, past stored lr
220         B               (R0)
221
222 TEXT    ·memclr(SB),7,$20
223         MOVW    0(FP), R0
224         MOVW    $0, R1          // c = 0
225         MOVW    R1, -16(SP)
226         MOVW    4(FP), R1       // n
227         MOVW    R1, -12(SP)
228         MOVW    m, -8(SP)       // Save m and g
229         MOVW    g, -4(SP)
230         BL      memset(SB)
231         MOVW    -8(SP), m       // Restore m and g, memset clobbers them
232         MOVW    -4(SP), g
233         RET
234
235 TEXT    ·getcallerpc+0(SB),7,$-4
236         MOVW    0(SP), R0
237         RET
238
239 TEXT    ·setcallerpc+0(SB),7,$-4
240         MOVW    x+4(FP), R0
241         MOVW    R0, 0(SP)
242         RET
243
244 // runcgo(void(*fn)(void*), void *arg)
245 // Just call fn(arg), but first align the stack
246 // appropriately for the gcc ABI.
247 // TODO(kaib): figure out the arm-gcc ABI
248 TEXT    runcgo(SB),7,$16
249         BL      abort(SB)
250 //      MOVL    fn+0(FP), AX
251 //      MOVL    arg+4(FP), BX
252 //      MOVL    SP, CX
253 //      ANDL    $~15, SP        // alignment for gcc ABI
254 //      MOVL    CX, 4(SP)
255 //      MOVL    BX, 0(SP)
256 //      CALL    AX
257 //      MOVL    4(SP), SP
258 //      RET
259
260 TEXT emptyfunc(SB),0,$0
261         RET
262
263 TEXT abort(SB),7,$0
264         MOVW    $0, R0
265         MOVW    (R0), R1
266
267 // callString(f, arg, out)
268 // call Go f(arg), which returns a string, and store in out
269 TEXT callString(SB), 7, $24
270         MOVW    arg+4(FP), R1
271         MOVW    f+0(FP), R0
272         MOVW    R1, 0(SP)
273         BL      (R0)
274         MOVW    4(SP), R1
275         MOVW    8(SP), R2
276         MOVW    12(SP), R3
277         MOVW    out+8(FP), R0
278         MOVW    R1, 0(R0)
279         MOVW    R2, 4(R0)
280         MOVW    R3, 8(R0)
281         RET