Commit 062e354c authored by Austin Clements's avatar Austin Clements

[dev.power64] runtime: power64 fixes and ports of changes

Fix include paths that got moved in the great pkg/ rename.  Add
missing runtime/arch_* files for power64.  Port changes that
happened on default since branching to
runtime/{asm,atomic,sys_linux}_power64x.s (precise stacks,
calling convention change, various new and deleted functions.
Port struct renaming and fix some bugs in
runtime/defs_linux_power64.h.

LGTM=rsc
R=rsc, dave
CC=golang-codereviews
https://golang.org/cl/161450043
parent 6be0c8a5
......@@ -4,7 +4,7 @@
// +build power64 power64le
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
TEXT ·Asin(SB),NOSPLIT,$0
BR ·asin(SB)
......
// Copyright 2014 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.
package runtime
type uintreg uint64
type intptr int64 // TODO(rsc): remove
// Copyright 2014 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.
package runtime
type uintreg uint64
type intptr int64 // TODO(rsc): remove
......@@ -6,9 +6,9 @@
#include "zasm_GOOS_GOARCH.h"
#include "funcdata.h"
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
TEXT _rt0_go(SB),NOSPLIT,$0
TEXT runtime·rt0_go(SB),NOSPLIT,$0
// initialize essential registers
BL runtime·reginit(SB)
......@@ -21,9 +21,10 @@ TEXT _rt0_go(SB),NOSPLIT,$0
MOVD $runtime·g0(SB), g
MOVD $(-64*1024), R31
ADD R31, R1, R3
MOVD R3, g_stackguard(g)
MOVD R3, g_stackguard0(g)
MOVD R1, g_stackbase(g)
MOVD R3, g_stackguard1(g)
MOVD R3, (g_stack+stack_lo)(g)
MOVD R1, (g_stack+stack_hi)(g)
// TODO: if there is a _cgo_init, call it.
// TODO: add TLS
......@@ -41,7 +42,6 @@ TEXT _rt0_go(SB),NOSPLIT,$0
// args are already prepared
BL runtime·args(SB)
BL runtime·osinit(SB)
BL runtime·hashinit(SB)
BL runtime·schedinit(SB)
// create a new goroutine to start program
......@@ -49,9 +49,7 @@ TEXT _rt0_go(SB),NOSPLIT,$0
MOVDU R3, -8(R1)
MOVDU R0, -8(R1)
MOVDU R0, -8(R1)
ARGSIZE(24)
BL runtime·newproc(SB)
ARGSIZE(-1)
ADD $24, R1
// start this M
......@@ -118,7 +116,7 @@ TEXT runtime·gogo(SB), NOSPLIT, $-8-8
MOVD R31, CTR
BR (CTR)
// void mcall(void (*fn)(G*))
// void mcall(fn func(*g))
// Switch to m->g0's stack, call fn(g).
// Fn must never return. It should gogo(&g->sched)
// to keep running g.
......@@ -137,9 +135,10 @@ TEXT runtime·mcall(SB), NOSPLIT, $-8-8
CMP g, R3
BNE 2(PC)
BR runtime·badmcall(SB)
MOVD fn+0(FP), R4
MOVD fn+0(FP), R11 // context
MOVD 0(R11), R4 // code pointer
MOVD R4, CTR
MOVD (g_sched+gobuf_sp)(g), R1
MOVD (g_sched+gobuf_sp)(g), R1 // sp = m->g0->sched.sp
MOVDU R3, -8(R1)
MOVDU R0, -8(R1)
BL (CTR)
......@@ -150,23 +149,50 @@ TEXT runtime·mcall(SB), NOSPLIT, $-8-8
// lives at the bottom of the G stack from the one that lives
// at the top of the M stack because the one at the top of
// the M stack terminates the stack walk (see topofstack()).
TEXT runtime·switchtoM(SB), NOSPLIT, $0-8
TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
UNDEF
BL (LR) // make sure this function is not leaf
RETURN
// void onM(void (*fn)())
// calls fn() on the M stack.
// switches to the M stack if not already on it, and
// switches back when fn() returns.
// func onM_signalok(fn func())
TEXT runtime·onM_signalok(SB), NOSPLIT, $8-8
MOVD g, R3 // R3 = g
MOVD g_m(R3), R4 // R4 = g->m
MOVD m_gsignal(R4), R4 // R4 = g->m->gsignal
MOVD fn+0(FP), R11 // context for call below
CMP R3, R4
BEQ onsignal
MOVD R11, 8(R1)
BL runtime·onM(SB)
RETURN
onsignal:
MOVD 0(R11), R3 // code pointer
MOVD R3, CTR
BL (CTR)
RETURN
// void onM(fn func())
TEXT runtime·onM(SB), NOSPLIT, $0-8
MOVD fn+0(FP), R3 // R3 = fn
MOVD R3, CTR
MOVD R3, R11 // context
MOVD g_m(g), R4 // R4 = m
MOVD m_g0(R4), R5 // R5 = g0
CMP g, R5
BEQ onm
MOVD m_curg(R4), R6
CMP g, R6
BEQ oncurg
// Not g0, not curg. Must be gsignal, but that's not allowed.
// Hide call from linker nosplit analysis.
MOVD $runtime·badonm(SB), R3
MOVD R3, CTR
BL (CTR)
oncurg:
// save our state in g->sched. Pretend to
// be switchtoM if the G stack is scanned.
MOVD $runtime·switchtoM(SB), R6
......@@ -178,10 +204,16 @@ TEXT runtime·onM(SB), NOSPLIT, $0-8
// switch to g0
MOVD R5, g
MOVD (g_sched+gobuf_sp)(g), R1
MOVD (g_sched+gobuf_sp)(g), R3
// make it look like mstart called onM on g0, to stop traceback
SUB $8, R3
MOVD $runtime·mstart(SB), R4
MOVD R4, 0(R3)
MOVD R3, R1
// call target function
ARGSIZE(0)
MOVD 0(R11), R3 // code pointer
MOVD R3, CTR
BL (CTR)
// switch back to g
......@@ -193,6 +225,8 @@ TEXT runtime·onM(SB), NOSPLIT, $0-8
onm:
// already on m stack, just call directly
MOVD 0(R11), R3 // code pointer
MOVD R3, CTR
BL (CTR)
RETURN
......@@ -216,8 +250,11 @@ TEXT runtime·morestack(SB),NOSPLIT,$-8-0
BNE 2(PC)
BL runtime·abort(SB)
MOVW R3, m_moreframesize(R7)
MOVW R4, m_moreargsize(R7)
// Cannot grow signal stack (m->gsignal).
MOVD m_gsignal(R7), R8
CMP g, R8
BNE 2(PC)
BL runtime·abort(SB)
// Called from f.
// Set g->sched to context in f.
......@@ -231,8 +268,6 @@ TEXT runtime·morestack(SB),NOSPLIT,$-8-0
// Set m->morebuf to f's caller.
MOVD R5, (m_morebuf+gobuf_pc)(R7) // f's caller's PC
MOVD R1, (m_morebuf+gobuf_sp)(R7) // f's caller's SP
MOVD $8(R1), R8 // f's argument pointer
MOVD R8, m_moreargp(R7)
MOVD g, (m_morebuf+gobuf_g)(R7)
// Call newstack on m->g0's stack.
......@@ -248,51 +283,8 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-8-0
MOVD R0, R11
BR runtime·morestack(SB)
// Called from panic. Mimics morestack,
// reuses stack growth code to create a frame
// with the desired args running the desired function.
//
// func call(fn *byte, arg *byte, argsize uint32).
TEXT runtime·newstackcall(SB), NOSPLIT, $-8-20
// Save our caller's state as the PC and SP to restore when
// returning from f.
MOVD g_m(g), R5
MOVD LR, R31
MOVD R31, (m_morebuf+gobuf_pc)(R5) // our caller's PC
MOVD R1, (m_morebuf+gobuf_sp)(R5) // our caller's SP
MOVD g, (m_morebuf+gobuf_g)(R5)
// Save our own state as the PC and SP to restore if this
// goroutine needs to be restarted.
MOVD $runtime·newstackcall(SB), R7
MOVD R7, (g_sched+gobuf_pc)(g)
MOVD LR, R31
MOVD R31, (g_sched+gobuf_lr)(g)
MOVD R1, (g_sched+gobuf_sp)(g)
// Set up morestack arguments to call f on a new stack.
// We set f's frame size to 1, as a hint to newstack that
// this is a call from runtime.newstackcall.
// If it turns out that f needs a larger frame than the
// default stack, f's usual stack growth prolog will
// allocate a new segment (and recopy the arguments).
MOVD fn+0(FP), R7
MOVD args+8(FP), R8
MOVW n+16(FP), R9
MOVD R7, m_cret(R5)
MOVD R8, m_moreargp(R5)
MOVW R9, m_moreargsize(R5)
MOVD $1, R10
MOVW R10, m_moreframesize(R5)
// call newstack on m->g0's stack
MOVD m_g0(R5), g
MOVD (g_sched+gobuf_sp)(g), R1
BR runtime·newstack(SB)
// reflect·call: call a function with the given argument list
// func call(f *FuncVal, arg *byte, argsize uint32).
// reflectcall: call a function with the given argument list
// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
// we don't have variable-sized frames, so we use a small number
// of constant-sized-frame functions to encode a few bits of size in the pc.
// Caution: ugly multiline assembly macros in your future!
......@@ -301,60 +293,47 @@ TEXT runtime·newstackcall(SB), NOSPLIT, $-8-20
MOVD $MAXSIZE, R31; \
CMP R3, R31; \
BGT 4(PC); \
MOVD $runtime·NAME(SB), R31; \
MOVD $NAME(SB), R31; \
MOVD R31, CTR; \
BR (CTR)
// Note: can't just "BR NAME(SB)" - bad inlining results.
// Note: can't just "BR runtime·NAME(SB)" - bad inlining results.
TEXT reflect·call(SB), NOSPLIT, $-8-24
TEXT ·reflectcall(SB), NOSPLIT, $-8-24
MOVW argsize+16(FP), R3
DISPATCH(call16, 16)
DISPATCH(call32, 32)
DISPATCH(call64, 64)
DISPATCH(call128, 128)
DISPATCH(call256, 256)
DISPATCH(call512, 512)
DISPATCH(call1024, 1024)
DISPATCH(call2048, 2048)
DISPATCH(call4096, 4096)
DISPATCH(call8192, 8192)
DISPATCH(call16384, 16384)
DISPATCH(call32768, 32768)
DISPATCH(call65536, 65536)
DISPATCH(call131072, 131072)
DISPATCH(call262144, 262144)
DISPATCH(call524288, 524288)
DISPATCH(call1048576, 1048576)
DISPATCH(call2097152, 2097152)
DISPATCH(call4194304, 4194304)
DISPATCH(call8388608, 8388608)
DISPATCH(call16777216, 16777216)
DISPATCH(call33554432, 33554432)
DISPATCH(call67108864, 67108864)
DISPATCH(call134217728, 134217728)
DISPATCH(call268435456, 268435456)
DISPATCH(call536870912, 536870912)
DISPATCH(call1073741824, 1073741824)
DISPATCH(runtime·call16, 16)
DISPATCH(runtime·call32, 32)
DISPATCH(runtime·call64, 64)
DISPATCH(runtime·call128, 128)
DISPATCH(runtime·call256, 256)
DISPATCH(runtime·call512, 512)
DISPATCH(runtime·call1024, 1024)
DISPATCH(runtime·call2048, 2048)
DISPATCH(runtime·call4096, 4096)
DISPATCH(runtime·call8192, 8192)
DISPATCH(runtime·call16384, 16384)
DISPATCH(runtime·call32768, 32768)
DISPATCH(runtime·call65536, 65536)
DISPATCH(runtime·call131072, 131072)
DISPATCH(runtime·call262144, 262144)
DISPATCH(runtime·call524288, 524288)
DISPATCH(runtime·call1048576, 1048576)
DISPATCH(runtime·call2097152, 2097152)
DISPATCH(runtime·call4194304, 4194304)
DISPATCH(runtime·call8388608, 8388608)
DISPATCH(runtime·call16777216, 16777216)
DISPATCH(runtime·call33554432, 33554432)
DISPATCH(runtime·call67108864, 67108864)
DISPATCH(runtime·call134217728, 134217728)
DISPATCH(runtime·call268435456, 268435456)
DISPATCH(runtime·call536870912, 536870912)
DISPATCH(runtime·call1073741824, 1073741824)
MOVD $runtime·badreflectcall(SB), R31
MOVD R31, CTR
BR (CTR)
// Argument map for the callXX frames. Each has one
// stack map (for the single call) with 3 arguments.
DATA gcargs_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
DATA gcargs_reflectcall<>+0x04(SB)/4, $6 // 3 args
DATA gcargs_reflectcall<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsScalar<<4))
GLOBL gcargs_reflectcall<>(SB),RODATA,$12
// callXX frames have no locals
DATA gclocals_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
DATA gclocals_reflectcall<>+0x04(SB)/4, $0 // 0 locals
GLOBL gclocals_reflectcall<>(SB),RODATA,$8
#define CALLFN(NAME,MAXSIZE) \
TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-24; \
FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_reflectcall<>(SB); \
FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_reflectcall<>(SB);\
TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \
NO_LOCAL_POINTERS; \
/* copy arguments to stack */ \
MOVD argptr+8(FP), R3; \
MOVW argsize+16(FP), R4; \
......@@ -391,47 +370,33 @@ TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-24; \
BR -4(PC); \
RETURN
CALLFN(call16, 16)
CALLFN(call32, 32)
CALLFN(call64, 64)
CALLFN(call128, 128)
CALLFN(call256, 256)
CALLFN(call512, 512)
CALLFN(call1024, 1024)
CALLFN(call2048, 2048)
CALLFN(call4096, 4096)
CALLFN(call8192, 8192)
CALLFN(call16384, 16384)
CALLFN(call32768, 32768)
CALLFN(call65536, 65536)
CALLFN(call131072, 131072)
CALLFN(call262144, 262144)
CALLFN(call524288, 524288)
CALLFN(call1048576, 1048576)
CALLFN(call2097152, 2097152)
CALLFN(call4194304, 4194304)
CALLFN(call8388608, 8388608)
CALLFN(call16777216, 16777216)
CALLFN(call33554432, 33554432)
CALLFN(call67108864, 67108864)
CALLFN(call134217728, 134217728)
CALLFN(call268435456, 268435456)
CALLFN(call536870912, 536870912)
CALLFN(call1073741824, 1073741824)
// Return point when leaving stack.
//
// Lessstack can appear in stack traces for the same reason
// as morestack; in that context, it has 0 arguments.
TEXT runtime·lessstack(SB), NOSPLIT, $-8-0
// Save return value in m->cret
MOVD g_m(g), R5
MOVD R3, m_cret(R5)
// Call oldstack on m->g0's stack.
MOVD m_g0(R5), g
MOVD (g_sched+gobuf_sp)(g), R1
BL runtime·oldstack(SB)
CALLFNcall16, 16)
CALLFNcall32, 32)
CALLFNcall64, 64)
CALLFNcall128, 128)
CALLFNcall256, 256)
CALLFNcall512, 512)
CALLFNcall1024, 1024)
CALLFNcall2048, 2048)
CALLFNcall4096, 4096)
CALLFNcall8192, 8192)
CALLFNcall16384, 16384)
CALLFNcall32768, 32768)
CALLFNcall65536, 65536)
CALLFNcall131072, 131072)
CALLFNcall262144, 262144)
CALLFNcall524288, 524288)
CALLFNcall1048576, 1048576)
CALLFNcall2097152, 2097152)
CALLFNcall4194304, 4194304)
CALLFNcall8388608, 8388608)
CALLFNcall16777216, 16777216)
CALLFNcall33554432, 33554432)
CALLFNcall67108864, 67108864)
CALLFNcall134217728, 134217728)
CALLFNcall268435456, 268435456)
CALLFNcall536870912, 536870912)
CALLFNcall1073741824, 1073741824)
// bool cas(int32 *val, int32 old, int32 new)
// Atomically:
......@@ -440,22 +405,23 @@ TEXT runtime·lessstack(SB), NOSPLIT, $-8-0
// return 1;
// } else
// return 0;
TEXT runtime·cas(SB), NOSPLIT, $0-16
TEXT runtime·cas(SB), NOSPLIT, $0-17
MOVD p+0(FP), R3
MOVW old+8(FP), R4
MOVW new+12(FP), R5
SYNC
LWAR (R3), R6
CMPW R6, R4
BNE 7(PC)
BNE 8(PC)
STWCCC R5, (R3)
BNE -5(PC)
MOVD $1, R3
SYNC
ISYNC
MOVB R3, ret+16(FP)
RETURN
MOVD $0, R3
BR -4(PC)
BR -5(PC)
// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
// Atomically:
......@@ -465,7 +431,7 @@ TEXT runtime·cas(SB), NOSPLIT, $0-16
// } else {
// return 0;
// }
TEXT runtime·cas64(SB), NOSPLIT, $0-24
TEXT runtime·cas64(SB), NOSPLIT, $0-25
MOVD p+0(FP), R3
MOVD old+8(FP), R4
MOVD new+16(FP), R5
......@@ -478,10 +444,23 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-24
MOVD $1, R3
SYNC
ISYNC
MOVB R3, ret+24(FP)
RETURN
MOVD $0, R3
BR -4(PC)
TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
BR runtime·cas64(SB)
TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $-8-16
BR runtime·atomicload64(SB)
TEXT runtime·atomicloaduint(SB), NOSPLIT, $-8-16
BR runtime·atomicload64(SB)
TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16
BR runtime·atomicstore64(SB)
// bool casp(void **val, void *old, void *new)
// Atomically:
// if(*val == old){
......@@ -489,14 +468,14 @@ TEXT runtime·cas64(SB), NOSPLIT, $0-24
// return 1;
// } else
// return 0;
TEXT runtime·casp(SB), NOSPLIT, $0-24
TEXT runtime·casp(SB), NOSPLIT, $0-25
BR runtime·cas64(SB)
// uint32 xadd(uint32 volatile *val, int32 delta)
// Atomically:
// *val += delta;
// return *val;
TEXT runtime·xadd(SB), NOSPLIT, $0-12
TEXT runtime·xadd(SB), NOSPLIT, $0-20
MOVD p+0(FP), R4
MOVW delta+8(FP), R5
SYNC
......@@ -506,10 +485,10 @@ TEXT runtime·xadd(SB), NOSPLIT, $0-12
BNE -4(PC)
SYNC
ISYNC
MOVW R3, R3
MOVW R3, ret+16(FP)
RETURN
TEXT runtime·xadd64(SB), NOSPLIT, $0-16
TEXT runtime·xadd64(SB), NOSPLIT, $0-24
MOVD p+0(FP), R4
MOVD delta+8(FP), R5
SYNC
......@@ -519,9 +498,10 @@ TEXT runtime·xadd64(SB), NOSPLIT, $0-16
BNE -4(PC)
SYNC
ISYNC
MOVD R3, ret+16(FP)
RETURN
TEXT runtime·xchg(SB), NOSPLIT, $0-12
TEXT runtime·xchg(SB), NOSPLIT, $0-20
MOVD p+0(FP), R4
MOVW new+8(FP), R5
SYNC
......@@ -530,9 +510,10 @@ TEXT runtime·xchg(SB), NOSPLIT, $0-12
BNE -3(PC)
SYNC
ISYNC
MOVW R3, ret+16(FP)
RETURN
TEXT runtime·xchg64(SB), NOSPLIT, $0-16
TEXT runtime·xchg64(SB), NOSPLIT, $0-24
MOVD p+0(FP), R4
MOVD new+8(FP), R5
SYNC
......@@ -541,9 +522,13 @@ TEXT runtime·xchg64(SB), NOSPLIT, $0-16
BNE -3(PC)
SYNC
ISYNC
MOVD R3, ret+16(FP)
RETURN
TEXT runtime·xchgp(SB), NOSPLIT, $0-16
TEXT runtime·xchgp(SB), NOSPLIT, $0-24
BR runtime·xchg64(SB)
TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24
BR runtime·xchg64(SB)
TEXT runtime·procyield(SB),NOSPLIT,$0-0
......@@ -553,20 +538,33 @@ TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
BR runtime·atomicstore64(SB)
TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
MOVD 0(FP), R3
MOVW 8(FP), R4
MOVD ptr+0(FP), R3
MOVW val+8(FP), R4
SYNC
MOVW R4, 0(R3)
RETURN
TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
MOVD ptr+0(FP), R3
MOVD val+8(FP), R4
SYNC
MOVD R4, 0(R3)
RETURN
// void runtime·atomicor8(byte volatile*, byte);
TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
MOVD 0(FP), R3
MOVD 8(FP), R4
SYNC
MOVD R4, 0(R3)
LWAR (R3), R5
OR R4, R5
STWCCC R5, (R3)
BNE -3(PC)
SYNC
ISYNC
RETURN
// void jmpdefer(fn, sp);
// void jmpdefer(fv, sp);
// called from deferreturn.
// 1. grab stored LR for caller
// 2. sub 4 bytes to get back to BL deferreturn
......@@ -576,7 +574,7 @@ TEXT runtime·jmpdefer(SB), NOSPLIT, $-8-16
SUB $4, R31
MOVD R31, LR
MOVD fn+0(FP), R11
MOVD fv+0(FP), R11
MOVD argp+8(FP), R1
SUB $8, R1
MOVD 0(R11), R3
......@@ -597,7 +595,7 @@ TEXT gosave<>(SB),NOSPLIT,$-8
// Call fn(arg) on the scheduler stack,
// aligned appropriately for the gcc ABI.
// See cgocall.c for more details.
TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
TEXT ·asmcgocall(SB),NOSPLIT,$0-16
MOVD R0, 21(R0)
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
......@@ -608,19 +606,20 @@ TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
// See cgocall.c for more details.
TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-24
TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24
MOVD R0, 23(R0)
// void setg(G*); set g. for use by needm.
TEXT runtime·setg(SB), NOSPLIT, $0-16
TEXT runtime·setg(SB), NOSPLIT, $0-8
MOVD R0, 24(R0)
// void setg_gcc(G*); set g called from gcc.
TEXT setg_gcc<>(SB),NOSPLIT,$0
MOVD R0, 25(R0)
TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-8
TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-16
MOVD 0(R1), R3
MOVD R3, ret+8(FP)
RETURN
TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-8-16
......@@ -629,16 +628,24 @@ TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-8-16
RETURN
TEXT runtime·setcallerpc(SB),NOSPLIT,$-8-16
MOVD x+8(FP),R3 // addr of first arg
MOVD pc+8(FP), R3
MOVD R3, 0(R1) // set calling pc
RETURN
TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
MOVD sp+0(FP), R3
SUB $8, R3
MOVD R3, ret+8(FP)
RETURN
TEXT runtime·abort(SB),NOSPLIT,$-4-0
// func gogetcallersp(p unsafe.Pointer) uintptr
TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
MOVD sp+0(FP), R3
SUB $8, R3
MOVD R3,ret+8(FP)
RETURN
TEXT runtime·abort(SB),NOSPLIT,$-8-0
MOVW (R0), R0
UNDEF
......@@ -646,7 +653,7 @@ TEXT runtime·abort(SB),NOSPLIT,$-4-0
#define TBRU 269 /* Time base Upper/Lower */
// int64 runtime·cputicks(void)
TEXT runtime·cputicks(SB),NOSPLIT,$0-0
TEXT runtime·cputicks(SB),NOSPLIT,$0-8
MOVW SPR(TBRU), R4
MOVW SPR(TBRL), R3
MOVW SPR(TBRU), R5
......@@ -654,17 +661,9 @@ TEXT runtime·cputicks(SB),NOSPLIT,$0-0
BNE -4(PC)
SLD $32, R5
OR R5, R3
MOVD R3, ret+0(FP)
RETURN
TEXT runtime·stackguard(SB),NOSPLIT,$0-16
MOVD R1, R3
MOVD R3, sp+0(FP)
MOVD g_stackguard(g), R3
MOVD R3, limit+8(FP)
RETURN
GLOBL runtime·tls0(SB), $64
// AES hashing not implemented for Power
TEXT runtime·aeshash(SB),NOSPLIT,$-8-0
MOVW (R0), R1
......@@ -675,7 +674,7 @@ TEXT runtime·aeshash64(SB),NOSPLIT,$-8-0
TEXT runtime·aeshashstr(SB),NOSPLIT,$-8-0
MOVW (R0), R1
TEXT runtime·memeq(SB),NOSPLIT,$-8-24
TEXT runtime·memeq(SB),NOSPLIT,$-8-25
MOVD a+0(FP), R3
MOVD b+8(FP), R4
MOVD count+16(FP), R5
......@@ -683,26 +682,6 @@ TEXT runtime·memeq(SB),NOSPLIT,$-8-24
SUB $1, R4
ADD R3, R5, R8
_next:
CMP R3, R8
BNE 3(PC)
MOVD $1, R3
RETURN
MOVBZU 1(R3), R6
MOVBZU 1(R4), R7
CMP R6, R7
BEQ _next
MOVD $0, R3
RETURN
TEXT runtime·gomemeq(SB),NOSPLIT,$0-25
MOVD a+0(FP), R3
MOVD b+8(FP), R4
MOVD count+16(FP), R5
SUB $1, R3
SUB $1, R4
ADD R3, R5, R8
_next2:
CMP R3, R8
BNE 4(PC)
MOVD $1, R3
......@@ -711,14 +690,14 @@ _next2:
MOVBZU 1(R3), R6
MOVBZU 1(R4), R7
CMP R6, R7
BEQ _next2
BEQ _next
MOVB R0, ret+24(FP)
RETURN
// eqstring tests whether two strings are equal.
// See runtime_test.go:eqstring_generic for
// equivlaent Go code.
// equivalent Go code.
TEXT runtime·eqstring(SB),NOSPLIT,$0-33
MOVD s1len+8(FP), R4
MOVD s2len+24(FP), R5
......@@ -824,9 +803,6 @@ _index2_notfound:
RETURN
TEXT runtime·timenow(SB), NOSPLIT, $0-0
BR time·now(SB)
// A Duff's device for zeroing memory.
// The compiler jumps to computed addresses within
// this routine to zero chunks of memory. Do not
......@@ -966,80 +942,22 @@ TEXT runtime·duffzero(SB), NOSPLIT, $-8-0
MOVDU R0, 8(R3)
RETURN
TEXT runtime·fastrand2(SB), NOSPLIT, $0-4
TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
MOVD g_m(g), R4
MOVD m_fastrand(R4), R3
MOVWZ m_fastrand(R4), R3
ADD R3, R3
CMP R3, $0
BGE 2(PC)
XOR $0x88888eef, R3
MOVD R3, m_fastrand(R4)
MOVD R3, ret+0(FP)
MOVW R3, m_fastrand(R4)
MOVW R3, ret+0(FP)
RETURN
// The gohash and goeq trampolines are necessary while we have
// both Go and C calls to alg functions. Once we move all call
// sites to Go, we can redo the hash/eq functions to use the
// Go calling convention and remove these.
// convert call to:
// func (alg unsafe.Pointer, p unsafe.Pointer, size uintpr, seed uintptr) uintptr
// to:
// func (hash *uintptr, size uintptr, p unsafe.Pointer)
TEXT runtime·gohash(SB), NOSPLIT, $24-40
FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_gohash<>(SB)
FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_gohash<>(SB)
MOVD a+0(FP), R3
MOVD alg_hash(R3), R3
MOVD R3, CTR
MOVD p+8(FP), R4
MOVD size+16(FP), R5
MOVD seed+24(FP), R6
MOVD R6, ret+32(FP)
MOVD $ret+32(FP), R7
MOVD R7, 8(R1)
MOVD R5, 16(R1)
MOVD R4, 24(R1)
PCDATA $PCDATA_StackMapIndex, $0
BL (CTR)
TEXT runtime·return0(SB), NOSPLIT, $0
MOVW $0, R3
RETURN
DATA gcargs_gohash<>+0x00(SB)/4, $1 // 1 stackmap
DATA gcargs_gohash<>+0x04(SB)/4, $10 // 5 args
DATA gcargs_gohash<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2))
GLOBL gcargs_gohash<>(SB),RODATA,$12
DATA gclocals_gohash<>+0x00(SB)/4, $1 // 1 stackmap
DATA gclocals_gohash<>+0x04(SB)/4, $0 // 0 locals
GLOBL gclocals_gohash<>(SB),RODATA,$8
// convert call to:
// func (alg unsafe.Pointer, p, q unsafe.Pointer, size uintptr) bool
// to:
// func (eq *bool, size uintptr, p, q unsafe.Pointer)
TEXT runtime·goeq(SB), NOSPLIT, $32-33
FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_goeq<>(SB)
FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_goeq<>(SB)
MOVD alg+0(FP), R3
MOVD alg_equal(R3), R3
MOVD R3, CTR
MOVD p+8(FP), R4
MOVD q+16(FP), R5
MOVD size+24(FP), R6
MOVD $ret+32(FP), R7
MOVD R7, 8(R1)
MOVD R6, 16(R1)
MOVD R5, 24(R1)
MOVD R4, 32(R1)
PCDATA $PCDATA_StackMapIndex, $0
BL (CTR)
RETURN
DATA gcargs_goeq<>+0x00(SB)/4, $1 // 1 stackmap
DATA gcargs_goeq<>+0x04(SB)/4, $10 // 5 args
DATA gcargs_goeq<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsPointer<<4))
GLOBL gcargs_goeq<>(SB),RODATA,$12
DATA gclocals_goeq<>+0x00(SB)/4, $1 // 1 stackmap
DATA gclocals_goeq<>+0x04(SB)/4, $0 // 0 locals
GLOBL gclocals_goeq<>(SB),RODATA,$8
// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
// Must obey the gcc calling convention.
TEXT _cgo_topofstack(SB),NOSPLIT,$0
MOVD R0, 26(R0)
......@@ -4,34 +4,37 @@
// +build power64 power64le
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
// uint32 runtime·atomicload(uint32 volatile* addr)
TEXT ·atomicload(SB),NOSPLIT,$-8-8
TEXT ·atomicload(SB),NOSPLIT,$-8-12
MOVD 0(FP), R3
SYNC
MOVWZ 0(R3), R3
CMPW R3, R3, CR7
BC 4, 30, 1(PC) // bne- cr7,0x4
ISYNC
MOVW R3, ret+8(FP)
RETURN
// uint64 runtime·atomicload64(uint64 volatile* addr)
TEXT ·atomicload64(SB),NOSPLIT,$-8-8
TEXT ·atomicload64(SB),NOSPLIT,$-8-16
MOVD 0(FP), R3
SYNC
MOVD 0(R3), R3
CMP R3, R3, CR7
BC 4, 30, 1(PC) // bne- cr7,0x4
ISYNC
MOVD R3, ret+8(FP)
RETURN
// void *runtime·atomicloadp(void *volatile *addr)
TEXT ·atomicloadp(SB),NOSPLIT,$-8-8
TEXT ·atomicloadp(SB),NOSPLIT,$-8-16
MOVD 0(FP), R3
SYNC
MOVD 0(R3), R3
CMP R3, R3, CR7
BC 4, 30, 1(PC) // bne- cr7,0x4
ISYNC
MOVD R3, ret+8(FP)
RETURN
......@@ -7,6 +7,12 @@
#ifdef GOARCH_arm
#define JMP B
#endif
#ifdef GOARCH_power64
#define JMP BR
#endif
#ifdef GOARCH_power64le
#define JMP BR
#endif
TEXT ·setMaxStack(SB),NOSPLIT,$0-0
JMP runtime·setMaxStack(SB)
......
......@@ -88,11 +88,10 @@ enum {
typedef struct Sigset Sigset;
typedef struct Timespec Timespec;
typedef struct Timeval Timeval;
typedef struct Sigaction Sigaction;
typedef struct SigactionT SigactionT;
typedef struct Siginfo Siginfo;
typedef struct Itimerval Itimerval;
typedef struct EpollEvent EpollEvent;
typedef uint64 Usigset;
#pragma pack on
......@@ -109,11 +108,11 @@ struct Timeval {
int64 tv_sec;
int64 tv_usec;
};
struct Sigaction {
struct SigactionT {
void *sa_handler;
uint64 sa_flags;
void *sa_restorer;
Usigset sa_mask;
uint64 sa_mask;
};
struct Siginfo {
int32 si_signo;
......@@ -129,7 +128,7 @@ struct Itimerval {
struct EpollEvent {
uint32 events;
byte Pad_cgo_0[4];
uint64 data;
byte data[8]; // unaligned uintptr
};
......@@ -144,7 +143,6 @@ enum {
SA_RESTORER = 0,
};
//typedef struct Usigset Usigset;
typedef struct Ptregs Ptregs;
typedef struct Vreg Vreg;
typedef struct SigaltstackT SigaltstackT;
......@@ -153,11 +151,6 @@ typedef struct Ucontext Ucontext;
#pragma pack on
//struct Usigset {
// uint64 sig[1];
//};
//typedef Sigset Usigset;
struct Ptregs {
uint64 gpr[32];
uint64 nip;
......@@ -202,8 +195,8 @@ struct Ucontext {
uint64 uc_flags;
Ucontext *uc_link;
SigaltstackT uc_stack;
Usigset uc_sigmask;
Usigset __unused[15];
uint64 uc_sigmask;
uint64 __unused[15];
Sigcontext uc_mcontext;
};
......
......@@ -4,7 +4,7 @@
// +build power64 power64le
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
// void runtime·memclr(void*, uintptr)
TEXT runtime·memclr(SB),NOSPLIT,$0-16
......
......@@ -4,7 +4,7 @@
// +build power64 power64le
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
// void runtime·memmove(void*, void*, uintptr)
TEXT runtime·memmove(SB), NOSPLIT, $-8-24
......
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
// actually a function descriptor for _main<>(SB)
TEXT _rt0_power64_linux(SB),7,$0
TEXT _rt0_power64_linux(SB),NOSPLIT,$0
DWORD $_main<>(SB)
DWORD $0
DWORD $0
......@@ -12,6 +12,6 @@ TEXT _main<>(SB),NOSPLIT,$-8
BR main(SB)
TEXT main(SB),NOSPLIT,$-8
MOVD $_rt0_go(SB), R31
MOVD $runtime·rt0_go(SB), R31
MOVD R31, CTR
BR (CTR)
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
TEXT _rt0_power64le_linux(SB),7,$0
TEXT _rt0_power64le_linux(SB),NOSPLIT,$0
BR _main<>(SB)
TEXT _main<>(SB),NOSPLIT,$-8
......@@ -9,6 +9,6 @@ TEXT _main<>(SB),NOSPLIT,$-8
BR main(SB)
TEXT main(SB),NOSPLIT,$-8
MOVD $_rt0_go(SB), R31
MOVD $runtime·rt0_go(SB), R31
MOVD R31, CTR
BR (CTR)
......@@ -10,7 +10,7 @@
//
#include "zasm_GOOS_GOARCH.h"
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
#define SYS_exit 1
#define SYS_read 3
......@@ -44,49 +44,54 @@
#define SYS_clock_gettime 246
#define SYS_epoll_create1 315
TEXT runtime·exit(SB),NOSPLIT,$-8-8
MOVW 8(R1), R3
TEXT runtime·exit(SB),NOSPLIT,$-8-4
MOVW code+0(FP), R3
SYSCALL $SYS_exit_group
RETURN
TEXT runtime·exit1(SB),NOSPLIT,$-8-8
MOVW 8(R1), R3
TEXT runtime·exit1(SB),NOSPLIT,$-8-4
MOVW code+0(FP), R3
SYSCALL $SYS_exit
RETURN
TEXT runtime·open(SB),NOSPLIT,$-8-16
MOVD 8(R1), R3
MOVW 16(R1), R4
MOVW 20(R1), R5
TEXT runtime·open(SB),NOSPLIT,$-8-20
MOVD name+0(FP), R3
MOVW mode+8(FP), R4
MOVW perm+12(FP), R5
SYSCALL $SYS_open
MOVW R3, ret+16(FP)
RETURN
TEXT runtime·close(SB),NOSPLIT,$-8-16
MOVW 8(R1), R3
TEXT runtime·close(SB),NOSPLIT,$-8-12
MOVW fd+0(FP), R3
SYSCALL $SYS_close
MOVW R3, ret+8(FP)
RETURN
TEXT runtime·write(SB),NOSPLIT,$-8-24
MOVD 8(R1), R3
MOVD 16(R1), R4
MOVW 24(R1), R5
TEXT runtime·write(SB),NOSPLIT,$-8-28
MOVD fd+0(FP), R3
MOVD p+8(FP), R4
MOVW n+16(FP), R5
SYSCALL $SYS_write
MOVW R3, ret+24(FP)
RETURN
TEXT runtime·read(SB),NOSPLIT,$-8-24
MOVW 8(R1), R3
MOVD 16(R1), R4
MOVW 24(R1), R5
TEXT runtime·read(SB),NOSPLIT,$-8-28
MOVW fd+0(FP), R3
MOVD p+8(FP), R4
MOVW n+16(FP), R5
SYSCALL $SYS_read
MOVW R3, ret+24(FP)
RETURN
TEXT runtime·getrlimit(SB),NOSPLIT,$-8-24
MOVW 8(R1), R3
MOVD 16(R1), R4
TEXT runtime·getrlimit(SB),NOSPLIT,$-8-20
MOVW kind+0(FP), R3
MOVD limit+8(FP), R4
SYSCALL $SYS_ugetrlimit
MOVW R3, ret+16(FP)
RETURN
TEXT runtime·usleep(SB),NOSPLIT,$-8-16
TEXT runtime·usleep(SB),NOSPLIT,$16-4
MOVW usec+0(FP), R3
MOVD R3, R5
MOVW $1000000, R4
......@@ -113,17 +118,18 @@ TEXT runtime·raise(SB),NOSPLIT,$-8
RETURN
TEXT runtime·setitimer(SB),NOSPLIT,$-8-24
MOVW 8(R1), R3
MOVD 16(R1), R4
MOVD 24(R1), R5
MOVW mode+0(FP), R3
MOVD new+8(FP), R4
MOVD old+16(FP), R5
SYSCALL $SYS_setitimer
RETURN
TEXT runtime·mincore(SB),NOSPLIT,$-8-24
MOVD 8(R1), R3
MOVD 16(R1), R4
MOVD 24(R1), R5
TEXT runtime·mincore(SB),NOSPLIT,$-8-28
MOVD addr+0(FP), R3
MOVD n+8(FP), R4
MOVD dst+16(FP), R5
SYSCALL $SYS_mincore
MOVW R3, ret+24(FP)
RETURN
// func now() (sec int64, nsec int32)
......@@ -150,24 +156,26 @@ TEXT runtime·nanotime(SB),NOSPLIT,$16
MOVD $1000000000, R4
MULLD R4, R3
ADD R5, R3
MOVD R3, ret+0(FP)
RETURN
TEXT runtime·rtsigprocmask(SB),NOSPLIT,$-8-32
MOVW 8(R1), R3
MOVD 16(R1), R4
MOVD 24(R1), R5
MOVW 32(R1), R6
TEXT runtime·rtsigprocmask(SB),NOSPLIT,$-8-28
MOVW sig+0(FP), R3
MOVD new+8(FP), R4
MOVD old+16(FP), R5
MOVW size+24(FP), R6
SYSCALL $SYS_rt_sigprocmask
BVC 2(PC)
MOVD R0, 0xf1(R0) // crash
RETURN
TEXT runtime·rt_sigaction(SB),NOSPLIT,$-8-32
MOVD 8(R1), R3
MOVD 16(R1), R4
MOVD 24(R1), R5
MOVD 32(R1), R6
TEXT runtime·rt_sigaction(SB),NOSPLIT,$-8-36
MOVD sig+0(FP), R3
MOVD new+8(FP), R4
MOVD old+16(FP), R5
MOVD size+24(FP), R6
SYSCALL $SYS_rt_sigaction
MOVW R3, ret+32(FP)
RETURN
#ifdef GOARCH_power64le
......@@ -214,28 +222,29 @@ TEXT runtime·_sigtramp(SB),NOSPLIT,$64
RETURN
TEXT runtime·mmap(SB),NOSPLIT,$-8
MOVD 8(R1), R3
MOVD 16(R1), R4
MOVW 24(R1), R5
MOVW 28(R1), R6
MOVW 32(R1), R7
MOVW 36(R1), R8
MOVD addr+0(FP), R3
MOVD n+8(FP), R4
MOVW prot+16(FP), R5
MOVW flags+20(FP), R6
MOVW fd+24(FP), R7
MOVW off+28(FP), R8
SYSCALL $SYS_mmap
MOVD R3, ret+32(FP)
RETURN
TEXT runtime·munmap(SB),NOSPLIT,$-8
MOVD 8(R1), R3
MOVD 16(R1), R4
MOVD addr+0(FP), R3
MOVD n+8(FP), R4
SYSCALL $SYS_munmap
BVC 2(PC)
MOVD R0, 0xf3(R0)
RETURN
TEXT runtime·madvise(SB),NOSPLIT,$-8
MOVD 8(R1), R3
MOVD 16(R1), R4
MOVD 24(R1), R5
MOVD addr+0(FP), R3
MOVD n+8(FP), R4
MOVW flags+16(FP), R5
SYSCALL $SYS_madvise
// ignore failure - maybe pages are locked
RETURN
......@@ -243,19 +252,20 @@ TEXT runtime·madvise(SB),NOSPLIT,$-8
// int64 futex(int32 *uaddr, int32 op, int32 val,
// struct timespec *timeout, int32 *uaddr2, int32 val2);
TEXT runtime·futex(SB),NOSPLIT,$-8
MOVD 8(R1), R3
MOVW 16(R1), R4
MOVW 20(R1), R5
MOVD 24(R1), R6
MOVD 32(R1), R7
MOVW 40(R1), R8
MOVD addr+0(FP), R3
MOVW op+8(FP), R4
MOVW val+12(FP), R5
MOVD ts+16(FP), R6
MOVD addr2+24(FP), R7
MOVW val3+32(FP), R8
SYSCALL $SYS_futex
MOVW R3, ret+40(FP)
RETURN
// int64 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
TEXT runtime·clone(SB),NOSPLIT,$-8
MOVW flags+0(FP), R3
MOVD stack+8(FP), R4
MOVD stk+8(FP), R4
// Copy mp, gp, fn off parent stack for use by child.
// Careful: Linux system call clobbers ???.
......@@ -273,7 +283,8 @@ TEXT runtime·clone(SB),NOSPLIT,$-8
// In parent, return.
CMP R3, $0
BEQ 2(PC)
BEQ 3(PC)
MOVW R3, ret+40(FP)
RETURN
// In child, on new stack.
......@@ -322,45 +333,50 @@ TEXT runtime·osyield(SB),NOSPLIT,$-8
RETURN
TEXT runtime·sched_getaffinity(SB),NOSPLIT,$-8
MOVD 8(R1), R3
MOVD 16(R1), R4
MOVD 24(R1), R5
MOVD pid+0(FP), R3
MOVD len+8(FP), R4
MOVD buf+16(FP), R5
SYSCALL $SYS_sched_getaffinity
MOVW R3, ret+24(FP)
RETURN
// int32 runtime·epollcreate(int32 size);
TEXT runtime·epollcreate(SB),NOSPLIT,$-8
MOVW 8(R1), R3
MOVW size+0(FP), R3
SYSCALL $SYS_epoll_create
MOVW R3, ret+8(FP)
RETURN
// int32 runtime·epollcreate1(int32 flags);
TEXT runtime·epollcreate1(SB),NOSPLIT,$-8
MOVW 8(R1), R3
MOVW flags+0(FP), R3
SYSCALL $SYS_epoll_create1
MOVW R3, ret+8(FP)
RETURN
// int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev);
// func epollctl(epfd, op, fd int32, ev *epollEvent) int
TEXT runtime·epollctl(SB),NOSPLIT,$-8
MOVW 8(R1), R3
MOVW 12(R1), R4
MOVW 16(R1), R5
MOVD 24(R1), R6
MOVW epfd+0(FP), R3
MOVW op+4(FP), R4
MOVW fd+8(FP), R5
MOVD ev+16(FP), R6
SYSCALL $SYS_epoll_ctl
MOVW R3, ret+24(FP)
RETURN
// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
TEXT runtime·epollwait(SB),NOSPLIT,$-8
MOVW 8(R1), R3
MOVD 16(R1), R4
MOVW 24(R1), R5
MOVW 28(R1), R6
MOVW epfd+0(FP), R3
MOVD ev+8(FP), R4
MOVW nev+16(FP), R5
MOVW timeout+20(FP), R6
SYSCALL $SYS_epoll_wait
MOVW R3, ret+24(FP)
RETURN
// void runtime·closeonexec(int32 fd);
TEXT runtime·closeonexec(SB),NOSPLIT,$-8
MOVW 8(R1), R3 // fd
MOVW fd+0(FP), R3 // fd
MOVD $2, R4 // F_SETFD
MOVD $1, R5 // FD_CLOEXEC
SYSCALL $SYS_fcntl
......
......@@ -4,7 +4,7 @@
// +build power64 power64le
#include "../../../cmd/ld/textflag.h"
#include "textflag.h"
TEXT ·SwapInt32(SB),NOSPLIT,$0-20
BR ·SwapUint32(SB)
......
......@@ -4,5 +4,12 @@
#include "textflag.h"
#ifdef GOARCH_power64
#define RET RETURN
#endif
#ifdef GOARCH_power64le
#define RET RETURN
#endif
TEXT ·use(SB),NOSPLIT,$0
RET
......@@ -5,7 +5,7 @@
// +build linux
// +build power64 power64le
#include "../../cmd/ld/textflag.h"
#include "textflag.h"
//
// System calls for Power64, Linux
......
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