blob: 825acc4657351bd7dddad945ffcef10d4d377e1a [file] [log] [blame]
Rob Pike8e82a672008-06-30 11:50:36 -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
Russ Cox7343e032009-06-17 15:12:16 -07005#include "amd64/asm.h"
Rob Pike8e82a672008-06-30 11:50:36 -07006
7TEXT _rt0_amd64(SB),7,$-8
8
9 // copy arguments forward on an even stack
Rob Pike8e82a672008-06-30 11:50:36 -070010 MOVQ 0(SP), AX // argc
11 LEAQ 8(SP), BX // argv
12 SUBQ $(4*8+7), SP // 2args 2auto
13 ANDQ $~7, SP
14 MOVQ AX, 16(SP)
15 MOVQ BX, 24(SP)
16
Russ Coxd28acc42008-08-04 16:43:49 -070017 // set the per-goroutine and per-mach registers
Russ Cox7343e032009-06-17 15:12:16 -070018 LEAQ m0(SB), m
19 LEAQ g0(SB), g
20 MOVQ g, m_g0(m) // m has pointer to its g0
Rob Pike8e82a672008-06-30 11:50:36 -070021
Ken Thompson751ce3a2008-07-11 19:16:39 -070022 // create istack out of the given (operating system) stack
Russ Coxda0a7d72008-12-19 03:13:39 -080023 LEAQ (-8192+104)(SP), AX
Russ Cox7343e032009-06-17 15:12:16 -070024 MOVQ AX, g_stackguard(g)
25 MOVQ SP, g_stackbase(g)
Rob Pike8e82a672008-06-30 11:50:36 -070026
Ken Thompson8f53bc02008-12-15 15:07:35 -080027 CLD // convention is D is always left cleared
Rob Pike8e82a672008-06-30 11:50:36 -070028 CALL check(SB)
29
Rob Pike8e82a672008-06-30 11:50:36 -070030 MOVL 16(SP), AX // copy argc
31 MOVL AX, 0(SP)
32 MOVQ 24(SP), AX // copy argv
33 MOVQ AX, 8(SP)
34 CALL args(SB)
Russ Cox376898c2008-09-09 11:50:14 -070035 CALL osinit(SB)
Russ Coxd28acc42008-08-04 16:43:49 -070036 CALL schedinit(SB)
Russ Coxf7f63292008-08-05 14:21:42 -070037
Ken Thompson751ce3a2008-07-11 19:16:39 -070038 // create a new goroutine to start program
Russ Coxa67258f2008-09-18 15:56:46 -070039 PUSHQ $mainstart(SB) // entry
Russ Cox7343e032009-06-17 15:12:16 -070040 PUSHQ $0 // arg size
Ken Thompson751ce3a2008-07-11 19:16:39 -070041 CALL sys·newproc(SB)
Russ Coxebd1eef2008-09-22 13:47:59 -070042 POPQ AX
43 POPQ AX
Russ Cox79e1db22008-12-04 08:30:54 -080044
Russ Coxebd1eef2008-09-22 13:47:59 -070045 // start this M
Russ Coxa67258f2008-09-18 15:56:46 -070046 CALL mstart(SB)
Rob Pike8e82a672008-06-30 11:50:36 -070047
Ken Thompson751ce3a2008-07-11 19:16:39 -070048 CALL notok(SB) // never returns
Rob Pike8e82a672008-06-30 11:50:36 -070049 RET
50
Russ Coxa67258f2008-09-18 15:56:46 -070051TEXT mainstart(SB),7,$0
Russ Cox0183baa2009-01-20 14:40:00 -080052 CALL main·init(SB)
Russ Coxa67258f2008-09-18 15:56:46 -070053 CALL initdone(SB)
54 CALL main·main(SB)
Russ Coxebd1eef2008-09-22 13:47:59 -070055 PUSHQ $0
Russ Cox918afd942009-05-08 15:21:41 -070056 CALL exit(SB)
Russ Coxebd1eef2008-09-22 13:47:59 -070057 POPQ AX
58 CALL notok(SB)
Russ Coxa67258f2008-09-18 15:56:46 -070059 RET
60
Russ Cox918afd942009-05-08 15:21:41 -070061TEXT breakpoint(SB),7,$0
Ken Thompson751ce3a2008-07-11 19:16:39 -070062 BYTE $0xcc
Rob Pike8e82a672008-06-30 11:50:36 -070063 RET
64
Ken Thompson751ce3a2008-07-11 19:16:39 -070065/*
66 * go-routine
67 */
Rob Piked3204ef2008-06-30 14:39:47 -070068
Russ Cox7343e032009-06-17 15:12:16 -070069// uintptr gosave(Gobuf*)
70// save state in Gobuf; setjmp
Ken Thompson751ce3a2008-07-11 19:16:39 -070071TEXT gosave(SB), 7, $0
72 MOVQ 8(SP), AX // gobuf
Russ Cox7343e032009-06-17 15:12:16 -070073 LEAQ 8(SP), BX // caller's SP
74 MOVQ BX, gobuf_sp(AX)
75 MOVQ 0(SP), BX // caller's PC
76 MOVQ BX, gobuf_pc(AX)
77 MOVQ g, gobuf_g(AX)
Ken Thompson751ce3a2008-07-11 19:16:39 -070078 MOVL $0, AX // return 0
79 RET
80
Russ Cox7343e032009-06-17 15:12:16 -070081// void gogo(Gobuf*, uintptr)
82// restore state from Gobuf; longjmp
83TEXT gogo(SB), 7, $0
84 MOVQ 16(SP), AX // return 2nd arg
85 MOVQ 8(SP), BX // gobuf
86 MOVQ gobuf_g(BX), g
87 MOVQ 0(g), CX // make sure g != nil
88 MOVQ gobuf_sp(BX), SP // restore SP
89 MOVQ gobuf_pc(BX), BX
90 JMP BX
91
92// void gogocall(Gobuf*, void (*fn)(void))
93// restore state from Gobuf but then call fn.
94// (call fn, returning to state in Gobuf)
95TEXT gogocall(SB), 7, $0
96 MOVQ 16(SP), AX // fn
97 MOVQ 8(SP), BX // gobuf
98 MOVQ gobuf_g(BX), g
99 MOVQ 0(g), CX // make sure g != nil
100 MOVQ gobuf_sp(BX), SP // restore SP
101 MOVQ gobuf_pc(BX), BX
102 PUSHQ BX
103 JMP AX
104 POPQ BX // not reached
105
Rob Pike2da97832008-07-12 11:30:53 -0700106/*
107 * support for morestack
108 */
109
Russ Cox7343e032009-06-17 15:12:16 -0700110// Called during function prolog when more stack is needed.
111TEXT sys·morestack(SB),7,$0
112 // Called from f.
113 // Set m->morebuf to f's caller.
114 MOVQ 8(SP), AX // f's caller's PC
115 MOVQ AX, (m_morebuf+gobuf_pc)(m)
116 LEAQ 16(SP), AX // f's caller's SP
117 MOVQ AX, (m_morebuf+gobuf_sp)(m)
118 MOVQ g, (m_morebuf+gobuf_g)(m)
119
120 // Set m->morepc to f's PC.
121 MOVQ 0(SP), AX
122 MOVQ AX, m_morepc(m)
123
124 // Call newstack on m's scheduling stack.
125 MOVQ m_g0(m), g
126 MOVQ (m_sched+gobuf_sp)(m), SP
127 CALL newstack(SB)
128 MOVQ $0, 0x1003 // crash if newstack returns
129 RET
130
131// Return point when leaving stack.
132TEXT sys·lessstack(SB), 7, $0
133 // Save return value in m->cret
134 MOVQ AX, m_cret(m)
135
136 // Call oldstack on m's scheduling stack.
137 MOVQ m_g0(m), g
138 MOVQ (m_sched+gobuf_sp)(m), SP
139 CALL oldstack(SB)
140 MOVQ $0, 0x1004 // crash if oldstack returns
141 RET
142
Ken Thompson1ed7f182009-05-01 18:07:33 -0700143// morestack trampolines
144TEXT sys·morestack00+0(SB),7,$0
145 MOVQ $0, AX
Russ Cox7343e032009-06-17 15:12:16 -0700146 MOVQ AX, m_morearg(m)
Ken Thompson1ed7f182009-05-01 18:07:33 -0700147 MOVQ $sys·morestack+0(SB), AX
148 JMP AX
149
150TEXT sys·morestack01+0(SB),7,$0
151 SHLQ $32, AX
Russ Cox7343e032009-06-17 15:12:16 -0700152 MOVQ AX, m_morearg(m)
Ken Thompson1ed7f182009-05-01 18:07:33 -0700153 MOVQ $sys·morestack+0(SB), AX
154 JMP AX
155
156TEXT sys·morestack10+0(SB),7,$0
157 MOVLQZX AX, AX
Russ Cox7343e032009-06-17 15:12:16 -0700158 MOVQ AX, m_morearg(m)
Ken Thompson1ed7f182009-05-01 18:07:33 -0700159 MOVQ $sys·morestack+0(SB), AX
160 JMP AX
161
162TEXT sys·morestack11+0(SB),7,$0
Russ Cox7343e032009-06-17 15:12:16 -0700163 MOVQ AX, m_morearg(m)
Ken Thompson1ed7f182009-05-01 18:07:33 -0700164 MOVQ $sys·morestack+0(SB), AX
165 JMP AX
166
Ken Thompson5963f592009-05-03 19:09:14 -0700167// subcases of morestack01
168// with const of 8,16,...48
169TEXT sys·morestack8(SB),7,$0
170 PUSHQ $1
171 MOVQ $sys·morestackx(SB), AX
172 JMP AX
173
174TEXT sys·morestack16(SB),7,$0
175 PUSHQ $2
176 MOVQ $sys·morestackx(SB), AX
177 JMP AX
178
179TEXT sys·morestack24(SB),7,$0
180 PUSHQ $3
181 MOVQ $sys·morestackx(SB), AX
182 JMP AX
183
184TEXT sys·morestack32(SB),7,$0
185 PUSHQ $4
186 MOVQ $sys·morestackx(SB), AX
187 JMP AX
188
189TEXT sys·morestack40(SB),7,$0
190 PUSHQ $5
191 MOVQ $sys·morestackx(SB), AX
192 JMP AX
193
194TEXT sys·morestack48(SB),7,$0
195 PUSHQ $6
196 MOVQ $sys·morestackx(SB), AX
197 JMP AX
198
Russ Cox7343e032009-06-17 15:12:16 -0700199TEXT sys·morestackx(SB),7,$0
200 POPQ AX
201 SHLQ $35, AX
202 MOVQ AX, m_morearg(m)
203 MOVQ $sys·morestack(SB), AX
Rob Pike2da97832008-07-12 11:30:53 -0700204 JMP AX
205
Russ Coxd28acc42008-08-04 16:43:49 -0700206// bool cas(int32 *val, int32 old, int32 new)
207// Atomically:
208// if(*val == old){
209// *val = new;
210// return 1;
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800211// } else
Russ Coxd28acc42008-08-04 16:43:49 -0700212// return 0;
213TEXT cas(SB), 7, $0
214 MOVQ 8(SP), BX
215 MOVL 16(SP), AX
216 MOVL 20(SP), CX
217 LOCK
218 CMPXCHGL CX, 0(BX)
219 JZ 3(PC)
220 MOVL $0, AX
221 RET
222 MOVL $1, AX
223 RET
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800224
Russ Coxaa3222d82009-06-02 23:02:12 -0700225// void jmpdefer(fn, sp);
226// called from deferreturn.
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800227// 1. pop the caller
228// 2. sub 5 bytes from the callers return
229// 3. jmp to the argument
230TEXT jmpdefer(SB), 7, $0
Russ Coxaa3222d82009-06-02 23:02:12 -0700231 MOVQ 8(SP), AX // fn
232 MOVQ 16(SP), BX // caller sp
233 LEAQ -8(BX), SP // caller sp after CALL
234 SUBQ $5, (SP) // return to CALL again
235 JMP AX // but first run the deferred function