Commit decd8109 authored by Aram Hăvărneanu's avatar Aram Hăvărneanu Committed by Dave Cheney

liblink, runtime: preliminary support for plan9/amd64

A TLS slot is reserved by _rt0_.*_plan9 as an automatic and
its address (which is static on Plan 9) is saved in the
global _privates symbol. The startup linkage now is exactly
like that from Plan 9 libc, and the way we access g is
exactly as if we'd have used privalloc(2).

Aside from making the code more standard, this change
drastically simplifies it, both for 386 and for amd64, and
makes the Plan 9 code in liblink common for both 386 and
amd64.

The amd64 runtime code was cleared of nxm assumptions, and
now runs on the standard Plan 9 kernel.

Note handling fixes will follow in a separate CL.

LGTM=rsc
R=golang-codereviews, rsc, bradfitz, dave
CC=0intro, ality, golang-codereviews, jas, minux.ma, mischief
https://golang.org/cl/101510049
parent d7b678b2
...@@ -391,7 +391,7 @@ struct Link ...@@ -391,7 +391,7 @@ struct Link
LSym* sym_modu; LSym* sym_modu;
LSym* symmorestack[20]; LSym* symmorestack[20];
LSym* tlsg; LSym* tlsg;
LSym* plan9tos; LSym* plan9privates;
Prog* curp; Prog* curp;
Prog* printp; Prog* printp;
Prog* blitrl; Prog* blitrl;
......
...@@ -1901,7 +1901,6 @@ prefixof(Link *ctxt, Addr *a) ...@@ -1901,7 +1901,6 @@ prefixof(Link *ctxt, Addr *a)
case Hlinux: case Hlinux:
case Hnetbsd: case Hnetbsd:
case Hopenbsd: case Hopenbsd:
case Hplan9:
case Hsolaris: case Hsolaris:
return 0x64; // FS return 0x64; // FS
case Hdarwin: case Hdarwin:
...@@ -3365,6 +3364,19 @@ mfound: ...@@ -3365,6 +3364,19 @@ mfound:
default: default:
sysfatal("unknown TLS base location for %s", headstr(ctxt->headtype)); sysfatal("unknown TLS base location for %s", headstr(ctxt->headtype));
case Hplan9:
if(ctxt->plan9privates == nil)
ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
memset(&pp.from, 0, sizeof pp.from);
pp.from.type = D_EXTERN;
pp.from.sym = ctxt->plan9privates;
pp.from.offset = 0;
pp.from.index = D_NONE;
ctxt->rexflag |= Pw;
*ctxt->andptr++ = 0x8B;
asmand(ctxt, &pp.from, &p->to);
break;
case Hsolaris: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c. case Hsolaris: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c.
// TLS base is 0(FS). // TLS base is 0(FS).
pp.from = p->from; pp.from = p->from;
......
...@@ -2707,11 +2707,11 @@ mfound: ...@@ -2707,11 +2707,11 @@ mfound:
break; break;
case Hplan9: case Hplan9:
if(ctxt->plan9tos == nil) if(ctxt->plan9privates == nil)
ctxt->plan9tos = linklookup(ctxt, "_tos", 0); ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
memset(&pp.from, 0, sizeof pp.from); memset(&pp.from, 0, sizeof pp.from);
pp.from.type = D_EXTERN; pp.from.type = D_EXTERN;
pp.from.sym = ctxt->plan9tos; pp.from.sym = ctxt->plan9privates;
pp.from.offset = 0; pp.from.offset = 0;
pp.from.index = D_NONE; pp.from.index = D_NONE;
*ctxt->andptr++ = 0x8B; *ctxt->andptr++ = 0x8B;
......
...@@ -103,7 +103,7 @@ static int ...@@ -103,7 +103,7 @@ static int
canuselocaltls(Link *ctxt) canuselocaltls(Link *ctxt)
{ {
switch(ctxt->headtype) { switch(ctxt->headtype) {
// case Hlinux: case Hplan9:
case Hwindows: case Hwindows:
return 0; return 0;
} }
...@@ -402,6 +402,10 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -402,6 +402,10 @@ addstacksplit(Link *ctxt, LSym *cursym)
for(i=0; i<nelem(morename); i++) for(i=0; i<nelem(morename); i++)
ctxt->symmorestack[i] = linklookup(ctxt, morename[i], 0); ctxt->symmorestack[i] = linklookup(ctxt, morename[i], 0);
} }
if(ctxt->headtype == Hplan9 && ctxt->plan9privates == nil)
ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
ctxt->cursym = cursym; ctxt->cursym = cursym;
if(cursym->text == nil || cursym->text->link == nil) if(cursym->text == nil || cursym->text->link == nil)
......
...@@ -270,8 +270,8 @@ addstacksplit(Link *ctxt, LSym *cursym) ...@@ -270,8 +270,8 @@ addstacksplit(Link *ctxt, LSym *cursym)
ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0); ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
} }
if(ctxt->headtype == Hplan9 && ctxt->plan9tos == nil) if(ctxt->headtype == Hplan9 && ctxt->plan9privates == nil)
ctxt->plan9tos = linklookup(ctxt, "_tos", 0); ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
ctxt->cursym = cursym; ctxt->cursym = cursym;
......
...@@ -128,8 +128,6 @@ linknew(LinkArch *arch) ...@@ -128,8 +128,6 @@ linknew(LinkArch *arch)
default: default:
sysfatal("unknown thread-local storage offset for %s", headstr(ctxt->headtype)); sysfatal("unknown thread-local storage offset for %s", headstr(ctxt->headtype));
case Hplan9: case Hplan9:
ctxt->tlsoffset = -2*ctxt->arch->ptrsize;
break;
case Hwindows: case Hwindows:
break; break;
case Hlinux: case Hlinux:
......
...@@ -11,8 +11,12 @@ enum { ...@@ -11,8 +11,12 @@ enum {
#else #else
#ifdef GOOS_windows #ifdef GOOS_windows
RuntimeGogoBytes = 80, RuntimeGogoBytes = 80,
#else
#ifdef GOOS_plan9
RuntimeGogoBytes = 80,
#else #else
RuntimeGogoBytes = 64, RuntimeGogoBytes = 64,
#endif // Plan 9
#endif // Windows #endif // Windows
#endif // Solaris #endif // Solaris
PhysPageSize = 4096, PhysPageSize = 4096,
......
#define PAGESIZE 0x200000ULL #define PAGESIZE 0x1000
typedef struct Ureg Ureg; typedef struct Ureg Ureg;
......
...@@ -5,44 +5,17 @@ ...@@ -5,44 +5,17 @@
#include "../../cmd/ld/textflag.h" #include "../../cmd/ld/textflag.h"
// void runtime·memclr(void*, uintptr) // void runtime·memclr(void*, uintptr)
TEXT runtime·memclr(SB), NOSPLIT, $0-16 TEXT runtime·memclr(SB),NOSPLIT,$0-16
MOVQ ptr+0(FP), DI MOVQ addr+0(FP), DI
MOVQ n+8(FP), BX MOVQ count+8(FP), CX
XORQ AX, AX MOVQ CX, BX
ANDQ $7, BX
clr_tail: SHRQ $3, CX
TESTQ BX, BX MOVQ $0, AX
JEQ clr_0 CLD
CMPQ BX, $2
JBE clr_1or2
CMPQ BX, $4
JBE clr_3or4
CMPQ BX, $8
JBE clr_5through8
CMPQ BX, $16
JBE clr_9through16
MOVQ BX, CX
SHRQ $2, CX
REP REP
STOSQ STOSQ
ANDQ $3, BX MOVQ BX, CX
JNE clr_tail REP
RET STOSB
clr_1or2:
MOVB AX, (DI)
MOVB AX, -1(DI)(BX*1)
clr_0:
RET
clr_3or4:
MOVW AX, (DI)
MOVW AX, -2(DI)(BX*1)
RET
clr_5through8:
MOVL AX, (DI)
MOVL AX, -4(DI)(BX*1)
RET
clr_9through16:
MOVQ AX, (DI)
MOVQ AX, -8(DI)(BX*1)
RET RET
...@@ -146,6 +146,35 @@ runtime·usleep(uint32 µs) ...@@ -146,6 +146,35 @@ runtime·usleep(uint32 µs)
runtime·sleep(ms); runtime·sleep(ms);
} }
#pragma textflag NOSPLIT
int64
runtime·nanotime(void)
{
static int32 fd = -1;
byte b[8];
uint32 hi, lo;
// As long as all goroutines share the same file
// descriptor table we can get away with using
// just a static fd. Without a lock the file can
// be opened twice but that's okay.
//
// Using /dev/bintime gives us a latency on the
// order of ten microseconds between two calls.
//
// The naïve implementation (without the cached
// file descriptor) is roughly four times slower
// in 9vx on a 2.16 GHz Intel Core 2 Duo.
if(fd < 0 && (fd = runtime·open("/dev/bintime", OREAD|OCEXEC, 0)) < 0)
return 0;
if(runtime·pread(fd, b, sizeof b, 0) != sizeof b)
return 0;
hi = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
lo = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
return (int64)hi<<32 | (int64)lo;
}
void void
time·now(int64 sec, int32 nsec) time·now(int64 sec, int32 nsec)
{ {
......
...@@ -4,39 +4,20 @@ ...@@ -4,39 +4,20 @@
#include "../../cmd/ld/textflag.h" #include "../../cmd/ld/textflag.h"
TEXT _rt0_386_plan9(SB),NOSPLIT, $0 TEXT _rt0_386_plan9(SB),NOSPLIT,$12
MOVL AX, _tos(SB) MOVL AX, _tos(SB)
LEAL 8(SP), AX
// move arguments down to make room for MOVL AX, _privates(SB)
// m and g at top of stack, right before Tos. MOVL $1, _nprivates(SB)
MOVL SP, SI
SUBL $8, SP
MOVL SP, DI
MOVL AX, CX
SUBL SI, CX
CLD
REP; MOVSB
// adjust argv
SUBL SI, DI
MOVL newargc+0(SP), CX
LEAL newargv+4(SP), BP
argv_fix:
ADDL DI, 0(BP)
ADDL $4, BP
LOOP argv_fix
CALL runtime·asminit(SB) CALL runtime·asminit(SB)
MOVL inargc-4(FP), AX
MOVL 0(SP), AX MOVL AX, 0(SP)
LEAL 4(SP), BX LEAL inargv+0(FP), AX
PUSHL BX MOVL AX, 4(SP)
PUSHL AX CALL _rt0_go(SB)
PUSHL $-1
JMP _rt0_go(SB)
DATA runtime·isplan9(SB)/4, $1 DATA runtime·isplan9(SB)/4, $1
GLOBL runtime·isplan9(SB), $4 GLOBL runtime·isplan9(SB), $4
GLOBL _tos(SB), $4 GLOBL _tos(SB), $4
GLOBL _privates(SB), $4
GLOBL _nprivates(SB), $4
...@@ -4,11 +4,18 @@ ...@@ -4,11 +4,18 @@
#include "../../cmd/ld/textflag.h" #include "../../cmd/ld/textflag.h"
TEXT _rt0_amd64_plan9(SB),NOSPLIT,$-8 TEXT _rt0_amd64_plan9(SB),NOSPLIT,$24
LEAQ 8(SP), SI // argv MOVQ AX, _tos(SB)
MOVQ 0(SP), DI // argc LEAQ 16(SP), AX
MOVQ AX, _privates(SB)
MOVL $1, _nprivates(SB)
MOVL inargc-8(FP), DI
LEAQ inargv+0(FP), SI
MOVQ $_rt0_go(SB), AX MOVQ $_rt0_go(SB), AX
JMP AX JMP AX
DATA runtime·isplan9(SB)/4, $1 DATA runtime·isplan9(SB)/4, $1
GLOBL runtime·isplan9(SB), $4 GLOBL runtime·isplan9(SB), $4
GLOBL _tos(SB), $8
GLOBL _privates(SB), $8
GLOBL _nprivates(SB), $4
...@@ -101,7 +101,7 @@ TEXT runtime·rfork(SB),NOSPLIT,$0 ...@@ -101,7 +101,7 @@ TEXT runtime·rfork(SB),NOSPLIT,$0
MOVL BX, g_m(DX) MOVL BX, g_m(DX)
// Initialize procid from TOS struct. // Initialize procid from TOS struct.
// TODO: Be explicit and insert a new MOVL _tos(SB), AX here. MOVL _tos(SB), AX
MOVL 48(AX), AX // procid MOVL 48(AX), AX // procid
MOVL AX, m_procid(BX) // save pid as m->procid MOVL AX, m_procid(BX) // save pid as m->procid
......
...@@ -10,26 +10,22 @@ TEXT runtime·setldt(SB),NOSPLIT,$0 ...@@ -10,26 +10,22 @@ TEXT runtime·setldt(SB),NOSPLIT,$0
RET RET
TEXT runtime·open(SB),NOSPLIT,$0 TEXT runtime·open(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $14, BP MOVQ $14, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·pread(SB),NOSPLIT,$0 TEXT runtime·pread(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $50, BP MOVQ $50, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·pwrite(SB),NOSPLIT,$0 TEXT runtime·pwrite(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $51, BP MOVQ $51, BP
SYSCALL SYSCALL
RET RET
// int32 _seek(int64*, int32, int64, int32) // int32 _seek(int64*, int32, int64, int32)
TEXT _seek<>(SB),NOSPLIT,$0 TEXT _seek<>(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $39, BP MOVQ $39, BP
SYSCALL SYSCALL
RET RET
...@@ -52,67 +48,51 @@ TEXT runtime·seek(SB),NOSPLIT,$56 ...@@ -52,67 +48,51 @@ TEXT runtime·seek(SB),NOSPLIT,$56
RET RET
TEXT runtime·close(SB),NOSPLIT,$0 TEXT runtime·close(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $4, BP MOVQ $4, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·exits(SB),NOSPLIT,$0 TEXT runtime·exits(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $8, BP MOVQ $8, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·brk_(SB),NOSPLIT,$0 TEXT runtime·brk_(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $24, BP MOVQ $24, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·sleep(SB),NOSPLIT,$0 TEXT runtime·sleep(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $17, BP MOVQ $17, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0 TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $37, BP MOVQ $37, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0 TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $52, BP MOVQ $52, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·notify(SB),NOSPLIT,$0 TEXT runtime·notify(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $28, BP MOVQ $28, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·noted(SB),NOSPLIT,$0 TEXT runtime·noted(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $29, BP MOVQ $29, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0 TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $38, BP MOVQ $38, BP
SYSCALL SYSCALL
RET RET
TEXT runtime·nanotime(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $60, BP
SYSCALL
RET
TEXT runtime·rfork(SB),NOSPLIT,$0 TEXT runtime·rfork(SB),NOSPLIT,$0
MOVQ $0x8000, AX
MOVQ $19, BP // rfork MOVQ $19, BP // rfork
SYSCALL SYSCALL
...@@ -135,8 +115,9 @@ TEXT runtime·rfork(SB),NOSPLIT,$0 ...@@ -135,8 +115,9 @@ TEXT runtime·rfork(SB),NOSPLIT,$0
MOVQ DX, g(AX) MOVQ DX, g(AX)
MOVQ BX, g_m(DX) MOVQ BX, g_m(DX)
// Initialize AX from pid in TLS. // Initialize procid from TOS struct.
MOVQ 0(FS), AX MOVQ _tos(SB), AX
MOVQ 64(AX), AX
MOVQ AX, m_procid(BX) // save pid as m->procid MOVQ AX, m_procid(BX) // save pid as m->procid
CALL runtime·stackcheck(SB) // smashes AX, CX CALL runtime·stackcheck(SB) // smashes AX, CX
...@@ -224,7 +205,6 @@ TEXT runtime·errstr(SB),NOSPLIT,$0 ...@@ -224,7 +205,6 @@ TEXT runtime·errstr(SB),NOSPLIT,$0
MOVQ m_errstr(BX), CX MOVQ m_errstr(BX), CX
MOVQ CX, 8(SP) MOVQ CX, 8(SP)
MOVQ $ERRMAX, 16(SP) MOVQ $ERRMAX, 16(SP)
MOVQ $0x8000, AX
MOVQ $41, BP MOVQ $41, BP
SYSCALL SYSCALL
......
// Copyright 2010 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.
#include "runtime.h"
#include "os_GOOS.h"
#include "../../cmd/ld/textflag.h"
#pragma textflag NOSPLIT
int64
runtime·nanotime(void)
{
static int32 fd = -1;
byte b[8];
uint32 hi, lo;
// As long as all goroutines share the same file
// descriptor table we can get away with using
// just a static fd. Without a lock the file can
// be opened twice but that's okay.
//
// Using /dev/bintime gives us a latency on the
// order of ten microseconds between two calls.
//
// The naïve implementation (without the cached
// file descriptor) is roughly four times slower
// in 9vx on a 2.16 GHz Intel Core 2 Duo.
if(fd < 0 && (fd = runtime·open("/dev/bintime", OREAD|OCEXEC, 0)) < 0)
return 0;
if(runtime·pread(fd, b, sizeof b, 0) != sizeof b)
return 0;
hi = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
lo = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
return (int64)hi<<32 | (int64)lo;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment