1
0
mirror of https://github.com/golang/go synced 2024-10-05 16:41:21 -06:00
go/src/runtime/386/asm.s

216 lines
3.9 KiB
ArmAsm
Raw Normal View History

// 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