summaryrefslogtreecommitdiff
path: root/src/lib/runtime/amd64/asm.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/runtime/amd64/asm.s')
-rw-r--r--src/lib/runtime/amd64/asm.s207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/lib/runtime/amd64/asm.s b/src/lib/runtime/amd64/asm.s
new file mode 100644
index 000000000..6fc01bbc9
--- /dev/null
+++ b/src/lib/runtime/amd64/asm.s
@@ -0,0 +1,207 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+TEXT _rt0_amd64(SB),7,$-8
+
+ // copy arguments forward on an even stack
+
+ MOVQ 0(SP), AX // argc
+ LEAQ 8(SP), BX // argv
+ SUBQ $(4*8+7), SP // 2args 2auto
+ ANDQ $~7, SP
+ MOVQ AX, 16(SP)
+ MOVQ BX, 24(SP)
+
+ // set the per-goroutine and per-mach registers
+
+ LEAQ m0(SB), R14 // dedicated m. register
+ LEAQ g0(SB), R15 // dedicated g. register
+ MOVQ R15, 0(R14) // m has pointer to its g0
+
+ // create istack out of the given (operating system) stack
+
+ LEAQ (-8192+104)(SP), AX
+ MOVQ AX, 0(R15) // 0(R15) is stack limit (w 104b guard)
+ MOVQ SP, 8(R15) // 8(R15) is base
+
+ CLD // convention is D is always left cleared
+ CALL check(SB)
+
+ MOVL 16(SP), AX // copy argc
+ MOVL AX, 0(SP)
+ MOVQ 24(SP), AX // copy argv
+ MOVQ AX, 8(SP)
+ CALL args(SB)
+ CALL osinit(SB)
+ CALL schedinit(SB)
+
+ // create a new goroutine to start program
+ PUSHQ $mainstart(SB) // entry
+ PUSHQ $16 // arg size
+ CALL sys·newproc(SB)
+ POPQ AX
+ POPQ AX
+
+ // start this M
+ CALL mstart(SB)
+
+ CALL notok(SB) // never returns
+ RET
+
+TEXT mainstart(SB),7,$0
+ CALL main·init(SB)
+ CALL initdone(SB)
+ CALL main·main(SB)
+ PUSHQ $0
+ CALL exit(SB)
+ POPQ AX
+ CALL notok(SB)
+ RET
+
+TEXT breakpoint(SB),7,$0
+ BYTE $0xcc
+ RET
+
+/*
+ * go-routine
+ */
+TEXT gogo(SB), 7, $0
+ MOVQ 8(SP), AX // gobuf
+ MOVQ 0(AX), SP // restore SP
+ MOVQ 8(AX), AX
+ MOVQ AX, 0(SP) // put PC on the stack
+ MOVL $1, AX // return 1
+ RET
+
+TEXT gosave(SB), 7, $0
+ MOVQ 8(SP), AX // gobuf
+ MOVQ SP, 0(AX) // save SP
+ MOVQ 0(SP), BX
+ MOVQ BX, 8(AX) // save PC
+ MOVL $0, AX // return 0
+ RET
+
+/*
+ * support for morestack
+ */
+
+// morestack trampolines
+TEXT sys·morestack00+0(SB),7,$0
+ MOVQ $0, AX
+ MOVQ AX, 8(R14)
+ MOVQ $sys·morestack+0(SB), AX
+ JMP AX
+
+TEXT sys·morestack01+0(SB),7,$0
+ SHLQ $32, AX
+ MOVQ AX, 8(R14)
+ MOVQ $sys·morestack+0(SB), AX
+ JMP AX
+
+TEXT sys·morestack10+0(SB),7,$0
+ MOVLQZX AX, AX
+ MOVQ AX, 8(R14)
+ MOVQ $sys·morestack+0(SB), AX
+ JMP AX
+
+TEXT sys·morestack11+0(SB),7,$0
+ MOVQ AX, 8(R14)
+ MOVQ $sys·morestack+0(SB), AX
+ JMP AX
+
+TEXT sys·morestackx(SB),7,$0
+ POPQ AX
+ SHLQ $35, AX
+ MOVQ AX, 8(R14)
+ MOVQ $sys·morestack(SB), AX
+ JMP AX
+
+// subcases of morestack01
+// with const of 8,16,...48
+TEXT sys·morestack8(SB),7,$0
+ PUSHQ $1
+ MOVQ $sys·morestackx(SB), AX
+ JMP AX
+
+TEXT sys·morestack16(SB),7,$0
+ PUSHQ $2
+ MOVQ $sys·morestackx(SB), AX
+ JMP AX
+
+TEXT sys·morestack24(SB),7,$0
+ PUSHQ $3
+ MOVQ $sys·morestackx(SB), AX
+ JMP AX
+
+TEXT sys·morestack32(SB),7,$0
+ PUSHQ $4
+ MOVQ $sys·morestackx(SB), AX
+ JMP AX
+
+TEXT sys·morestack40(SB),7,$0
+ PUSHQ $5
+ MOVQ $sys·morestackx(SB), AX
+ JMP AX
+
+TEXT sys·morestack48(SB),7,$0
+ PUSHQ $6
+ MOVQ $sys·morestackx(SB), AX
+ JMP AX
+
+// return point when leaving new stack. save AX, jmp to lessstack to switch back
+TEXT retfromnewstack(SB), 7, $0
+ MOVQ AX, 16(R14) // save AX in m->cret
+ MOVQ $lessstack(SB), AX
+ JMP AX
+
+// gogo, returning 2nd arg instead of 1
+TEXT gogoret(SB), 7, $0
+ MOVQ 16(SP), AX // return 2nd arg
+ MOVQ 8(SP), BX // gobuf
+ MOVQ 0(BX), SP // restore SP
+ MOVQ 8(BX), BX
+ MOVQ BX, 0(SP) // put PC on the stack
+ RET
+
+TEXT setspgoto(SB), 7, $0
+ MOVQ 8(SP), AX // SP
+ MOVQ 16(SP), BX // fn to call
+ MOVQ 24(SP), CX // fn to return
+ MOVQ AX, SP
+ PUSHQ CX
+ JMP BX
+ POPQ AX // not reached
+ RET
+
+// bool cas(int32 *val, int32 old, int32 new)
+// Atomically:
+// if(*val == old){
+// *val = new;
+// return 1;
+// } else
+// return 0;
+TEXT cas(SB), 7, $0
+ MOVQ 8(SP), BX
+ MOVL 16(SP), AX
+ MOVL 20(SP), CX
+ LOCK
+ CMPXCHGL CX, 0(BX)
+ JZ 3(PC)
+ MOVL $0, AX
+ RET
+ MOVL $1, AX
+ RET
+
+// void jmpdefer(fn, sp);
+// called from deferreturn.
+// 1. pop the caller
+// 2. sub 5 bytes from the callers return
+// 3. jmp to the argument
+TEXT jmpdefer(SB), 7, $0
+ MOVQ 8(SP), AX // fn
+ MOVQ 16(SP), BX // caller sp
+ LEAQ -8(BX), SP // caller sp after CALL
+ SUBQ $5, (SP) // return to CALL again
+ JMP AX // but first run the deferred function