blob: c03422f10c8118d48c798b8bc66f16ad7def7eed [file] [log] [blame]
Kai Backman79435562009-05-26 11:18:42 -07001// 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
Kai Backmanbe639b92009-06-23 11:54:23 -07005#include "arm/asm.h"
6
7// using frame size $-4 means do not save LR on stack.
8TEXT _rt0_arm(SB),7,$-4
Russ Cox80527862010-10-17 11:41:23 -04009 MOVW $0xcafebabe, R12
Kai Backman79435562009-05-26 11:18:42 -070010
Kai Backman1ac2cfc2009-06-16 11:25:58 -070011 // copy arguments forward on an even stack
Kai Backmanbe639b92009-06-23 11:54:23 -070012 // use R13 instead of SP to avoid linker rewriting the offsets
13 MOVW 0(R13), R0 // argc
14 MOVW $4(R13), R1 // argv
Russ Coxd9fd1142011-02-22 17:40:40 -050015 SUB $64, R13 // plenty of scratch
Kai Backmanbe639b92009-06-23 11:54:23 -070016 AND $~7, R13
Russ Coxd9fd1142011-02-22 17:40:40 -050017 MOVW R0, 60(R13) // save argc, argv away
18 MOVW R1, 64(R13)
Kai Backman79435562009-05-26 11:18:42 -070019
Kai Backman1ac2cfc2009-06-16 11:25:58 -070020 // set up m and g registers
21 // g is R10, m is R9
Russ Cox68b42552010-11-04 14:00:19 -040022 MOVW $runtime·g0(SB), g
23 MOVW $runtime·m0(SB), m
Kai Backman79435562009-05-26 11:18:42 -070024
Kai Backman1ac2cfc2009-06-16 11:25:58 -070025 // save m->g0 = g0
Kai Backmanbe639b92009-06-23 11:54:23 -070026 MOVW g, m_g0(m)
Kai Backman79435562009-05-26 11:18:42 -070027
Kai Backman1ac2cfc2009-06-16 11:25:58 -070028 // create istack out of the OS stack
Kai Backmanbe639b92009-06-23 11:54:23 -070029 MOVW $(-8192+104)(R13), R0
30 MOVW R0, g_stackguard(g) // (w 104b guard)
31 MOVW R13, g_stackbase(g)
Russ Cox68b42552010-11-04 14:00:19 -040032 BL runtime·emptyfunc(SB) // fault if stack check is wrong
Kai Backman79435562009-05-26 11:18:42 -070033
Russ Cox68b42552010-11-04 14:00:19 -040034 BL runtime·check(SB)
Kai Backman79435562009-05-26 11:18:42 -070035
Kai Backman1ac2cfc2009-06-16 11:25:58 -070036 // saved argc, argv
Russ Coxd9fd1142011-02-22 17:40:40 -050037 MOVW 60(R13), R0
Kai Backmanbe639b92009-06-23 11:54:23 -070038 MOVW R0, 4(R13)
Russ Coxd9fd1142011-02-22 17:40:40 -050039 MOVW 64(R13), R1
Kai Backmanbe639b92009-06-23 11:54:23 -070040 MOVW R1, 8(R13)
Russ Cox68b42552010-11-04 14:00:19 -040041 BL runtime·args(SB)
42 BL runtime·osinit(SB)
43 BL runtime·schedinit(SB)
Kai Backman79435562009-05-26 11:18:42 -070044
Kai Backman1ac2cfc2009-06-16 11:25:58 -070045 // create a new goroutine to start program
Russ Cox6808da02011-10-27 18:04:12 -070046 MOVW $runtime·main(SB), R0
Kai Backmanbe639b92009-06-23 11:54:23 -070047 MOVW.W R0, -4(R13)
Kai Backman1ac2cfc2009-06-16 11:25:58 -070048 MOVW $8, R0
Kai Backmanbe639b92009-06-23 11:54:23 -070049 MOVW.W R0, -4(R13)
Kai Backman1ac2cfc2009-06-16 11:25:58 -070050 MOVW $0, R0
Kai Backmanbe639b92009-06-23 11:54:23 -070051 MOVW.W R0, -4(R13) // push $0 as guard
Russ Cox68b42552010-11-04 14:00:19 -040052 BL runtime·newproc(SB)
Kai Backmanbe639b92009-06-23 11:54:23 -070053 MOVW $12(R13), R13 // pop args and LR
Kai Backman79435562009-05-26 11:18:42 -070054
Kai Backman1ac2cfc2009-06-16 11:25:58 -070055 // start this M
Russ Cox68b42552010-11-04 14:00:19 -040056 BL runtime·mstart(SB)
Kai Backman79435562009-05-26 11:18:42 -070057
Kai Backman770b8722009-10-29 21:21:14 -070058 MOVW $1234, R0
59 MOVW $1000, R1
60 MOVW R0, (R1) // fail hard
Russ Cox68b42552010-11-04 14:00:19 -040061 B runtime·_dep_dummy(SB) // Never reached
Kai Backman1ac2cfc2009-06-16 11:25:58 -070062
Kai Backmand85bb812009-12-17 16:08:42 -080063// TODO(kaib): remove these once i actually understand how the linker removes symbols
Kai Backman52891952009-06-10 11:53:07 -070064// pull in dummy dependencies
Russ Cox68b42552010-11-04 14:00:19 -040065TEXT runtime·_dep_dummy(SB),7,$0
Kai Backman1ac2cfc2009-06-16 11:25:58 -070066 BL _div(SB)
67 BL _divu(SB)
68 BL _mod(SB)
69 BL _modu(SB)
70 BL _modu(SB)
Kai Backmand85bb812009-12-17 16:08:42 -080071 BL _sfloat(SB)
Kai Backman52891952009-06-10 11:53:07 -070072
Russ Cox68b42552010-11-04 14:00:19 -040073TEXT runtime·breakpoint(SB),7,$0
Russ Cox8fff9162010-10-25 21:25:13 -070074 // no breakpoint yet; let program exit
Russ Cox6c196012010-04-05 12:51:09 -070075 RET
Kai Backman52891952009-06-10 11:53:07 -070076
Kai Backmanbe639b92009-06-23 11:54:23 -070077/*
78 * go-routine
79 */
Kai Backman52891952009-06-10 11:53:07 -070080
Russ Coxf9ca3b52011-03-07 10:37:42 -050081// void gosave(Gobuf*)
Kai Backmanbe639b92009-06-23 11:54:23 -070082// save state in Gobuf; setjmp
Russ Cox68b42552010-11-04 14:00:19 -040083TEXT runtime·gosave(SB), 7, $-4
Ken Thompsoned575dc2010-10-08 16:46:05 -070084 MOVW 0(FP), R0 // gobuf
Kai Backmanbe639b92009-06-23 11:54:23 -070085 MOVW SP, gobuf_sp(R0)
86 MOVW LR, gobuf_pc(R0)
87 MOVW g, gobuf_g(R0)
Kai Backmanbe639b92009-06-23 11:54:23 -070088 RET
89
90// void gogo(Gobuf*, uintptr)
91// restore state from Gobuf; longjmp
Russ Cox68b42552010-11-04 14:00:19 -040092TEXT runtime·gogo(SB), 7, $-4
Ken Thompsoned575dc2010-10-08 16:46:05 -070093 MOVW 0(FP), R1 // gobuf
Kai Backman46e392e2009-09-18 16:45:41 -070094 MOVW 4(FP), R0 // return 2nd arg
Kai Backmanbe639b92009-06-23 11:54:23 -070095 MOVW gobuf_g(R1), g
96 MOVW 0(g), R2 // make sure g != nil
97 MOVW gobuf_sp(R1), SP // restore SP
98 MOVW gobuf_pc(R1), PC
99
100// void gogocall(Gobuf*, void (*fn)(void))
101// restore state from Gobuf but then call fn.
102// (call fn, returning to state in Gobuf)
Kai Backmanbe639b92009-06-23 11:54:23 -0700103// using frame size $-4 means do not save LR on stack.
Russ Cox68b42552010-11-04 14:00:19 -0400104TEXT runtime·gogocall(SB), 7, $-4
Ken Thompsoned575dc2010-10-08 16:46:05 -0700105 MOVW 0(FP), R0 // gobuf
Kai Backman46e392e2009-09-18 16:45:41 -0700106 MOVW 4(FP), R1 // fn
Ken Thompsoned575dc2010-10-08 16:46:05 -0700107 MOVW 8(FP), R2 // fp offset
Kai Backmanbe639b92009-06-23 11:54:23 -0700108 MOVW gobuf_g(R0), g
Ken Thompsoned575dc2010-10-08 16:46:05 -0700109 MOVW 0(g), R3 // make sure g != nil
Kai Backmanbe639b92009-06-23 11:54:23 -0700110 MOVW gobuf_sp(R0), SP // restore SP
111 MOVW gobuf_pc(R0), LR
112 MOVW R1, PC
113
Russ Coxf9ca3b52011-03-07 10:37:42 -0500114// void mcall(void (*fn)(G*))
115// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400116// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500117// to keep running g.
118TEXT runtime·mcall(SB), 7, $-4
119 MOVW fn+0(FP), R0
120
121 // Save caller state in g->gobuf.
122 MOVW SP, (g_sched+gobuf_sp)(g)
123 MOVW LR, (g_sched+gobuf_pc)(g)
124 MOVW g, (g_sched+gobuf_g)(g)
125
126 // Switch to m->g0 & its stack, call fn.
127 MOVW g, R1
128 MOVW m_g0(m), g
129 CMP g, R1
130 BL.EQ runtime·badmcall(SB)
131 MOVW (g_sched+gobuf_sp)(g), SP
132 SUB $8, SP
133 MOVW R1, 4(SP)
134 BL (R0)
135 BL runtime·badmcall2(SB)
136 RET
137
Kai Backmanbe639b92009-06-23 11:54:23 -0700138/*
139 * support for morestack
140 */
141
142// Called during function prolog when more stack is needed.
143// R1 frame size
144// R2 arg size
145// R3 prolog's LR
Russ Cox6c196012010-04-05 12:51:09 -0700146// NB. we do not save R0 because we've forced 5c to pass all arguments
Kai Backman0af8e102009-10-23 10:59:31 -0700147// on the stack.
Kai Backmanbe639b92009-06-23 11:54:23 -0700148// using frame size $-4 means do not save LR on stack.
Russ Cox68b42552010-11-04 14:00:19 -0400149TEXT runtime·morestack(SB),7,$-4
Kai Backmanbe639b92009-06-23 11:54:23 -0700150 // Cannot grow scheduler stack (m->g0).
151 MOVW m_g0(m), R4
152 CMP g, R4
Russ Cox68b42552010-11-04 14:00:19 -0400153 BL.EQ runtime·abort(SB)
Kai Backman52891952009-06-10 11:53:07 -0700154
Kai Backmanbe639b92009-06-23 11:54:23 -0700155 // Save in m.
Russ Cox141a4a12011-01-14 14:05:20 -0500156 MOVW R1, m_moreframesize(m)
157 MOVW R2, m_moreargsize(m)
Kai Backman52891952009-06-10 11:53:07 -0700158
Kai Backmanbe639b92009-06-23 11:54:23 -0700159 // Called from f.
160 // Set m->morebuf to f's caller.
Ken Thompsonb33f5d52010-10-13 13:24:14 -0700161 MOVW R3, (m_morebuf+gobuf_pc)(m) // f's caller's PC
162 MOVW SP, (m_morebuf+gobuf_sp)(m) // f's caller's SP
Russ Cox141a4a12011-01-14 14:05:20 -0500163 MOVW $4(SP), R3 // f's argument pointer
164 MOVW R3, m_moreargp(m)
Kai Backmanbe639b92009-06-23 11:54:23 -0700165 MOVW g, (m_morebuf+gobuf_g)(m)
Kai Backman52891952009-06-10 11:53:07 -0700166
Kai Backmanbe639b92009-06-23 11:54:23 -0700167 // Set m->morepc to f's PC.
168 MOVW LR, m_morepc(m)
Kai Backman52891952009-06-10 11:53:07 -0700169
Russ Coxf9ca3b52011-03-07 10:37:42 -0500170 // Call newstack on m->g0's stack.
Kai Backmanbe639b92009-06-23 11:54:23 -0700171 MOVW m_g0(m), g
Russ Coxf9ca3b52011-03-07 10:37:42 -0500172 MOVW (g_sched+gobuf_sp)(g), SP
Russ Cox68b42552010-11-04 14:00:19 -0400173 B runtime·newstack(SB)
Kai Backmanbe639b92009-06-23 11:54:23 -0700174
Russ Coxbba278a2009-07-08 18:16:09 -0700175// Called from reflection library. Mimics morestack,
176// reuses stack growth code to create a frame
177// with the desired args running the desired function.
178//
179// func call(fn *byte, arg *byte, argsize uint32).
180TEXT reflect·call(SB), 7, $-4
181 // Save our caller's state as the PC and SP to
182 // restore when returning from f.
183 MOVW LR, (m_morebuf+gobuf_pc)(m) // our caller's PC
184 MOVW SP, (m_morebuf+gobuf_sp)(m) // our caller's SP
Kai Backman7842b032009-07-12 22:12:19 -0700185 MOVW g, (m_morebuf+gobuf_g)(m)
Russ Coxbba278a2009-07-08 18:16:09 -0700186
187 // Set up morestack arguments to call f on a new stack.
Russ Cox83727cc2010-03-29 21:48:22 -0700188 // We set f's frame size to 1, as a hint to newstack
189 // that this is a call from reflect·call.
190 // If it turns out that f needs a larger frame than
191 // the default stack, f's usual stack growth prolog will
192 // allocate a new segment (and recopy the arguments).
Ken Thompsoned575dc2010-10-08 16:46:05 -0700193 MOVW 4(SP), R0 // fn
194 MOVW 8(SP), R1 // arg frame
195 MOVW 12(SP), R2 // arg size
Russ Coxbba278a2009-07-08 18:16:09 -0700196
Ken Thompsoned575dc2010-10-08 16:46:05 -0700197 MOVW R0, m_morepc(m) // f's PC
Russ Cox141a4a12011-01-14 14:05:20 -0500198 MOVW R1, m_moreargp(m) // f's argument pointer
199 MOVW R2, m_moreargsize(m) // f's argument size
Russ Cox83727cc2010-03-29 21:48:22 -0700200 MOVW $1, R3
Russ Cox141a4a12011-01-14 14:05:20 -0500201 MOVW R3, m_moreframesize(m) // f's frame size
Russ Coxbba278a2009-07-08 18:16:09 -0700202
Russ Coxf9ca3b52011-03-07 10:37:42 -0500203 // Call newstack on m->g0's stack.
Russ Coxbba278a2009-07-08 18:16:09 -0700204 MOVW m_g0(m), g
Russ Coxf9ca3b52011-03-07 10:37:42 -0500205 MOVW (g_sched+gobuf_sp)(g), SP
Russ Cox68b42552010-11-04 14:00:19 -0400206 B runtime·newstack(SB)
Russ Coxbba278a2009-07-08 18:16:09 -0700207
Kai Backmanbe639b92009-06-23 11:54:23 -0700208// Return point when leaving stack.
209// using frame size $-4 means do not save LR on stack.
Russ Cox68b42552010-11-04 14:00:19 -0400210TEXT runtime·lessstack(SB), 7, $-4
Kai Backmanbe639b92009-06-23 11:54:23 -0700211 // Save return value in m->cret
212 MOVW R0, m_cret(m)
213
Russ Coxf9ca3b52011-03-07 10:37:42 -0500214 // Call oldstack on m->g0's stack.
Kai Backmanbe639b92009-06-23 11:54:23 -0700215 MOVW m_g0(m), g
Russ Coxf9ca3b52011-03-07 10:37:42 -0500216 MOVW (g_sched+gobuf_sp)(g), SP
Russ Cox68b42552010-11-04 14:00:19 -0400217 B runtime·oldstack(SB)
Kai Backman1ac2cfc2009-06-16 11:25:58 -0700218
Kai Backman52891952009-06-10 11:53:07 -0700219// void jmpdefer(fn, sp);
220// called from deferreturn.
Kai Backmand58b5fc2009-10-05 21:52:10 -0700221// 1. grab stored LR for caller
222// 2. sub 4 bytes to get back to BL deferreturn
223// 3. B to fn
Russ Cox68b42552010-11-04 14:00:19 -0400224TEXT runtime·jmpdefer(SB), 7, $0
Kai Backmand58b5fc2009-10-05 21:52:10 -0700225 MOVW 0(SP), LR
226 MOVW $-4(LR), LR // BL deferreturn
Russ Cox141a4a12011-01-14 14:05:20 -0500227 MOVW fn+0(FP), R0
228 MOVW argp+4(FP), SP
229 MOVW $-4(SP), SP // SP is 4 below argp, due to saved LR
Kai Backmand58b5fc2009-10-05 21:52:10 -0700230 B (R0)
Kai Backman52891952009-06-10 11:53:07 -0700231
Russ Coxf9ca3b52011-03-07 10:37:42 -0500232TEXT runtime·asmcgocall(SB),7,$0
233 B runtime·cgounimpl(SB)
234
235TEXT runtime·cgocallback(SB),7,$0
236 B runtime·cgounimpl(SB)
237
Russ Cox68b42552010-11-04 14:00:19 -0400238TEXT runtime·memclr(SB),7,$20
Kai Backman46e392e2009-09-18 16:45:41 -0700239 MOVW 0(FP), R0
Kai Backmanbe639b92009-06-23 11:54:23 -0700240 MOVW $0, R1 // c = 0
241 MOVW R1, -16(SP)
242 MOVW 4(FP), R1 // n
243 MOVW R1, -12(SP)
244 MOVW m, -8(SP) // Save m and g
245 MOVW g, -4(SP)
Russ Cox68b42552010-11-04 14:00:19 -0400246 BL runtime·memset(SB)
Kai Backmanbe639b92009-06-23 11:54:23 -0700247 MOVW -8(SP), m // Restore m and g, memset clobbers them
248 MOVW -4(SP), g
249 RET
Kai Backman52891952009-06-10 11:53:07 -0700250
Russ Cox68b42552010-11-04 14:00:19 -0400251TEXT runtime·getcallerpc(SB),7,$-4
Kai Backman33a7bcf2009-10-19 21:58:16 -0700252 MOVW 0(SP), R0
253 RET
Kai Backman52891952009-06-10 11:53:07 -0700254
Russ Cox68b42552010-11-04 14:00:19 -0400255TEXT runtime·setcallerpc(SB),7,$-4
Kai Backman33a7bcf2009-10-19 21:58:16 -0700256 MOVW x+4(FP), R0
257 MOVW R0, 0(SP)
258 RET
Kai Backman52891952009-06-10 11:53:07 -0700259
Russ Cox68b42552010-11-04 14:00:19 -0400260TEXT runtime·getcallersp(SB),7,$-4
Russ Cox6c196012010-04-05 12:51:09 -0700261 MOVW 0(FP), R0
262 MOVW $-4(R0), R0
263 RET
264
Russ Cox68b42552010-11-04 14:00:19 -0400265TEXT runtime·emptyfunc(SB),0,$0
Kai Backman1ac2cfc2009-06-16 11:25:58 -0700266 RET
267
Russ Cox68b42552010-11-04 14:00:19 -0400268TEXT runtime·abort(SB),7,$-4
Kai Backman1ac2cfc2009-06-16 11:25:58 -0700269 MOVW $0, R0
270 MOVW (R0), R1
Kai Backman52891952009-06-10 11:53:07 -0700271
Russ Cox9ad97422011-02-25 14:29:55 -0500272// bool armcas(int32 *val, int32 old, int32 new)
273// Atomically:
274// if(*val == old){
275// *val = new;
276// return 1;
277// }else
278// return 0;
279//
280// To implement runtime·cas in ../$GOOS/arm/sys.s
281// using the native instructions, use:
282//
283// TEXT runtime·cas(SB),7,$0
284// B runtime·armcas(SB)
285//
286TEXT runtime·armcas(SB),7,$0
287 MOVW valptr+0(FP), R1
288 MOVW old+4(FP), R2
289 MOVW new+8(FP), R3
290casl:
291 LDREX (R1), R0
292 CMP R0, R2
293 BNE casfail
294 STREX R3, (R1), R0
295 CMP $0, R0
296 BNE casl
297 MOVW $1, R0
298 RET
299casfail:
300 MOVW $0, R0
301 RET