mirror of
https://github.com/golang/go
synced 2024-10-05 16:41:21 -06:00
216 lines
3.9 KiB
ArmAsm
216 lines
3.9 KiB
ArmAsm
|
// 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_386(SB),7,$0
|
||
|
// copy arguments forward on an even stack
|
||
|
MOVL 0(SP), AX // argc
|
||
|
LEAL 4(SP), BX // argv
|
||
|
SUBL $128, SP // plenty of scratch
|
||
|
ANDL $~7, SP
|
||
|
MOVL AX, 120(SP) // save argc, argv away
|
||
|
MOVL BX, 124(SP)
|
||
|
|
||
|
/*
|
||
|
// write "go386\n"
|
||
|
PUSHL $6
|
||
|
PUSHL $hello(SB)
|
||
|
PUSHL $1
|
||
|
CALL sys·write(SB)
|
||
|
POPL AX
|
||
|
POPL AX
|
||
|
POPL AX
|
||
|
*/
|
||
|
|
||
|
CALL ldt0setup(SB)
|
||
|
|
||
|
// set up %fs to refer to that ldt entry
|
||
|
MOVL $(7*8+7), AX
|
||
|
MOVW AX, FS
|
||
|
|
||
|
// store through it, to make sure it works
|
||
|
MOVL $0x123, 0(FS)
|
||
|
MOVL tls0(SB), AX
|
||
|
CMPL AX, $0x123
|
||
|
JEQ ok
|
||
|
MOVL AX, 0
|
||
|
ok:
|
||
|
|
||
|
// set up m and g "registers"
|
||
|
// g is 0(FS), m is 4(FS)
|
||
|
LEAL g0(SB), CX
|
||
|
MOVL CX, 0(FS)
|
||
|
LEAL m0(SB), AX
|
||
|
MOVL AX, 4(FS)
|
||
|
|
||
|
// save m->g0 = g0
|
||
|
MOVL CX, 0(AX)
|
||
|
|
||
|
// create istack out of the OS stack
|
||
|
LEAL (-8192+104)(SP), AX // TODO: 104?
|
||
|
MOVL AX, 0(CX) // 8(g) is stack limit (w 104b guard)
|
||
|
MOVL SP, 4(CX) // 12(g) is base
|
||
|
CALL emptyfunc(SB) // fault if stack check is wrong
|
||
|
|
||
|
// convention is D is always cleared
|
||
|
CLD
|
||
|
|
||
|
CALL check(SB)
|
||
|
|
||
|
// saved argc, argv
|
||
|
MOVL 120(SP), AX
|
||
|
MOVL AX, 0(SP)
|
||
|
MOVL 124(SP), AX
|
||
|
MOVL AX, 4(SP)
|
||
|
CALL args(SB)
|
||
|
CALL osinit(SB)
|
||
|
CALL schedinit(SB)
|
||
|
|
||
|
// create a new goroutine to start program
|
||
|
PUSHL $mainstart(SB) // entry
|
||
|
PUSHL $8 // arg size
|
||
|
CALL sys·newproc(SB)
|
||
|
POPL AX
|
||
|
POPL AX
|
||
|
|
||
|
// start this M
|
||
|
CALL mstart(SB)
|
||
|
|
||
|
INT $3
|
||
|
RET
|
||
|
|
||
|
TEXT mainstart(SB),7,$0
|
||
|
CALL main·init(SB)
|
||
|
CALL initdone(SB)
|
||
|
CALL main·main(SB)
|
||
|
PUSHL $0
|
||
|
CALL sys·Exit(SB)
|
||
|
POPL AX
|
||
|
INT $3
|
||
|
RET
|
||
|
|
||
|
TEXT sys·Breakpoint(SB),7,$0
|
||
|
BYTE $0xcc
|
||
|
RET
|
||
|
|
||
|
// go-routine
|
||
|
TEXT gogo(SB), 7, $0
|
||
|
MOVL 4(SP), AX // gobuf
|
||
|
MOVL 0(AX), SP // restore SP
|
||
|
MOVL 4(AX), AX
|
||
|
MOVL AX, 0(SP) // put PC on the stack
|
||
|
MOVL $1, AX
|
||
|
RET
|
||
|
|
||
|
TEXT gosave(SB), 7, $0
|
||
|
MOVL 4(SP), AX // gobuf
|
||
|
MOVL SP, 0(AX) // save SP
|
||
|
MOVL 0(SP), BX
|
||
|
MOVL BX, 4(AX) // save PC
|
||
|
MOVL $0, AX // return 0
|
||
|
RET
|
||
|
|
||
|
// support for morestack
|
||
|
|
||
|
// return point when leaving new stack.
|
||
|
// save AX, jmp to lesstack to switch back
|
||
|
TEXT retfromnewstack(SB),7,$0
|
||
|
MOVL 4(FS), BX // m
|
||
|
MOVL AX, 8(BX) // save AX in m->cret
|
||
|
JMP lessstack(SB)
|
||
|
|
||
|
// gogo, returning 2nd arg instead of 1
|
||
|
TEXT gogoret(SB), 7, $0
|
||
|
MOVL 8(SP), AX // return 2nd arg
|
||
|
MOVL 4(SP), BX // gobuf
|
||
|
MOVL 0(BX), SP // restore SP
|
||
|
MOVL 4(BX), BX
|
||
|
MOVL BX, 0(SP) // put PC on the stack
|
||
|
RET
|
||
|
|
||
|
TEXT setspgoto(SB), 7, $0
|
||
|
MOVL 4(SP), AX // SP
|
||
|
MOVL 8(SP), BX // fn to call
|
||
|
MOVL 12(SP), CX // fn to return
|
||
|
MOVL AX, SP
|
||
|
PUSHL CX
|
||
|
JMP BX
|
||
|
POPL AX
|
||
|
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
|
||
|
MOVL 4(SP), BX
|
||
|
MOVL 8(SP), AX
|
||
|
MOVL 12(SP), CX
|
||
|
LOCK
|
||
|
CMPXCHGL CX, 0(BX)
|
||
|
JZ 3(PC)
|
||
|
MOVL $0, AX
|
||
|
RET
|
||
|
MOVL $1, AX
|
||
|
RET
|
||
|
|
||
|
// void jmpdefer(byte*);
|
||
|
// 1. pop the caller
|
||
|
// 2. sub 5 bytes from the callers return
|
||
|
// 3. jmp to the argument
|
||
|
TEXT jmpdefer(SB), 7, $0
|
||
|
MOVL 4(SP), AX // function
|
||
|
ADDL $(4+56), SP // pop saved PC and callers frame
|
||
|
SUBL $5, (SP) // reposition his return address
|
||
|
JMP AX // and goto function
|
||
|
|
||
|
TEXT sys·memclr(SB),7,$0
|
||
|
MOVL 4(SP), DI // arg 1 addr
|
||
|
MOVL 8(SP), CX // arg 2 count
|
||
|
ADDL $3, CX
|
||
|
SHRL $2, CX
|
||
|
MOVL $0, AX
|
||
|
CLD
|
||
|
REP
|
||
|
STOSL
|
||
|
RET
|
||
|
|
||
|
TEXT sys·getcallerpc+0(SB),7,$0
|
||
|
MOVL x+0(FP),AX // addr of first arg
|
||
|
MOVL -4(AX),AX // get calling pc
|
||
|
RET
|
||
|
|
||
|
TEXT sys·setcallerpc+0(SB),7,$0
|
||
|
MOVL x+0(FP),AX // addr of first arg
|
||
|
MOVL x+4(FP), BX
|
||
|
MOVL BX, -4(AX) // set calling pc
|
||
|
RET
|
||
|
|
||
|
TEXT ldt0setup(SB),7,$16
|
||
|
// set up ldt 7 to point at tls0
|
||
|
// ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go.
|
||
|
MOVL $7, 0(SP)
|
||
|
LEAL tls0(SB), AX
|
||
|
MOVL AX, 4(SP)
|
||
|
MOVL $32, 8(SP) // sizeof(tls array)
|
||
|
CALL setldt(SB)
|
||
|
RET
|
||
|
|
||
|
GLOBL m0+0(SB), $1024
|
||
|
GLOBL g0+0(SB), $1024
|
||
|
|
||
|
GLOBL tls0+0(SB), $32
|
||
|
|
||
|
TEXT emptyfunc(SB),0,$0
|
||
|
RET
|
||
|
|
||
|
TEXT abort(SB),7,$0
|
||
|
INT $0x3
|
||
|
|
||
|
DATA hello+0(SB)/8, $"go386\n\z\z"
|
||
|
GLOBL hello+0(SB), $8
|
||
|
|