LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "zasm_GOOS_GOARCH.h" | 5 #include "zasm_GOOS_GOARCH.h" |
6 | 6 #include "funcdata.h" |
7 TEXT _rt0_go(SB),7,$0 | 7 #include "../../cmd/ld/textflag.h" |
| 8 |
| 9 TEXT _rt0_go(SB),NOSPLIT,$0 |
8 // copy arguments forward on an even stack | 10 // copy arguments forward on an even stack |
9 MOVL argc+0(FP), AX | 11 MOVL argc+0(FP), AX |
10 MOVL argv+4(FP), BX | 12 MOVL argv+4(FP), BX |
11 SUBL $128, SP // plenty of scratch | 13 SUBL $128, SP // plenty of scratch |
12 ANDL $~15, SP | 14 ANDL $~15, SP |
13 MOVL AX, 120(SP) // save argc, argv away | 15 MOVL AX, 120(SP) // save argc, argv away |
14 MOVL BX, 124(SP) | 16 MOVL BX, 124(SP) |
15 | 17 |
16 // set default stack bounds. | 18 // set default stack bounds. |
17 // _cgo_init may update stackguard. | 19 // _cgo_init may update stackguard. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 MOVL 124(SP), AX | 90 MOVL 124(SP), AX |
89 MOVL AX, 4(SP) | 91 MOVL AX, 4(SP) |
90 CALL runtime·args(SB) | 92 CALL runtime·args(SB) |
91 CALL runtime·osinit(SB) | 93 CALL runtime·osinit(SB) |
92 CALL runtime·hashinit(SB) | 94 CALL runtime·hashinit(SB) |
93 CALL runtime·schedinit(SB) | 95 CALL runtime·schedinit(SB) |
94 | 96 |
95 // create a new goroutine to start program | 97 // create a new goroutine to start program |
96 PUSHL $runtime·main·f(SB) // entry | 98 PUSHL $runtime·main·f(SB) // entry |
97 PUSHL $0 // arg size | 99 PUSHL $0 // arg size |
| 100 ARGSIZE(8) |
98 CALL runtime·newproc(SB) | 101 CALL runtime·newproc(SB) |
| 102 ARGSIZE(-1) |
99 POPL AX | 103 POPL AX |
100 POPL AX | 104 POPL AX |
101 | 105 |
102 // start this M | 106 // start this M |
103 CALL runtime·mstart(SB) | 107 CALL runtime·mstart(SB) |
104 | 108 |
105 INT $3 | 109 INT $3 |
106 RET | 110 RET |
107 | 111 |
108 DATA runtime·main·f+0(SB)/4,$runtime·main(SB) | 112 DATA runtime·main·f+0(SB)/4,$runtime·main(SB) |
109 GLOBL» runtime·main·f(SB),8,$4 | 113 GLOBL» runtime·main·f(SB),RODATA,$4 |
110 | 114 |
111 TEXT runtime·breakpoint(SB),7,$0 | 115 TEXT runtime·breakpoint(SB),NOSPLIT,$0-0 |
112 INT $3 | 116 INT $3 |
113 RET | 117 RET |
114 | 118 |
115 TEXT runtime·asminit(SB),7,$0 | 119 TEXT runtime·asminit(SB),NOSPLIT,$0-0 |
116 // Linux and MinGW start the FPU in extended double precision. | 120 // Linux and MinGW start the FPU in extended double precision. |
117 // Other operating systems use double precision. | 121 // Other operating systems use double precision. |
118 // Change to double precision to match them, | 122 // Change to double precision to match them, |
119 // and to match other hardware that only has double. | 123 // and to match other hardware that only has double. |
120 PUSHL $0x27F | 124 PUSHL $0x27F |
121 FLDCW 0(SP) | 125 FLDCW 0(SP) |
122 POPL AX | 126 POPL AX |
123 RET | 127 RET |
124 | 128 |
125 /* | 129 /* |
126 * go-routine | 130 * go-routine |
127 */ | 131 */ |
128 | 132 |
129 // void gosave(Gobuf*) | 133 // void gosave(Gobuf*) |
130 // save state in Gobuf; setjmp | 134 // save state in Gobuf; setjmp |
131 TEXT runtime·gosave(SB), 7, $0 | 135 TEXT runtime·gosave(SB), NOSPLIT, $0-4 |
132 MOVL 4(SP), AX // gobuf | 136 MOVL 4(SP), AX // gobuf |
133 LEAL 4(SP), BX // caller's SP | 137 LEAL 4(SP), BX // caller's SP |
134 MOVL BX, gobuf_sp(AX) | 138 MOVL BX, gobuf_sp(AX) |
135 MOVL 0(SP), BX // caller's PC | 139 MOVL 0(SP), BX // caller's PC |
136 MOVL BX, gobuf_pc(AX) | 140 MOVL BX, gobuf_pc(AX) |
137 MOVL $0, gobuf_ret(AX) | 141 MOVL $0, gobuf_ret(AX) |
138 MOVL $0, gobuf_ctxt(AX) | 142 MOVL $0, gobuf_ctxt(AX) |
139 get_tls(CX) | 143 get_tls(CX) |
140 MOVL g(CX), BX | 144 MOVL g(CX), BX |
141 MOVL BX, gobuf_g(AX) | 145 MOVL BX, gobuf_g(AX) |
142 RET | 146 RET |
143 | 147 |
144 // void gogo(Gobuf*) | 148 // void gogo(Gobuf*) |
145 // restore state from Gobuf; longjmp | 149 // restore state from Gobuf; longjmp |
146 TEXT runtime·gogo(SB), 7, $0 | 150 TEXT runtime·gogo(SB), NOSPLIT, $0-4 |
147 MOVL 4(SP), BX // gobuf | 151 MOVL 4(SP), BX // gobuf |
148 MOVL gobuf_g(BX), DX | 152 MOVL gobuf_g(BX), DX |
149 MOVL 0(DX), CX // make sure g != nil | 153 MOVL 0(DX), CX // make sure g != nil |
150 get_tls(CX) | 154 get_tls(CX) |
151 MOVL DX, g(CX) | 155 MOVL DX, g(CX) |
152 MOVL gobuf_sp(BX), SP // restore SP | 156 MOVL gobuf_sp(BX), SP // restore SP |
153 MOVL gobuf_ret(BX), AX | 157 MOVL gobuf_ret(BX), AX |
154 MOVL gobuf_ctxt(BX), DX | 158 MOVL gobuf_ctxt(BX), DX |
155 MOVL $0, gobuf_sp(BX) // clear to help garbage collector | 159 MOVL $0, gobuf_sp(BX) // clear to help garbage collector |
156 MOVL $0, gobuf_ret(BX) | 160 MOVL $0, gobuf_ret(BX) |
157 MOVL $0, gobuf_ctxt(BX) | 161 MOVL $0, gobuf_ctxt(BX) |
158 MOVL gobuf_pc(BX), BX | 162 MOVL gobuf_pc(BX), BX |
159 JMP BX | 163 JMP BX |
160 | 164 |
161 // void mcall(void (*fn)(G*)) | 165 // void mcall(void (*fn)(G*)) |
162 // Switch to m->g0's stack, call fn(g). | 166 // Switch to m->g0's stack, call fn(g). |
163 // Fn must never return. It should gogo(&g->sched) | 167 // Fn must never return. It should gogo(&g->sched) |
164 // to keep running g. | 168 // to keep running g. |
165 TEXT runtime·mcall(SB), 7, $0 | 169 TEXT runtime·mcall(SB), NOSPLIT, $0-4 |
166 MOVL fn+0(FP), DI | 170 MOVL fn+0(FP), DI |
167 ········ | 171 ········ |
168 get_tls(CX) | 172 get_tls(CX) |
169 MOVL g(CX), AX // save state in g->sched | 173 MOVL g(CX), AX // save state in g->sched |
170 MOVL 0(SP), BX // caller's PC | 174 MOVL 0(SP), BX // caller's PC |
171 MOVL BX, (g_sched+gobuf_pc)(AX) | 175 MOVL BX, (g_sched+gobuf_pc)(AX) |
172 LEAL 4(SP), BX // caller's SP | 176 LEAL 4(SP), BX // caller's SP |
173 MOVL BX, (g_sched+gobuf_sp)(AX) | 177 MOVL BX, (g_sched+gobuf_sp)(AX) |
174 MOVL AX, (g_sched+gobuf_g)(AX) | 178 MOVL AX, (g_sched+gobuf_g)(AX) |
175 | 179 |
176 // switch to m->g0 & its stack, call fn | 180 // switch to m->g0 & its stack, call fn |
177 MOVL m(CX), BX | 181 MOVL m(CX), BX |
178 MOVL m_g0(BX), SI | 182 MOVL m_g0(BX), SI |
179 CMPL SI, AX // if g == m->g0 call badmcall | 183 CMPL SI, AX // if g == m->g0 call badmcall |
180 JNE 2(PC) | 184 JNE 2(PC) |
181 CALL runtime·badmcall(SB) | 185 CALL runtime·badmcall(SB) |
182 MOVL SI, g(CX) // g = m->g0 | 186 MOVL SI, g(CX) // g = m->g0 |
183 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp | 187 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp |
184 PUSHL AX | 188 PUSHL AX |
185 CALL DI | 189 CALL DI |
186 POPL AX | 190 POPL AX |
187 CALL runtime·badmcall2(SB) | 191 CALL runtime·badmcall2(SB) |
188 RET | 192 RET |
189 | 193 |
190 /* | 194 /* |
191 * support for morestack | 195 * support for morestack |
192 */ | 196 */ |
193 | 197 |
194 // Called during function prolog when more stack is needed. | 198 // Called during function prolog when more stack is needed. |
195 TEXT runtime·morestack(SB),7,$0 | 199 // |
| 200 // The traceback routines see morestack on a g0 as being |
| 201 // the top of a stack (for example, morestack calling newstack |
| 202 // calling the scheduler calling newm calling gc), so we must |
| 203 // record an argument size. For that purpose, it has no arguments. |
| 204 TEXT runtime·morestack(SB),NOSPLIT,$0-0 |
196 // Cannot grow scheduler stack (m->g0). | 205 // Cannot grow scheduler stack (m->g0). |
197 get_tls(CX) | 206 get_tls(CX) |
198 MOVL m(CX), BX | 207 MOVL m(CX), BX |
199 MOVL m_g0(BX), SI | 208 MOVL m_g0(BX), SI |
200 CMPL g(CX), SI | 209 CMPL g(CX), SI |
201 JNE 2(PC) | 210 JNE 2(PC) |
202 INT $3 | 211 INT $3 |
203 ········ | |
204 MOVL DX, m_cret(BX) | |
205 | 212 |
206 // frame size in DI | 213 // frame size in DI |
207 // arg size in AX | 214 // arg size in AX |
208 // Save in m. | 215 // Save in m. |
209 MOVL DI, m_moreframesize(BX) | 216 MOVL DI, m_moreframesize(BX) |
210 MOVL AX, m_moreargsize(BX) | 217 MOVL AX, m_moreargsize(BX) |
211 | 218 |
212 // Called from f. | 219 // Called from f. |
213 // Set m->morebuf to f's caller. | 220 // Set m->morebuf to f's caller. |
214 MOVL 4(SP), DI // f's caller's PC | 221 MOVL 4(SP), DI // f's caller's PC |
215 MOVL DI, (m_morebuf+gobuf_pc)(BX) | 222 MOVL DI, (m_morebuf+gobuf_pc)(BX) |
216 LEAL 8(SP), CX // f's caller's SP | 223 LEAL 8(SP), CX // f's caller's SP |
217 MOVL CX, (m_morebuf+gobuf_sp)(BX) | 224 MOVL CX, (m_morebuf+gobuf_sp)(BX) |
218 MOVL CX, m_moreargp(BX) | 225 MOVL CX, m_moreargp(BX) |
219 get_tls(CX) | 226 get_tls(CX) |
220 MOVL g(CX), SI | 227 MOVL g(CX), SI |
221 MOVL SI, (m_morebuf+gobuf_g)(BX) | 228 MOVL SI, (m_morebuf+gobuf_g)(BX) |
222 | 229 |
223 » // Set m->morepc to f's PC. | 230 » // Set g->sched to context in f. |
224 » MOVL» 0(SP), AX | 231 » MOVL» 0(SP), AX» // f's PC |
225 » MOVL» AX, m_morepc(BX) | 232 » MOVL» AX, (g_sched+gobuf_pc)(SI) |
| 233 » MOVL» SI, (g_sched+gobuf_g)(SI) |
| 234 » LEAL» 4(SP), AX» // f's SP |
| 235 » MOVL» AX, (g_sched+gobuf_sp)(SI) |
| 236 » MOVL» DX, (g_sched+gobuf_ctxt)(SI) |
226 | 237 |
227 // Call newstack on m->g0's stack. | 238 // Call newstack on m->g0's stack. |
228 MOVL m_g0(BX), BP | 239 MOVL m_g0(BX), BP |
229 MOVL BP, g(CX) | 240 MOVL BP, g(CX) |
230 MOVL (g_sched+gobuf_sp)(BP), AX | 241 MOVL (g_sched+gobuf_sp)(BP), AX |
231 MOVL -4(AX), BX // fault if CALL would, before smashing SP | 242 MOVL -4(AX), BX // fault if CALL would, before smashing SP |
232 MOVL AX, SP | 243 MOVL AX, SP |
233 CALL runtime·newstack(SB) | 244 CALL runtime·newstack(SB) |
234 MOVL $0, 0x1003 // crash if newstack returns | 245 MOVL $0, 0x1003 // crash if newstack returns |
235 RET | 246 RET |
236 | 247 |
237 // Called from reflection library. Mimics morestack, | 248 // Called from panic. Mimics morestack, |
238 // reuses stack growth code to create a frame | 249 // reuses stack growth code to create a frame |
239 // with the desired args running the desired function. | 250 // with the desired args running the desired function. |
240 // | 251 // |
241 // func call(fn *byte, arg *byte, argsize uint32). | 252 // func call(fn *byte, arg *byte, argsize uint32). |
242 TEXT reflect·call(SB), 7, $0 | 253 TEXT runtime·newstackcall(SB), NOSPLIT, $0-12 |
243 get_tls(CX) | 254 get_tls(CX) |
244 MOVL m(CX), BX | 255 MOVL m(CX), BX |
245 | 256 |
246 // Save our caller's state as the PC and SP to | 257 // Save our caller's state as the PC and SP to |
247 // restore when returning from f. | 258 // restore when returning from f. |
248 MOVL 0(SP), AX // our caller's PC | 259 MOVL 0(SP), AX // our caller's PC |
249 MOVL AX, (m_morebuf+gobuf_pc)(BX) | 260 MOVL AX, (m_morebuf+gobuf_pc)(BX) |
250 LEAL 4(SP), AX // our caller's SP | 261 LEAL 4(SP), AX // our caller's SP |
251 MOVL AX, (m_morebuf+gobuf_sp)(BX) | 262 MOVL AX, (m_morebuf+gobuf_sp)(BX) |
252 MOVL g(CX), AX | 263 MOVL g(CX), AX |
253 MOVL AX, (m_morebuf+gobuf_g)(BX) | 264 MOVL AX, (m_morebuf+gobuf_g)(BX) |
254 | 265 |
| 266 // Save our own state as the PC and SP to restore |
| 267 // if this goroutine needs to be restarted. |
| 268 MOVL $runtime·newstackcall(SB), (g_sched+gobuf_pc)(AX) |
| 269 MOVL SP, (g_sched+gobuf_sp)(AX) |
| 270 |
255 // Set up morestack arguments to call f on a new stack. | 271 // Set up morestack arguments to call f on a new stack. |
256 // We set f's frame size to 1, as a hint to newstack | 272 // We set f's frame size to 1, as a hint to newstack |
257 » // that this is a call from reflect·call. | 273 » // that this is a call from runtime·newstackcall. |
258 // If it turns out that f needs a larger frame than | 274 // If it turns out that f needs a larger frame than |
259 // the default stack, f's usual stack growth prolog will | 275 // the default stack, f's usual stack growth prolog will |
260 // allocate a new segment (and recopy the arguments). | 276 // allocate a new segment (and recopy the arguments). |
261 MOVL 4(SP), AX // fn | 277 MOVL 4(SP), AX // fn |
262 MOVL 8(SP), DX // arg frame | 278 MOVL 8(SP), DX // arg frame |
263 MOVL 12(SP), CX // arg size | 279 MOVL 12(SP), CX // arg size |
264 | 280 |
265 » MOVL» AX, m_morepc(BX)» // f's PC | 281 » MOVL» AX, m_cret(BX)» // f's PC |
266 MOVL DX, m_moreargp(BX) // f's argument pointer | 282 MOVL DX, m_moreargp(BX) // f's argument pointer |
267 MOVL CX, m_moreargsize(BX) // f's argument size | 283 MOVL CX, m_moreargsize(BX) // f's argument size |
268 MOVL $1, m_moreframesize(BX) // f's frame size | 284 MOVL $1, m_moreframesize(BX) // f's frame size |
269 | 285 |
270 // Call newstack on m->g0's stack. | 286 // Call newstack on m->g0's stack. |
271 MOVL m_g0(BX), BP | 287 MOVL m_g0(BX), BP |
272 get_tls(CX) | 288 get_tls(CX) |
273 MOVL BP, g(CX) | 289 MOVL BP, g(CX) |
274 MOVL (g_sched+gobuf_sp)(BP), SP | 290 MOVL (g_sched+gobuf_sp)(BP), SP |
275 CALL runtime·newstack(SB) | 291 CALL runtime·newstack(SB) |
276 MOVL $0, 0x1103 // crash if newstack returns | 292 MOVL $0, 0x1103 // crash if newstack returns |
277 RET | 293 RET |
278 | 294 |
| 295 // reflect·call: call a function with the given argument list |
| 296 // func call(f *FuncVal, arg *byte, argsize uint32). |
| 297 // we don't have variable-sized frames, so we use a small number |
| 298 // of constant-sized-frame functions to encode a few bits of size in the pc. |
| 299 // Caution: ugly multiline assembly macros in your future! |
| 300 |
| 301 #define DISPATCH(NAME,MAXSIZE) \ |
| 302 CMPL CX, $MAXSIZE; \ |
| 303 JA 3(PC); \ |
| 304 MOVL $runtime·NAME(SB), AX; \ |
| 305 JMP AX |
| 306 // Note: can't just "JMP runtime·NAME(SB)" - bad inlining results. |
| 307 |
| 308 TEXT reflect·call(SB), NOSPLIT, $0-12 |
| 309 MOVL argsize+8(FP), CX |
| 310 DISPATCH(call16, 16) |
| 311 DISPATCH(call32, 32) |
| 312 DISPATCH(call64, 64) |
| 313 DISPATCH(call128, 128) |
| 314 DISPATCH(call256, 256) |
| 315 DISPATCH(call512, 512) |
| 316 DISPATCH(call1024, 1024) |
| 317 DISPATCH(call2048, 2048) |
| 318 DISPATCH(call4096, 4096) |
| 319 DISPATCH(call8192, 8192) |
| 320 DISPATCH(call16384, 16384) |
| 321 DISPATCH(call32768, 32768) |
| 322 DISPATCH(call65536, 65536) |
| 323 DISPATCH(call131072, 131072) |
| 324 DISPATCH(call262144, 262144) |
| 325 DISPATCH(call524288, 524288) |
| 326 DISPATCH(call1048576, 1048576) |
| 327 DISPATCH(call2097152, 2097152) |
| 328 DISPATCH(call4194304, 4194304) |
| 329 DISPATCH(call8388608, 8388608) |
| 330 DISPATCH(call16777216, 16777216) |
| 331 DISPATCH(call33554432, 33554432) |
| 332 DISPATCH(call67108864, 67108864) |
| 333 DISPATCH(call134217728, 134217728) |
| 334 DISPATCH(call268435456, 268435456) |
| 335 DISPATCH(call536870912, 536870912) |
| 336 DISPATCH(call1073741824, 1073741824) |
| 337 MOVL $runtime·badreflectcall(SB), AX |
| 338 JMP AX |
| 339 |
| 340 #define CALLFN(NAME,MAXSIZE) \ |
| 341 TEXT runtime·NAME(SB), 0, $MAXSIZE-12; \ |
| 342 /* copy arguments to stack */ \ |
| 343 MOVL argptr+4(FP), SI; \ |
| 344 MOVL argsize+8(FP), CX; \ |
| 345 MOVL SP, DI; \ |
| 346 REP;MOVSB; \ |
| 347 /* call function */ \ |
| 348 MOVL f+0(FP), DX; \ |
| 349 CALL (DX); \ |
| 350 /* copy return values back */ \ |
| 351 MOVL argptr+4(FP), DI; \ |
| 352 MOVL argsize+8(FP), CX; \ |
| 353 MOVL SP, SI; \ |
| 354 REP;MOVSB; \ |
| 355 RET |
| 356 |
| 357 CALLFN(call16, 16) |
| 358 CALLFN(call32, 32) |
| 359 CALLFN(call64, 64) |
| 360 CALLFN(call128, 128) |
| 361 CALLFN(call256, 256) |
| 362 CALLFN(call512, 512) |
| 363 CALLFN(call1024, 1024) |
| 364 CALLFN(call2048, 2048) |
| 365 CALLFN(call4096, 4096) |
| 366 CALLFN(call8192, 8192) |
| 367 CALLFN(call16384, 16384) |
| 368 CALLFN(call32768, 32768) |
| 369 CALLFN(call65536, 65536) |
| 370 CALLFN(call131072, 131072) |
| 371 CALLFN(call262144, 262144) |
| 372 CALLFN(call524288, 524288) |
| 373 CALLFN(call1048576, 1048576) |
| 374 CALLFN(call2097152, 2097152) |
| 375 CALLFN(call4194304, 4194304) |
| 376 CALLFN(call8388608, 8388608) |
| 377 CALLFN(call16777216, 16777216) |
| 378 CALLFN(call33554432, 33554432) |
| 379 CALLFN(call67108864, 67108864) |
| 380 CALLFN(call134217728, 134217728) |
| 381 CALLFN(call268435456, 268435456) |
| 382 CALLFN(call536870912, 536870912) |
| 383 CALLFN(call1073741824, 1073741824) |
279 | 384 |
280 // Return point when leaving stack. | 385 // Return point when leaving stack. |
281 TEXT runtime·lessstack(SB), 7, $0 | 386 // |
| 387 // Lessstack can appear in stack traces for the same reason |
| 388 // as morestack; in that context, it has 0 arguments. |
| 389 TEXT runtime·lessstack(SB), NOSPLIT, $0-0 |
282 // Save return value in m->cret | 390 // Save return value in m->cret |
283 get_tls(CX) | 391 get_tls(CX) |
284 MOVL m(CX), BX | 392 MOVL m(CX), BX |
285 MOVL AX, m_cret(BX) | 393 MOVL AX, m_cret(BX) |
286 | 394 |
287 // Call oldstack on m->g0's stack. | 395 // Call oldstack on m->g0's stack. |
288 MOVL m_g0(BX), BP | 396 MOVL m_g0(BX), BP |
289 MOVL BP, g(CX) | 397 MOVL BP, g(CX) |
290 MOVL (g_sched+gobuf_sp)(BP), SP | 398 MOVL (g_sched+gobuf_sp)(BP), SP |
291 CALL runtime·oldstack(SB) | 399 CALL runtime·oldstack(SB) |
292 MOVL $0, 0x1004 // crash if oldstack returns | 400 MOVL $0, 0x1004 // crash if oldstack returns |
293 RET | 401 RET |
294 | 402 |
295 | 403 |
296 // bool cas(int32 *val, int32 old, int32 new) | 404 // bool cas(int32 *val, int32 old, int32 new) |
297 // Atomically: | 405 // Atomically: |
298 // if(*val == old){ | 406 // if(*val == old){ |
299 // *val = new; | 407 // *val = new; |
300 // return 1; | 408 // return 1; |
301 // }else | 409 // }else |
302 // return 0; | 410 // return 0; |
303 TEXT runtime·cas(SB), 7, $0 | 411 TEXT runtime·cas(SB), NOSPLIT, $0-12 |
304 MOVL 4(SP), BX | 412 MOVL 4(SP), BX |
305 MOVL 8(SP), AX | 413 MOVL 8(SP), AX |
306 MOVL 12(SP), CX | 414 MOVL 12(SP), CX |
307 LOCK | 415 LOCK |
308 CMPXCHGL CX, 0(BX) | 416 CMPXCHGL CX, 0(BX) |
309 JZ 3(PC) | 417 JZ 3(PC) |
310 MOVL $0, AX | 418 MOVL $0, AX |
311 RET | 419 RET |
312 MOVL $1, AX | 420 MOVL $1, AX |
313 RET | 421 RET |
314 | 422 |
315 // bool runtime·cas64(uint64 *val, uint64 *old, uint64 new) | 423 // bool runtime·cas64(uint64 *val, uint64 old, uint64 new) |
316 // Atomically: | 424 // Atomically: |
317 // if(*val == *old){ | 425 // if(*val == *old){ |
318 // *val = new; | 426 // *val = new; |
319 // return 1; | 427 // return 1; |
320 // } else { | 428 // } else { |
321 // *old = *val | |
322 // return 0; | 429 // return 0; |
323 // } | 430 // } |
324 TEXT runtime·cas64(SB), 7, $0 | 431 TEXT runtime·cas64(SB), NOSPLIT, $0-20 |
325 MOVL 4(SP), BP | 432 MOVL 4(SP), BP |
326 » MOVL» 8(SP), SI | 433 » MOVL» 8(SP), AX |
327 » MOVL» 0(SI), AX | 434 » MOVL» 12(SP), DX |
328 » MOVL» 4(SI), DX | 435 » MOVL» 16(SP), BX |
329 » MOVL» 12(SP), BX | 436 » MOVL» 20(SP), CX |
330 » MOVL» 16(SP), CX | |
331 LOCK | 437 LOCK |
332 CMPXCHG8B 0(BP) | 438 CMPXCHG8B 0(BP) |
333 JNZ cas64_fail | 439 JNZ cas64_fail |
334 MOVL $1, AX | 440 MOVL $1, AX |
335 RET | 441 RET |
336 cas64_fail: | 442 cas64_fail: |
337 MOVL AX, 0(SI) | |
338 MOVL DX, 4(SI) | |
339 MOVL $0, AX | 443 MOVL $0, AX |
340 RET | 444 RET |
341 | 445 |
342 // bool casp(void **p, void *old, void *new) | 446 // bool casp(void **p, void *old, void *new) |
343 // Atomically: | 447 // Atomically: |
344 // if(*p == old){ | 448 // if(*p == old){ |
345 // *p = new; | 449 // *p = new; |
346 // return 1; | 450 // return 1; |
347 // }else | 451 // }else |
348 // return 0; | 452 // return 0; |
349 TEXT runtime·casp(SB), 7, $0 | 453 TEXT runtime·casp(SB), NOSPLIT, $0-12 |
350 MOVL 4(SP), BX | 454 MOVL 4(SP), BX |
351 MOVL 8(SP), AX | 455 MOVL 8(SP), AX |
352 MOVL 12(SP), CX | 456 MOVL 12(SP), CX |
353 LOCK | 457 LOCK |
354 CMPXCHGL CX, 0(BX) | 458 CMPXCHGL CX, 0(BX) |
355 JZ 3(PC) | 459 JZ 3(PC) |
356 MOVL $0, AX | 460 MOVL $0, AX |
357 RET | 461 RET |
358 MOVL $1, AX | 462 MOVL $1, AX |
359 RET | 463 RET |
360 | 464 |
361 // uint32 xadd(uint32 volatile *val, int32 delta) | 465 // uint32 xadd(uint32 volatile *val, int32 delta) |
362 // Atomically: | 466 // Atomically: |
363 // *val += delta; | 467 // *val += delta; |
364 // return *val; | 468 // return *val; |
365 TEXT runtime·xadd(SB), 7, $0 | 469 TEXT runtime·xadd(SB), NOSPLIT, $0-8 |
366 MOVL 4(SP), BX | 470 MOVL 4(SP), BX |
367 MOVL 8(SP), AX | 471 MOVL 8(SP), AX |
368 MOVL AX, CX | 472 MOVL AX, CX |
369 LOCK | 473 LOCK |
370 XADDL AX, 0(BX) | 474 XADDL AX, 0(BX) |
371 ADDL CX, AX | 475 ADDL CX, AX |
372 RET | 476 RET |
373 | 477 |
374 TEXT runtime·xchg(SB), 7, $0 | 478 TEXT runtime·xchg(SB), NOSPLIT, $0-8 |
375 MOVL 4(SP), BX | 479 MOVL 4(SP), BX |
376 MOVL 8(SP), AX | 480 MOVL 8(SP), AX |
377 XCHGL AX, 0(BX) | 481 XCHGL AX, 0(BX) |
378 RET | 482 RET |
379 | 483 |
380 TEXT runtime·procyield(SB),7,$0 | 484 TEXT runtime·procyield(SB),NOSPLIT,$0-0 |
381 MOVL 4(SP), AX | 485 MOVL 4(SP), AX |
382 again: | 486 again: |
383 PAUSE | 487 PAUSE |
384 SUBL $1, AX | 488 SUBL $1, AX |
385 JNZ again | 489 JNZ again |
386 RET | 490 RET |
387 | 491 |
388 TEXT runtime·atomicstorep(SB), 7, $0 | 492 TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8 |
389 MOVL 4(SP), BX | 493 MOVL 4(SP), BX |
390 MOVL 8(SP), AX | 494 MOVL 8(SP), AX |
391 XCHGL AX, 0(BX) | 495 XCHGL AX, 0(BX) |
392 RET | 496 RET |
393 | 497 |
394 TEXT runtime·atomicstore(SB), 7, $0 | 498 TEXT runtime·atomicstore(SB), NOSPLIT, $0-8 |
395 MOVL 4(SP), BX | 499 MOVL 4(SP), BX |
396 MOVL 8(SP), AX | 500 MOVL 8(SP), AX |
397 XCHGL AX, 0(BX) | 501 XCHGL AX, 0(BX) |
398 RET | 502 RET |
399 | 503 |
400 // uint64 atomicload64(uint64 volatile* addr); | 504 // uint64 atomicload64(uint64 volatile* addr); |
401 // so actually | 505 // so actually |
402 // void atomicload64(uint64 *res, uint64 volatile *addr); | 506 // void atomicload64(uint64 *res, uint64 volatile *addr); |
403 TEXT runtime·atomicload64(SB), 7, $0 | 507 TEXT runtime·atomicload64(SB), NOSPLIT, $0-8 |
404 » MOVL 4(SP), BX | 508 » MOVL» 4(SP), BX |
405 MOVL 8(SP), AX | 509 MOVL 8(SP), AX |
406 // MOVQ (%EAX), %MM0 | 510 // MOVQ (%EAX), %MM0 |
407 BYTE $0x0f; BYTE $0x6f; BYTE $0x00 | 511 BYTE $0x0f; BYTE $0x6f; BYTE $0x00 |
408 // MOVQ %MM0, 0(%EBX) | 512 // MOVQ %MM0, 0(%EBX) |
409 BYTE $0x0f; BYTE $0x7f; BYTE $0x03 | 513 BYTE $0x0f; BYTE $0x7f; BYTE $0x03 |
410 // EMMS | 514 // EMMS |
411 BYTE $0x0F; BYTE $0x77 | 515 BYTE $0x0F; BYTE $0x77 |
412 RET | 516 RET |
413 | 517 |
414 // void runtime·atomicstore64(uint64 volatile* addr, uint64 v); | 518 // void runtime·atomicstore64(uint64 volatile* addr, uint64 v); |
415 TEXT runtime·atomicstore64(SB), 7, $0 | 519 TEXT runtime·atomicstore64(SB), NOSPLIT, $0-12 |
416 MOVL 4(SP), AX | 520 MOVL 4(SP), AX |
417 // MOVQ and EMMS were introduced on the Pentium MMX. | 521 // MOVQ and EMMS were introduced on the Pentium MMX. |
418 // MOVQ 0x8(%ESP), %MM0 | 522 // MOVQ 0x8(%ESP), %MM0 |
419 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 | 523 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 |
420 // MOVQ %MM0, (%EAX) | 524 // MOVQ %MM0, (%EAX) |
421 BYTE $0x0f; BYTE $0x7f; BYTE $0x00· | 525 BYTE $0x0f; BYTE $0x7f; BYTE $0x00· |
422 // EMMS | 526 // EMMS |
423 BYTE $0x0F; BYTE $0x77 | 527 BYTE $0x0F; BYTE $0x77 |
424 // This is essentially a no-op, but it provides required memory fencing. | 528 // This is essentially a no-op, but it provides required memory fencing. |
425 // It can be replaced with MFENCE, but MFENCE was introduced only on the
Pentium4 (SSE2). | 529 // It can be replaced with MFENCE, but MFENCE was introduced only on the
Pentium4 (SSE2). |
426 MOVL $0, AX | 530 MOVL $0, AX |
427 LOCK | 531 LOCK |
428 XADDL AX, (SP) | 532 XADDL AX, (SP) |
429 RET | 533 RET |
430 | 534 |
431 // void jmpdefer(fn, sp); | 535 // void jmpdefer(fn, sp); |
432 // called from deferreturn. | 536 // called from deferreturn. |
433 // 1. pop the caller | 537 // 1. pop the caller |
434 // 2. sub 5 bytes from the callers return | 538 // 2. sub 5 bytes from the callers return |
435 // 3. jmp to the argument | 539 // 3. jmp to the argument |
436 TEXT runtime·jmpdefer(SB), 7, $0 | 540 TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8 |
437 MOVL 4(SP), DX // fn | 541 MOVL 4(SP), DX // fn |
438 MOVL 8(SP), BX // caller sp | 542 MOVL 8(SP), BX // caller sp |
439 LEAL -4(BX), SP // caller sp after CALL | 543 LEAL -4(BX), SP // caller sp after CALL |
440 SUBL $5, (SP) // return to CALL again | 544 SUBL $5, (SP) // return to CALL again |
441 MOVL 0(DX), BX | 545 MOVL 0(DX), BX |
442 JMP BX // but first run the deferred function | 546 JMP BX // but first run the deferred function |
443 | 547 |
444 // Save state of caller into g->sched. | 548 // Save state of caller into g->sched. |
445 TEXT gosave<>(SB),7,$0 | 549 TEXT gosave<>(SB),NOSPLIT,$0 |
446 PUSHL AX | 550 PUSHL AX |
447 PUSHL BX | 551 PUSHL BX |
448 get_tls(BX) | 552 get_tls(BX) |
449 MOVL g(BX), BX | 553 MOVL g(BX), BX |
450 LEAL arg+0(FP), AX | 554 LEAL arg+0(FP), AX |
451 MOVL AX, (g_sched+gobuf_sp)(BX) | 555 MOVL AX, (g_sched+gobuf_sp)(BX) |
452 MOVL -4(AX), AX | 556 MOVL -4(AX), AX |
453 MOVL AX, (g_sched+gobuf_pc)(BX) | 557 MOVL AX, (g_sched+gobuf_pc)(BX) |
454 MOVL $0, (g_sched+gobuf_ret)(BX) | 558 MOVL $0, (g_sched+gobuf_ret)(BX) |
455 MOVL $0, (g_sched+gobuf_ctxt)(BX) | 559 MOVL $0, (g_sched+gobuf_ctxt)(BX) |
456 POPL BX | 560 POPL BX |
457 POPL AX | 561 POPL AX |
458 RET | 562 RET |
459 | 563 |
460 // asmcgocall(void(*fn)(void*), void *arg) | 564 // asmcgocall(void(*fn)(void*), void *arg) |
461 // Call fn(arg) on the scheduler stack, | 565 // Call fn(arg) on the scheduler stack, |
462 // aligned appropriately for the gcc ABI. | 566 // aligned appropriately for the gcc ABI. |
463 // See cgocall.c for more details. | 567 // See cgocall.c for more details. |
464 TEXT runtime·asmcgocall(SB),7,$0 | 568 TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8 |
465 MOVL fn+0(FP), AX | 569 MOVL fn+0(FP), AX |
466 MOVL arg+4(FP), BX | 570 MOVL arg+4(FP), BX |
467 MOVL SP, DX | 571 MOVL SP, DX |
468 | 572 |
469 // Figure out if we need to switch to m->g0 stack. | 573 // Figure out if we need to switch to m->g0 stack. |
470 // We get called to create new OS threads too, and those | 574 // We get called to create new OS threads too, and those |
471 // come in on the m->g0 stack already. | 575 // come in on the m->g0 stack already. |
472 get_tls(CX) | 576 get_tls(CX) |
473 MOVL m(CX), BP | 577 MOVL m(CX), BP |
474 MOVL m_g0(BP), SI | 578 MOVL m_g0(BP), SI |
(...skipping 15 matching lines...) Expand all Loading... |
490 // Restore registers, g, stack pointer. | 594 // Restore registers, g, stack pointer. |
491 get_tls(CX) | 595 get_tls(CX) |
492 MOVL 8(SP), DI | 596 MOVL 8(SP), DI |
493 MOVL DI, g(CX) | 597 MOVL DI, g(CX) |
494 MOVL 4(SP), SP | 598 MOVL 4(SP), SP |
495 RET | 599 RET |
496 | 600 |
497 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) | 601 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) |
498 // Turn the fn into a Go func (by taking its address) and call | 602 // Turn the fn into a Go func (by taking its address) and call |
499 // cgocallback_gofunc. | 603 // cgocallback_gofunc. |
500 TEXT runtime·cgocallback(SB),7,$12 | 604 TEXT runtime·cgocallback(SB),NOSPLIT,$12-12 |
501 LEAL fn+0(FP), AX | 605 LEAL fn+0(FP), AX |
502 MOVL AX, 0(SP) | 606 MOVL AX, 0(SP) |
503 MOVL frame+4(FP), AX | 607 MOVL frame+4(FP), AX |
504 MOVL AX, 4(SP) | 608 MOVL AX, 4(SP) |
505 MOVL framesize+8(FP), AX | 609 MOVL framesize+8(FP), AX |
506 MOVL AX, 8(SP) | 610 MOVL AX, 8(SP) |
507 MOVL $runtime·cgocallback_gofunc(SB), AX | 611 MOVL $runtime·cgocallback_gofunc(SB), AX |
508 CALL AX | 612 CALL AX |
509 RET | 613 RET |
510 | 614 |
511 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) | 615 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) |
512 // See cgocall.c for more details. | 616 // See cgocall.c for more details. |
513 TEXT runtime·cgocallback_gofunc(SB),7,$12 | 617 TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12 |
514 // If m is nil, Go did not create the current thread. | 618 // If m is nil, Go did not create the current thread. |
515 // Call needm to obtain one for temporary use. | 619 // Call needm to obtain one for temporary use. |
516 // In this case, we're running on the thread stack, so there's | 620 // In this case, we're running on the thread stack, so there's |
517 // lots of space, but the linker doesn't know. Hide the call from | 621 // lots of space, but the linker doesn't know. Hide the call from |
518 // the linker analysis by using an indirect call through AX. | 622 // the linker analysis by using an indirect call through AX. |
519 get_tls(CX) | 623 get_tls(CX) |
520 #ifdef GOOS_windows | 624 #ifdef GOOS_windows |
| 625 MOVL $0, BP |
521 CMPL CX, $0 | 626 CMPL CX, $0 |
522 » JNE» 3(PC) | 627 » JEQ» 2(PC) |
523 » PUSHL» $0 | |
524 » JMP needm | |
525 #endif | 628 #endif |
526 MOVL m(CX), BP | 629 MOVL m(CX), BP |
527 » PUSHL» BP | 630 » MOVL» BP, DX // saved copy of oldm |
528 CMPL BP, $0 | 631 CMPL BP, $0 |
529 JNE havem | 632 JNE havem |
530 needm: | 633 needm: |
| 634 MOVL DX, 0(SP) |
531 MOVL $runtime·needm(SB), AX | 635 MOVL $runtime·needm(SB), AX |
532 CALL AX | 636 CALL AX |
| 637 MOVL 0(SP), DX |
533 get_tls(CX) | 638 get_tls(CX) |
534 MOVL m(CX), BP | 639 MOVL m(CX), BP |
535 | 640 |
536 havem: | 641 havem: |
537 // Now there's a valid m, and we're running on its m->g0. | 642 // Now there's a valid m, and we're running on its m->g0. |
538 // Save current m->g0->sched.sp on stack and then set it to SP. | 643 // Save current m->g0->sched.sp on stack and then set it to SP. |
539 // Save current sp in m->g0->sched.sp in preparation for | 644 // Save current sp in m->g0->sched.sp in preparation for |
540 // switch back to m->curg stack. | 645 // switch back to m->curg stack. |
| 646 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP). |
| 647 // On Windows, the SEH is at 4(SP) and 8(SP). |
541 MOVL m_g0(BP), SI | 648 MOVL m_g0(BP), SI |
542 » PUSHL» (g_sched+gobuf_sp)(SI) | 649 » MOVL» (g_sched+gobuf_sp)(SI), AX |
| 650 » MOVL» AX, 0(SP) |
543 MOVL SP, (g_sched+gobuf_sp)(SI) | 651 MOVL SP, (g_sched+gobuf_sp)(SI) |
544 | 652 |
545 » // Switch to m->curg stack and call runtime.cgocallbackg | 653 » // Switch to m->curg stack and call runtime.cgocallbackg. |
546 » // with the three arguments. Because we are taking over | 654 » // Because we are taking over the execution of m->curg |
547 » // the execution of m->curg but *not* resuming what had | 655 » // but *not* resuming what had been running, we need to |
548 » // been running, we need to save that information (m->curg->sched) | 656 » // save that information (m->curg->sched) so we can restore it. |
549 » // so that we can restore it when we're done. | |
550 // We can restore m->curg->sched.sp easily, because calling | 657 // We can restore m->curg->sched.sp easily, because calling |
551 // runtime.cgocallbackg leaves SP unchanged upon return. | 658 // runtime.cgocallbackg leaves SP unchanged upon return. |
552 // To save m->curg->sched.pc, we push it onto the stack. | 659 // To save m->curg->sched.pc, we push it onto the stack. |
553 // This has the added benefit that it looks to the traceback | 660 // This has the added benefit that it looks to the traceback |
554 // routine like cgocallbackg is going to return to that | 661 // routine like cgocallbackg is going to return to that |
555 » // PC (because we defined cgocallbackg to have | 662 » // PC (because the frame we allocate below has the same |
556 » // a frame size of 12, the same amount that we use below), | 663 » // size as cgocallback_gofunc's frame declared above) |
557 // so that the traceback will seamlessly trace back into | 664 // so that the traceback will seamlessly trace back into |
558 // the earlier calls. | 665 // the earlier calls. |
559 » MOVL» fn+0(FP), AX | 666 » // |
560 » MOVL» frame+4(FP), BX | 667 » // In the new goroutine, 0(SP) holds the saved oldm (DX) register. |
561 » MOVL» framesize+8(FP), DX | 668 » // 4(SP) and 8(SP) are unused. |
562 | |
563 MOVL m_curg(BP), SI | 669 MOVL m_curg(BP), SI |
564 MOVL SI, g(CX) | 670 MOVL SI, g(CX) |
565 » MOVL» (g_sched+gobuf_sp)(SI), DI // prepare stack as DI | 671 » MOVL» (g_sched+gobuf_sp)(SI), DI // prepare stack as DI |
566 | |
567 » // Push gobuf.pc | |
568 MOVL (g_sched+gobuf_pc)(SI), BP | 672 MOVL (g_sched+gobuf_pc)(SI), BP |
569 » SUBL» $4, DI | 673 » MOVL» BP, -4(DI) |
570 » MOVL» BP, 0(DI) | 674 » LEAL» -(4+12)(DI), SP |
571 | 675 » MOVL» DX, 0(SP) |
572 » // Push arguments to cgocallbackg. | |
573 » // Frame size here must match the frame size above | |
574 » // to trick traceback routines into doing the right thing. | |
575 » SUBL» $12, DI | |
576 » MOVL» AX, 0(DI) | |
577 » MOVL» BX, 4(DI) | |
578 » MOVL» DX, 8(DI) | |
579 »······· | |
580 » // Switch stack and make the call. | |
581 » MOVL» DI, SP | |
582 CALL runtime·cgocallbackg(SB) | 676 CALL runtime·cgocallbackg(SB) |
| 677 MOVL 0(SP), DX |
583 | 678 |
584 // Restore g->sched (== m->curg->sched) from saved values. | 679 // Restore g->sched (== m->curg->sched) from saved values. |
585 get_tls(CX) | 680 get_tls(CX) |
586 MOVL g(CX), SI | 681 MOVL g(CX), SI |
587 MOVL 12(SP), BP | 682 MOVL 12(SP), BP |
588 MOVL BP, (g_sched+gobuf_pc)(SI) | 683 MOVL BP, (g_sched+gobuf_pc)(SI) |
589 LEAL (12+4)(SP), DI | 684 LEAL (12+4)(SP), DI |
590 MOVL DI, (g_sched+gobuf_sp)(SI) | 685 MOVL DI, (g_sched+gobuf_sp)(SI) |
591 | 686 |
592 // Switch back to m->g0's stack and restore m->g0->sched.sp. | 687 // Switch back to m->g0's stack and restore m->g0->sched.sp. |
593 // (Unlike m->curg, the g0 goroutine never uses sched.pc, | 688 // (Unlike m->curg, the g0 goroutine never uses sched.pc, |
594 // so we do not have to restore it.) | 689 // so we do not have to restore it.) |
595 MOVL m(CX), BP | 690 MOVL m(CX), BP |
596 MOVL m_g0(BP), SI | 691 MOVL m_g0(BP), SI |
597 MOVL SI, g(CX) | 692 MOVL SI, g(CX) |
598 MOVL (g_sched+gobuf_sp)(SI), SP | 693 MOVL (g_sched+gobuf_sp)(SI), SP |
599 » POPL» (g_sched+gobuf_sp)(SI) | 694 » MOVL» 0(SP), AX |
| 695 » MOVL» AX, (g_sched+gobuf_sp)(SI) |
600 ········ | 696 ········ |
601 // If the m on entry was nil, we called needm above to borrow an m | 697 // If the m on entry was nil, we called needm above to borrow an m |
602 // for the duration of the call. Since the call is over, return it with
dropm. | 698 // for the duration of the call. Since the call is over, return it with
dropm. |
603 » POPL» BP | 699 » CMPL» DX, $0 |
604 » CMPL» BP, $0 | |
605 JNE 3(PC) | 700 JNE 3(PC) |
606 MOVL $runtime·dropm(SB), AX | 701 MOVL $runtime·dropm(SB), AX |
607 CALL AX | 702 CALL AX |
608 | 703 |
609 // Done! | 704 // Done! |
610 RET | 705 RET |
611 | 706 |
612 // void setmg(M*, G*); set m and g. for use by needm. | 707 // void setmg(M*, G*); set m and g. for use by needm. |
613 TEXT runtime·setmg(SB), 7, $0 | 708 TEXT runtime·setmg(SB), NOSPLIT, $0-8 |
614 #ifdef GOOS_windows | 709 #ifdef GOOS_windows |
615 MOVL mm+0(FP), AX | 710 MOVL mm+0(FP), AX |
616 CMPL AX, $0 | 711 CMPL AX, $0 |
617 JNE settls | 712 JNE settls |
618 MOVL $0, 0x14(FS) | 713 MOVL $0, 0x14(FS) |
619 RET | 714 RET |
620 settls: | 715 settls: |
621 LEAL m_tls(AX), AX | 716 LEAL m_tls(AX), AX |
622 MOVL AX, 0x14(FS) | 717 MOVL AX, 0x14(FS) |
623 #endif | 718 #endif |
624 MOVL mm+0(FP), AX | 719 MOVL mm+0(FP), AX |
625 get_tls(CX) | 720 get_tls(CX) |
626 MOVL mm+0(FP), AX | 721 MOVL mm+0(FP), AX |
627 MOVL AX, m(CX) | 722 MOVL AX, m(CX) |
628 MOVL gg+4(FP), BX | 723 MOVL gg+4(FP), BX |
629 MOVL BX, g(CX) | 724 MOVL BX, g(CX) |
630 RET | 725 RET |
631 | 726 |
632 // void setmg_gcc(M*, G*); set m and g. for use by gcc | 727 // void setmg_gcc(M*, G*); set m and g. for use by gcc |
633 TEXT setmg_gcc<>(SB), 7, $0» | 728 TEXT setmg_gcc<>(SB), NOSPLIT, $0 |
634 get_tls(AX) | 729 get_tls(AX) |
635 MOVL mm+0(FP), DX | 730 MOVL mm+0(FP), DX |
636 MOVL DX, m(AX) | 731 MOVL DX, m(AX) |
637 MOVL gg+4(FP), DX | 732 MOVL gg+4(FP), DX |
638 MOVL DX,g (AX) | 733 MOVL DX,g (AX) |
639 RET | 734 RET |
640 | 735 |
641 // check that SP is in range [g->stackbase, g->stackguard) | 736 // check that SP is in range [g->stackbase, g->stackguard) |
642 TEXT runtime·stackcheck(SB), 7, $0 | 737 TEXT runtime·stackcheck(SB), NOSPLIT, $0-0 |
643 get_tls(CX) | 738 get_tls(CX) |
644 MOVL g(CX), AX | 739 MOVL g(CX), AX |
645 CMPL g_stackbase(AX), SP | 740 CMPL g_stackbase(AX), SP |
646 JHI 2(PC) | 741 JHI 2(PC) |
647 INT $3 | 742 INT $3 |
648 CMPL SP, g_stackguard(AX) | 743 CMPL SP, g_stackguard(AX) |
649 JHI 2(PC) | 744 JHI 2(PC) |
650 INT $3 | 745 INT $3 |
651 RET | 746 RET |
652 | 747 |
653 TEXT runtime·memclr(SB),7,$0 | 748 TEXT runtime·memclr(SB),NOSPLIT,$0-8 |
654 MOVL 4(SP), DI // arg 1 addr | 749 MOVL 4(SP), DI // arg 1 addr |
655 MOVL 8(SP), CX // arg 2 count | 750 MOVL 8(SP), CX // arg 2 count |
656 MOVL CX, BX | 751 MOVL CX, BX |
657 ANDL $3, BX | 752 ANDL $3, BX |
658 SHRL $2, CX | 753 SHRL $2, CX |
659 MOVL $0, AX | 754 MOVL $0, AX |
660 CLD | 755 CLD |
661 REP | 756 REP |
662 STOSL | 757 STOSL |
663 MOVL BX, CX | 758 MOVL BX, CX |
664 REP | 759 REP |
665 STOSB | 760 STOSB |
666 RET | 761 RET |
667 | 762 |
668 TEXT runtime·getcallerpc(SB),7,$0 | 763 TEXT runtime·getcallerpc(SB),NOSPLIT,$0-4 |
669 MOVL x+0(FP),AX // addr of first arg | 764 MOVL x+0(FP),AX // addr of first arg |
670 MOVL -4(AX),AX // get calling pc | 765 MOVL -4(AX),AX // get calling pc |
671 RET | 766 RET |
672 | 767 |
673 TEXT runtime·setcallerpc(SB),7,$0 | 768 TEXT runtime·setcallerpc(SB),NOSPLIT,$0-8 |
674 MOVL x+0(FP),AX // addr of first arg | 769 MOVL x+0(FP),AX // addr of first arg |
675 MOVL x+4(FP), BX | 770 MOVL x+4(FP), BX |
676 MOVL BX, -4(AX) // set calling pc | 771 MOVL BX, -4(AX) // set calling pc |
677 RET | 772 RET |
678 | 773 |
679 TEXT runtime·getcallersp(SB), 7, $0 | 774 TEXT runtime·getcallersp(SB), NOSPLIT, $0-4 |
680 MOVL sp+0(FP), AX | 775 MOVL sp+0(FP), AX |
681 RET | 776 RET |
682 | 777 |
683 // int64 runtime·cputicks(void), so really | 778 // int64 runtime·cputicks(void), so really |
684 // void runtime·cputicks(int64 *ticks) | 779 // void runtime·cputicks(int64 *ticks) |
685 TEXT runtime·cputicks(SB),7,$0 | 780 TEXT runtime·cputicks(SB),NOSPLIT,$0-4 |
686 RDTSC | 781 RDTSC |
687 MOVL ret+0(FP), DI | 782 MOVL ret+0(FP), DI |
688 MOVL AX, 0(DI) | 783 MOVL AX, 0(DI) |
689 MOVL DX, 4(DI) | 784 MOVL DX, 4(DI) |
690 RET | 785 RET |
691 | 786 |
692 TEXT runtime·ldt0setup(SB),7,$16 | 787 TEXT runtime·ldt0setup(SB),NOSPLIT,$16-0 |
693 // set up ldt 7 to point at tls0 | 788 // set up ldt 7 to point at tls0 |
694 // ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go. | 789 // ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go. |
695 // the entry number is just a hint. setldt will set up GS with what it
used. | 790 // the entry number is just a hint. setldt will set up GS with what it
used. |
696 MOVL $7, 0(SP) | 791 MOVL $7, 0(SP) |
697 LEAL runtime·tls0(SB), AX | 792 LEAL runtime·tls0(SB), AX |
698 MOVL AX, 4(SP) | 793 MOVL AX, 4(SP) |
699 MOVL $32, 8(SP) // sizeof(tls array) | 794 MOVL $32, 8(SP) // sizeof(tls array) |
700 CALL runtime·setldt(SB) | 795 CALL runtime·setldt(SB) |
701 RET | 796 RET |
702 | 797 |
703 TEXT runtime·emptyfunc(SB),0,$0 | 798 TEXT runtime·emptyfunc(SB),0,$0-0 |
704 » RET | 799 » RET |
705 | 800 |
706 TEXT runtime·abort(SB),7,$0 | 801 TEXT runtime·abort(SB),NOSPLIT,$0-0 |
707 INT $0x3 | 802 INT $0x3 |
708 | 803 |
709 TEXT runtime·stackguard(SB),7,$0 | 804 TEXT runtime·stackguard(SB),NOSPLIT,$0-8 |
710 MOVL SP, DX | 805 MOVL SP, DX |
711 MOVL DX, sp+0(FP) | 806 MOVL DX, sp+0(FP) |
712 get_tls(CX) | 807 get_tls(CX) |
713 MOVL g(CX), BX | 808 MOVL g(CX), BX |
714 MOVL g_stackguard(BX), DX | 809 MOVL g_stackguard(BX), DX |
715 MOVL DX, limit+4(FP) | 810 MOVL DX, limit+4(FP) |
716 RET | 811 RET |
717 | 812 |
718 GLOBL runtime·tls0(SB), $32 | 813 GLOBL runtime·tls0(SB), $32 |
719 | 814 |
720 // hash function using AES hardware instructions | 815 // hash function using AES hardware instructions |
721 TEXT runtime·aeshash(SB),7,$0 | 816 TEXT runtime·aeshash(SB),NOSPLIT,$0-12 |
722 MOVL 4(SP), DX // ptr to hash value | 817 MOVL 4(SP), DX // ptr to hash value |
723 MOVL 8(SP), CX // size | 818 MOVL 8(SP), CX // size |
724 MOVL 12(SP), AX // ptr to data | 819 MOVL 12(SP), AX // ptr to data |
725 JMP runtime·aeshashbody(SB) | 820 JMP runtime·aeshashbody(SB) |
726 | 821 |
727 TEXT runtime·aeshashstr(SB),7,$0 | 822 TEXT runtime·aeshashstr(SB),NOSPLIT,$0-12 |
728 MOVL 4(SP), DX // ptr to hash value | 823 MOVL 4(SP), DX // ptr to hash value |
729 MOVL 12(SP), AX // ptr to string struct | 824 MOVL 12(SP), AX // ptr to string struct |
730 MOVL 4(AX), CX // length of string | 825 MOVL 4(AX), CX // length of string |
731 MOVL (AX), AX // string data | 826 MOVL (AX), AX // string data |
732 JMP runtime·aeshashbody(SB) | 827 JMP runtime·aeshashbody(SB) |
733 | 828 |
734 // AX: data | 829 // AX: data |
735 // CX: length | 830 // CX: length |
736 // DX: ptr to seed input / hash output | 831 // DX: ptr to seed input / hash output |
737 TEXT runtime·aeshashbody(SB),7,$0 | 832 TEXT runtime·aeshashbody(SB),NOSPLIT,$0-12 |
738 MOVL (DX), X0 // seed to low 32 bits of xmm0 | 833 MOVL (DX), X0 // seed to low 32 bits of xmm0 |
739 PINSRD $1, CX, X0 // size to next 32 bits of xmm0 | 834 PINSRD $1, CX, X0 // size to next 32 bits of xmm0 |
740 MOVO runtime·aeskeysched+0(SB), X2 | 835 MOVO runtime·aeskeysched+0(SB), X2 |
741 MOVO runtime·aeskeysched+16(SB), X3 | 836 MOVO runtime·aeskeysched+16(SB), X3 |
742 CMPL CX, $16 | 837 CMPL CX, $16 |
743 JB aessmall | 838 JB aessmall |
744 aesloop: | 839 aesloop: |
745 CMPL CX, $16 | 840 CMPL CX, $16 |
746 JBE aesloopend | 841 JBE aesloopend |
747 MOVOU (AX), X1 | 842 MOVOU (AX), X1 |
(...skipping 13 matching lines...) Expand all Loading... |
761 TESTL CX, CX | 856 TESTL CX, CX |
762 JE finalize // 0 bytes | 857 JE finalize // 0 bytes |
763 | 858 |
764 CMPB AX, $0xf0 | 859 CMPB AX, $0xf0 |
765 JA highpartial | 860 JA highpartial |
766 | 861 |
767 // 16 bytes loaded at this address won't cross | 862 // 16 bytes loaded at this address won't cross |
768 // a page boundary, so we can load it directly. | 863 // a page boundary, so we can load it directly. |
769 MOVOU (AX), X1 | 864 MOVOU (AX), X1 |
770 ADDL CX, CX | 865 ADDL CX, CX |
771 » PAND» masks(SB)(CX*8), X1 | 866 » PAND» masks<>(SB)(CX*8), X1 |
772 JMP partial | 867 JMP partial |
773 highpartial: | 868 highpartial: |
774 // address ends in 1111xxxx. Might be up against | 869 // address ends in 1111xxxx. Might be up against |
775 // a page boundary, so load ending at last byte. | 870 // a page boundary, so load ending at last byte. |
776 // Then shift bytes down using pshufb. | 871 // Then shift bytes down using pshufb. |
777 MOVOU -16(AX)(CX*1), X1 | 872 MOVOU -16(AX)(CX*1), X1 |
778 ADDL CX, CX | 873 ADDL CX, CX |
779 » PSHUFB» shifts(SB)(CX*8), X1 | 874 » PSHUFB» shifts<>(SB)(CX*8), X1 |
780 partial: | 875 partial: |
781 // incorporate partial block into hash | 876 // incorporate partial block into hash |
782 AESENC X3, X0 | 877 AESENC X3, X0 |
783 AESENC X1, X0 | 878 AESENC X1, X0 |
784 finalize:······· | 879 finalize:······· |
785 // finalize hash | 880 // finalize hash |
786 AESENC X2, X0 | 881 AESENC X2, X0 |
787 AESENC X3, X0 | 882 AESENC X3, X0 |
788 AESENC X2, X0 | 883 AESENC X2, X0 |
789 MOVL X0, (DX) | 884 MOVL X0, (DX) |
790 RET | 885 RET |
791 | 886 |
792 TEXT runtime·aeshash32(SB),7,$0 | 887 TEXT runtime·aeshash32(SB),NOSPLIT,$0-12 |
793 MOVL 4(SP), DX // ptr to hash value | 888 MOVL 4(SP), DX // ptr to hash value |
794 MOVL 12(SP), AX // ptr to data | 889 MOVL 12(SP), AX // ptr to data |
795 MOVL (DX), X0 // seed | 890 MOVL (DX), X0 // seed |
796 PINSRD $1, (AX), X0 // data | 891 PINSRD $1, (AX), X0 // data |
797 AESENC runtime·aeskeysched+0(SB), X0 | 892 AESENC runtime·aeskeysched+0(SB), X0 |
798 AESENC runtime·aeskeysched+16(SB), X0 | 893 AESENC runtime·aeskeysched+16(SB), X0 |
799 AESENC runtime·aeskeysched+0(SB), X0 | 894 AESENC runtime·aeskeysched+0(SB), X0 |
800 MOVL X0, (DX) | 895 MOVL X0, (DX) |
801 RET | 896 RET |
802 | 897 |
803 TEXT runtime·aeshash64(SB),7,$0 | 898 TEXT runtime·aeshash64(SB),NOSPLIT,$0-12 |
804 MOVL 4(SP), DX // ptr to hash value | 899 MOVL 4(SP), DX // ptr to hash value |
805 MOVL 12(SP), AX // ptr to data | 900 MOVL 12(SP), AX // ptr to data |
806 MOVQ (AX), X0 // data | 901 MOVQ (AX), X0 // data |
807 PINSRD $2, (DX), X0 // seed | 902 PINSRD $2, (DX), X0 // seed |
808 AESENC runtime·aeskeysched+0(SB), X0 | 903 AESENC runtime·aeskeysched+0(SB), X0 |
809 AESENC runtime·aeskeysched+16(SB), X0 | 904 AESENC runtime·aeskeysched+16(SB), X0 |
810 AESENC runtime·aeskeysched+0(SB), X0 | 905 AESENC runtime·aeskeysched+0(SB), X0 |
811 MOVL X0, (DX) | 906 MOVL X0, (DX) |
812 RET | 907 RET |
813 | 908 |
814 | |
815 // simple mask to get rid of data in the high part of the register. | 909 // simple mask to get rid of data in the high part of the register. |
816 TEXT masks(SB),7,$0 | 910 DATA masks<>+0x00(SB)/4, $0x00000000 |
817 » LONG $0x00000000 | 911 DATA masks<>+0x04(SB)/4, $0x00000000 |
818 » LONG $0x00000000 | 912 DATA masks<>+0x08(SB)/4, $0x00000000 |
819 » LONG $0x00000000 | 913 DATA masks<>+0x0c(SB)/4, $0x00000000 |
820 » LONG $0x00000000 | 914 »······· |
821 »······· | 915 DATA masks<>+0x10(SB)/4, $0x000000ff |
822 » LONG $0x000000ff | 916 DATA masks<>+0x14(SB)/4, $0x00000000 |
823 » LONG $0x00000000 | 917 DATA masks<>+0x18(SB)/4, $0x00000000 |
824 » LONG $0x00000000 | 918 DATA masks<>+0x1c(SB)/4, $0x00000000 |
825 » LONG $0x00000000 | 919 »······· |
826 »······· | 920 DATA masks<>+0x20(SB)/4, $0x0000ffff |
827 » LONG $0x0000ffff | 921 DATA masks<>+0x24(SB)/4, $0x00000000 |
828 » LONG $0x00000000 | 922 DATA masks<>+0x28(SB)/4, $0x00000000 |
829 » LONG $0x00000000 | 923 DATA masks<>+0x2c(SB)/4, $0x00000000 |
830 » LONG $0x00000000 | 924 »······· |
831 »······· | 925 DATA masks<>+0x30(SB)/4, $0x00ffffff |
832 » LONG $0x00ffffff | 926 DATA masks<>+0x34(SB)/4, $0x00000000 |
833 » LONG $0x00000000 | 927 DATA masks<>+0x38(SB)/4, $0x00000000 |
834 » LONG $0x00000000 | 928 DATA masks<>+0x3c(SB)/4, $0x00000000 |
835 » LONG $0x00000000 | 929 »······· |
836 »······· | 930 DATA masks<>+0x40(SB)/4, $0xffffffff |
837 » LONG $0xffffffff | 931 DATA masks<>+0x44(SB)/4, $0x00000000 |
838 » LONG $0x00000000 | 932 DATA masks<>+0x48(SB)/4, $0x00000000 |
839 » LONG $0x00000000 | 933 DATA masks<>+0x4c(SB)/4, $0x00000000 |
840 » LONG $0x00000000 | 934 »······· |
841 »······· | 935 DATA masks<>+0x50(SB)/4, $0xffffffff |
842 » LONG $0xffffffff | 936 DATA masks<>+0x54(SB)/4, $0x000000ff |
843 » LONG $0x000000ff | 937 DATA masks<>+0x58(SB)/4, $0x00000000 |
844 » LONG $0x00000000 | 938 DATA masks<>+0x5c(SB)/4, $0x00000000 |
845 » LONG $0x00000000 | 939 »······· |
846 »······· | 940 DATA masks<>+0x60(SB)/4, $0xffffffff |
847 » LONG $0xffffffff | 941 DATA masks<>+0x64(SB)/4, $0x0000ffff |
848 » LONG $0x0000ffff | 942 DATA masks<>+0x68(SB)/4, $0x00000000 |
849 » LONG $0x00000000 | 943 DATA masks<>+0x6c(SB)/4, $0x00000000 |
850 » LONG $0x00000000 | 944 »······· |
851 »······· | 945 DATA masks<>+0x70(SB)/4, $0xffffffff |
852 » LONG $0xffffffff | 946 DATA masks<>+0x74(SB)/4, $0x00ffffff |
853 » LONG $0x00ffffff | 947 DATA masks<>+0x78(SB)/4, $0x00000000 |
854 » LONG $0x00000000 | 948 DATA masks<>+0x7c(SB)/4, $0x00000000 |
855 » LONG $0x00000000 | 949 »······· |
856 »······· | 950 DATA masks<>+0x80(SB)/4, $0xffffffff |
857 » LONG $0xffffffff | 951 DATA masks<>+0x84(SB)/4, $0xffffffff |
858 » LONG $0xffffffff | 952 DATA masks<>+0x88(SB)/4, $0x00000000 |
859 » LONG $0x00000000 | 953 DATA masks<>+0x8c(SB)/4, $0x00000000 |
860 » LONG $0x00000000 | 954 »······· |
861 »······· | 955 DATA masks<>+0x90(SB)/4, $0xffffffff |
862 » LONG $0xffffffff | 956 DATA masks<>+0x94(SB)/4, $0xffffffff |
863 » LONG $0xffffffff | 957 DATA masks<>+0x98(SB)/4, $0x000000ff |
864 » LONG $0x000000ff | 958 DATA masks<>+0x9c(SB)/4, $0x00000000 |
865 » LONG $0x00000000 | 959 »······· |
866 »······· | 960 DATA masks<>+0xa0(SB)/4, $0xffffffff |
867 » LONG $0xffffffff | 961 DATA masks<>+0xa4(SB)/4, $0xffffffff |
868 » LONG $0xffffffff | 962 DATA masks<>+0xa8(SB)/4, $0x0000ffff |
869 » LONG $0x0000ffff | 963 DATA masks<>+0xac(SB)/4, $0x00000000 |
870 » LONG $0x00000000 | 964 »······· |
871 »······· | 965 DATA masks<>+0xb0(SB)/4, $0xffffffff |
872 » LONG $0xffffffff | 966 DATA masks<>+0xb4(SB)/4, $0xffffffff |
873 » LONG $0xffffffff | 967 DATA masks<>+0xb8(SB)/4, $0x00ffffff |
874 » LONG $0x00ffffff | 968 DATA masks<>+0xbc(SB)/4, $0x00000000 |
875 » LONG $0x00000000 | 969 »······· |
876 »······· | 970 DATA masks<>+0xc0(SB)/4, $0xffffffff |
877 » LONG $0xffffffff | 971 DATA masks<>+0xc4(SB)/4, $0xffffffff |
878 » LONG $0xffffffff | 972 DATA masks<>+0xc8(SB)/4, $0xffffffff |
879 » LONG $0xffffffff | 973 DATA masks<>+0xcc(SB)/4, $0x00000000 |
880 » LONG $0x00000000 | 974 »······· |
881 »······· | 975 DATA masks<>+0xd0(SB)/4, $0xffffffff |
882 » LONG $0xffffffff | 976 DATA masks<>+0xd4(SB)/4, $0xffffffff |
883 » LONG $0xffffffff | 977 DATA masks<>+0xd8(SB)/4, $0xffffffff |
884 » LONG $0xffffffff | 978 DATA masks<>+0xdc(SB)/4, $0x000000ff |
885 » LONG $0x000000ff | 979 »······· |
886 »······· | 980 DATA masks<>+0xe0(SB)/4, $0xffffffff |
887 » LONG $0xffffffff | 981 DATA masks<>+0xe4(SB)/4, $0xffffffff |
888 » LONG $0xffffffff | 982 DATA masks<>+0xe8(SB)/4, $0xffffffff |
889 » LONG $0xffffffff | 983 DATA masks<>+0xec(SB)/4, $0x0000ffff |
890 » LONG $0x0000ffff | 984 »······· |
891 »······· | 985 DATA masks<>+0xf0(SB)/4, $0xffffffff |
892 » LONG $0xffffffff | 986 DATA masks<>+0xf4(SB)/4, $0xffffffff |
893 » LONG $0xffffffff | 987 DATA masks<>+0xf8(SB)/4, $0xffffffff |
894 » LONG $0xffffffff | 988 DATA masks<>+0xfc(SB)/4, $0x00ffffff |
895 » LONG $0x00ffffff | 989 |
896 | 990 GLOBL masks<>(SB),RODATA,$256 |
897 » // these are arguments to pshufb. They move data down from | 991 |
898 » // the high bytes of the register to the low bytes of the register. | 992 // these are arguments to pshufb. They move data down from |
899 » // index is how many bytes to move. | 993 // the high bytes of the register to the low bytes of the register. |
900 TEXT shifts(SB),7,$0 | 994 // index is how many bytes to move. |
901 » LONG $0x00000000 | 995 DATA shifts<>+0x00(SB)/4, $0x00000000 |
902 » LONG $0x00000000 | 996 DATA shifts<>+0x04(SB)/4, $0x00000000 |
903 » LONG $0x00000000 | 997 DATA shifts<>+0x08(SB)/4, $0x00000000 |
904 » LONG $0x00000000 | 998 DATA shifts<>+0x0c(SB)/4, $0x00000000 |
905 »······· | 999 »······· |
906 » LONG $0xffffff0f | 1000 DATA shifts<>+0x10(SB)/4, $0xffffff0f |
907 » LONG $0xffffffff | 1001 DATA shifts<>+0x14(SB)/4, $0xffffffff |
908 » LONG $0xffffffff | 1002 DATA shifts<>+0x18(SB)/4, $0xffffffff |
909 » LONG $0xffffffff | 1003 DATA shifts<>+0x1c(SB)/4, $0xffffffff |
910 »······· | 1004 »······· |
911 » LONG $0xffff0f0e | 1005 DATA shifts<>+0x20(SB)/4, $0xffff0f0e |
912 » LONG $0xffffffff | 1006 DATA shifts<>+0x24(SB)/4, $0xffffffff |
913 » LONG $0xffffffff | 1007 DATA shifts<>+0x28(SB)/4, $0xffffffff |
914 » LONG $0xffffffff | 1008 DATA shifts<>+0x2c(SB)/4, $0xffffffff |
915 »······· | 1009 »······· |
916 » LONG $0xff0f0e0d | 1010 DATA shifts<>+0x30(SB)/4, $0xff0f0e0d |
917 » LONG $0xffffffff | 1011 DATA shifts<>+0x34(SB)/4, $0xffffffff |
918 » LONG $0xffffffff | 1012 DATA shifts<>+0x38(SB)/4, $0xffffffff |
919 » LONG $0xffffffff | 1013 DATA shifts<>+0x3c(SB)/4, $0xffffffff |
920 »······· | 1014 »······· |
921 » LONG $0x0f0e0d0c | 1015 DATA shifts<>+0x40(SB)/4, $0x0f0e0d0c |
922 » LONG $0xffffffff | 1016 DATA shifts<>+0x44(SB)/4, $0xffffffff |
923 » LONG $0xffffffff | 1017 DATA shifts<>+0x48(SB)/4, $0xffffffff |
924 » LONG $0xffffffff | 1018 DATA shifts<>+0x4c(SB)/4, $0xffffffff |
925 »······· | 1019 »······· |
926 » LONG $0x0e0d0c0b | 1020 DATA shifts<>+0x50(SB)/4, $0x0e0d0c0b |
927 » LONG $0xffffff0f | 1021 DATA shifts<>+0x54(SB)/4, $0xffffff0f |
928 » LONG $0xffffffff | 1022 DATA shifts<>+0x58(SB)/4, $0xffffffff |
929 » LONG $0xffffffff | 1023 DATA shifts<>+0x5c(SB)/4, $0xffffffff |
930 »······· | 1024 »······· |
931 » LONG $0x0d0c0b0a | 1025 DATA shifts<>+0x60(SB)/4, $0x0d0c0b0a |
932 » LONG $0xffff0f0e | 1026 DATA shifts<>+0x64(SB)/4, $0xffff0f0e |
933 » LONG $0xffffffff | 1027 DATA shifts<>+0x68(SB)/4, $0xffffffff |
934 » LONG $0xffffffff | 1028 DATA shifts<>+0x6c(SB)/4, $0xffffffff |
935 »······· | 1029 »······· |
936 » LONG $0x0c0b0a09 | 1030 DATA shifts<>+0x70(SB)/4, $0x0c0b0a09 |
937 » LONG $0xff0f0e0d | 1031 DATA shifts<>+0x74(SB)/4, $0xff0f0e0d |
938 » LONG $0xffffffff | 1032 DATA shifts<>+0x78(SB)/4, $0xffffffff |
939 » LONG $0xffffffff | 1033 DATA shifts<>+0x7c(SB)/4, $0xffffffff |
940 »······· | 1034 »······· |
941 » LONG $0x0b0a0908 | 1035 DATA shifts<>+0x80(SB)/4, $0x0b0a0908 |
942 » LONG $0x0f0e0d0c | 1036 DATA shifts<>+0x84(SB)/4, $0x0f0e0d0c |
943 » LONG $0xffffffff | 1037 DATA shifts<>+0x88(SB)/4, $0xffffffff |
944 » LONG $0xffffffff | 1038 DATA shifts<>+0x8c(SB)/4, $0xffffffff |
945 »······· | 1039 »······· |
946 » LONG $0x0a090807 | 1040 DATA shifts<>+0x90(SB)/4, $0x0a090807 |
947 » LONG $0x0e0d0c0b | 1041 DATA shifts<>+0x94(SB)/4, $0x0e0d0c0b |
948 » LONG $0xffffff0f | 1042 DATA shifts<>+0x98(SB)/4, $0xffffff0f |
949 » LONG $0xffffffff | 1043 DATA shifts<>+0x9c(SB)/4, $0xffffffff |
950 »······· | 1044 »······· |
951 » LONG $0x09080706 | 1045 DATA shifts<>+0xa0(SB)/4, $0x09080706 |
952 » LONG $0x0d0c0b0a | 1046 DATA shifts<>+0xa4(SB)/4, $0x0d0c0b0a |
953 » LONG $0xffff0f0e | 1047 DATA shifts<>+0xa8(SB)/4, $0xffff0f0e |
954 » LONG $0xffffffff | 1048 DATA shifts<>+0xac(SB)/4, $0xffffffff |
955 »······· | 1049 »······· |
956 » LONG $0x08070605 | 1050 DATA shifts<>+0xb0(SB)/4, $0x08070605 |
957 » LONG $0x0c0b0a09 | 1051 DATA shifts<>+0xb4(SB)/4, $0x0c0b0a09 |
958 » LONG $0xff0f0e0d | 1052 DATA shifts<>+0xb8(SB)/4, $0xff0f0e0d |
959 » LONG $0xffffffff | 1053 DATA shifts<>+0xbc(SB)/4, $0xffffffff |
960 »······· | 1054 »······· |
961 » LONG $0x07060504 | 1055 DATA shifts<>+0xc0(SB)/4, $0x07060504 |
962 » LONG $0x0b0a0908 | 1056 DATA shifts<>+0xc4(SB)/4, $0x0b0a0908 |
963 » LONG $0x0f0e0d0c | 1057 DATA shifts<>+0xc8(SB)/4, $0x0f0e0d0c |
964 » LONG $0xffffffff | 1058 DATA shifts<>+0xcc(SB)/4, $0xffffffff |
965 »······· | 1059 »······· |
966 » LONG $0x06050403 | 1060 DATA shifts<>+0xd0(SB)/4, $0x06050403 |
967 » LONG $0x0a090807 | 1061 DATA shifts<>+0xd4(SB)/4, $0x0a090807 |
968 » LONG $0x0e0d0c0b | 1062 DATA shifts<>+0xd8(SB)/4, $0x0e0d0c0b |
969 » LONG $0xffffff0f | 1063 DATA shifts<>+0xdc(SB)/4, $0xffffff0f |
970 »······· | 1064 »······· |
971 » LONG $0x05040302 | 1065 DATA shifts<>+0xe0(SB)/4, $0x05040302 |
972 » LONG $0x09080706 | 1066 DATA shifts<>+0xe4(SB)/4, $0x09080706 |
973 » LONG $0x0d0c0b0a | 1067 DATA shifts<>+0xe8(SB)/4, $0x0d0c0b0a |
974 » LONG $0xffff0f0e | 1068 DATA shifts<>+0xec(SB)/4, $0xffff0f0e |
975 »······· | 1069 »······· |
976 » LONG $0x04030201 | 1070 DATA shifts<>+0xf0(SB)/4, $0x04030201 |
977 » LONG $0x08070605 | 1071 DATA shifts<>+0xf4(SB)/4, $0x08070605 |
978 » LONG $0x0c0b0a09 | 1072 DATA shifts<>+0xf8(SB)/4, $0x0c0b0a09 |
979 » LONG $0xff0f0e0d | 1073 DATA shifts<>+0xfc(SB)/4, $0xff0f0e0d |
980 | 1074 |
981 TEXT runtime·memeq(SB),7,$0 | 1075 GLOBL shifts<>(SB),RODATA,$256 |
| 1076 |
| 1077 TEXT runtime·memeq(SB),NOSPLIT,$0-12 |
982 MOVL a+0(FP), SI | 1078 MOVL a+0(FP), SI |
983 MOVL b+4(FP), DI | 1079 MOVL b+4(FP), DI |
984 MOVL count+8(FP), BX | 1080 MOVL count+8(FP), BX |
985 JMP runtime·memeqbody(SB) | 1081 JMP runtime·memeqbody(SB) |
986 | 1082 |
987 | 1083 TEXT bytes·Equal(SB),NOSPLIT,$0-25 |
988 TEXT bytes·Equal(SB),7,$0 | |
989 MOVL a_len+4(FP), BX | 1084 MOVL a_len+4(FP), BX |
990 MOVL b_len+16(FP), CX | 1085 MOVL b_len+16(FP), CX |
991 XORL AX, AX | 1086 XORL AX, AX |
992 CMPL BX, CX | 1087 CMPL BX, CX |
993 JNE eqret | 1088 JNE eqret |
994 MOVL a+0(FP), SI | 1089 MOVL a+0(FP), SI |
995 MOVL b+12(FP), DI | 1090 MOVL b+12(FP), DI |
996 CALL runtime·memeqbody(SB) | 1091 CALL runtime·memeqbody(SB) |
997 eqret: | 1092 eqret: |
998 MOVB AX, ret+24(FP) | 1093 MOVB AX, ret+24(FP) |
999 RET | 1094 RET |
1000 | 1095 |
1001 // a in SI | 1096 // a in SI |
1002 // b in DI | 1097 // b in DI |
1003 // count in BX | 1098 // count in BX |
1004 TEXT runtime·memeqbody(SB),7,$0 | 1099 TEXT runtime·memeqbody(SB),NOSPLIT,$0-0 |
1005 XORL AX, AX | 1100 XORL AX, AX |
1006 | 1101 |
1007 CMPL BX, $4 | 1102 CMPL BX, $4 |
1008 JB small | 1103 JB small |
1009 | 1104 |
1010 // 64 bytes at a time using xmm registers | 1105 // 64 bytes at a time using xmm registers |
1011 hugeloop: | 1106 hugeloop: |
1012 CMPL BX, $64 | 1107 CMPL BX, $64 |
1013 JB bigloop | 1108 JB bigloop |
1014 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2 | 1109 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 MOVL -4(DI)(BX*1), DI | 1182 MOVL -4(DI)(BX*1), DI |
1088 SHRL CX, DI | 1183 SHRL CX, DI |
1089 di_finish: | 1184 di_finish: |
1090 | 1185 |
1091 SUBL SI, DI | 1186 SUBL SI, DI |
1092 SHLL CX, DI | 1187 SHLL CX, DI |
1093 equal: | 1188 equal: |
1094 SETEQ AX | 1189 SETEQ AX |
1095 RET | 1190 RET |
1096 | 1191 |
1097 TEXT runtime·cmpstring(SB),7,$0 | 1192 TEXT runtime·cmpstring(SB),NOSPLIT,$0-20 |
1098 MOVL s1+0(FP), SI | 1193 MOVL s1+0(FP), SI |
1099 MOVL s1+4(FP), BX | 1194 MOVL s1+4(FP), BX |
1100 MOVL s2+8(FP), DI | 1195 MOVL s2+8(FP), DI |
1101 MOVL s2+12(FP), DX | 1196 MOVL s2+12(FP), DX |
1102 CALL runtime·cmpbody(SB) | 1197 CALL runtime·cmpbody(SB) |
1103 MOVL AX, res+16(FP) | 1198 MOVL AX, res+16(FP) |
1104 RET | 1199 RET |
1105 | 1200 |
1106 TEXT bytes·Compare(SB),7,$0 | 1201 TEXT bytes·Compare(SB),NOSPLIT,$0-28 |
1107 MOVL s1+0(FP), SI | 1202 MOVL s1+0(FP), SI |
1108 MOVL s1+4(FP), BX | 1203 MOVL s1+4(FP), BX |
1109 MOVL s2+12(FP), DI | 1204 MOVL s2+12(FP), DI |
1110 MOVL s2+16(FP), DX | 1205 MOVL s2+16(FP), DX |
1111 CALL runtime·cmpbody(SB) | 1206 CALL runtime·cmpbody(SB) |
1112 MOVL AX, res+24(FP) | 1207 MOVL AX, res+24(FP) |
| 1208 RET |
| 1209 |
| 1210 TEXT bytes·IndexByte(SB),NOSPLIT,$0 |
| 1211 MOVL s+0(FP), SI |
| 1212 MOVL s_len+4(FP), CX |
| 1213 MOVB c+12(FP), AL |
| 1214 MOVL SI, DI |
| 1215 CLD; REPN; SCASB |
| 1216 JZ 3(PC) |
| 1217 MOVL $-1, ret+16(FP) |
| 1218 RET |
| 1219 SUBL SI, DI |
| 1220 SUBL $1, DI |
| 1221 MOVL DI, ret+16(FP) |
| 1222 RET |
| 1223 |
| 1224 TEXT strings·IndexByte(SB),NOSPLIT,$0 |
| 1225 MOVL s+0(FP), SI |
| 1226 MOVL s_len+4(FP), CX |
| 1227 MOVB c+8(FP), AL |
| 1228 MOVL SI, DI |
| 1229 CLD; REPN; SCASB |
| 1230 JZ 3(PC) |
| 1231 MOVL $-1, ret+12(FP) |
| 1232 RET |
| 1233 SUBL SI, DI |
| 1234 SUBL $1, DI |
| 1235 MOVL DI, ret+12(FP) |
1113 RET | 1236 RET |
1114 | 1237 |
1115 // input: | 1238 // input: |
1116 // SI = a | 1239 // SI = a |
1117 // DI = b | 1240 // DI = b |
1118 // BX = alen | 1241 // BX = alen |
1119 // DX = blen | 1242 // DX = blen |
1120 // output: | 1243 // output: |
1121 // AX = 1/0/-1 | 1244 // AX = 1/0/-1 |
1122 TEXT runtime·cmpbody(SB),7,$0 | 1245 TEXT runtime·cmpbody(SB),NOSPLIT,$0-0 |
1123 CMPL SI, DI | 1246 CMPL SI, DI |
1124 JEQ cmp_allsame | 1247 JEQ cmp_allsame |
1125 CMPL BX, DX | 1248 CMPL BX, DX |
1126 MOVL DX, BP | 1249 MOVL DX, BP |
1127 CMOVLLT BX, BP // BP = min(alen, blen) | 1250 CMOVLLT BX, BP // BP = min(alen, blen) |
1128 CMPL BP, $4 | 1251 CMPL BP, $4 |
1129 JB cmp_small | 1252 JB cmp_small |
1130 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2 | 1253 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2 |
1131 JE cmp_mediumloop | 1254 JE cmp_mediumloop |
1132 cmp_largeloop: | 1255 cmp_largeloop: |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 cmp_allsame: | 1346 cmp_allsame: |
1224 XORL AX, AX | 1347 XORL AX, AX |
1225 XORL CX, CX | 1348 XORL CX, CX |
1226 CMPL BX, DX | 1349 CMPL BX, DX |
1227 SETGT AX // 1 if alen > blen | 1350 SETGT AX // 1 if alen > blen |
1228 SETEQ CX // 1 if alen == blen | 1351 SETEQ CX // 1 if alen == blen |
1229 LEAL -1(CX)(AX*2), AX // 1,0,-1 result | 1352 LEAL -1(CX)(AX*2), AX // 1,0,-1 result |
1230 RET | 1353 RET |
1231 | 1354 |
1232 // Not implemented on 386 yet | 1355 // Not implemented on 386 yet |
1233 TEXT runtime·lib_init(SB),7,$-4 | 1356 TEXT runtime·lib_init(SB),NOSPLIT,$-4 |
1234 MOVW $0, AX | 1357 MOVW $0, AX |
1235 MOVW (AX), AX | 1358 MOVW (AX), AX |
LEFT | RIGHT |