diff options
| author | maxim-yurchuk <[email protected]> | 2024-10-09 12:29:46 +0300 |
|---|---|---|
| committer | maxim-yurchuk <[email protected]> | 2024-10-09 13:14:22 +0300 |
| commit | 9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch) | |
| tree | a8fb3181d5947c0d78cf402aa56e686130179049 /contrib/go/_std_1.22/src/internal | |
| parent | a44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff) | |
publishFullContrib: true for ydb
<HIDDEN_URL>
commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/go/_std_1.22/src/internal')
186 files changed, 10550 insertions, 0 deletions
diff --git a/contrib/go/_std_1.22/src/internal/abi/abi_generic.go b/contrib/go/_std_1.22/src/internal/abi/abi_generic.go new file mode 100644 index 00000000000..76ef2e28986 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/abi/abi_generic.go @@ -0,0 +1,38 @@ +// Copyright 2020 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. + +//go:build !goexperiment.regabiargs && !amd64 && !arm64 && !ppc64 && !ppc64le && !riscv64 + +package abi + +const ( + // ABI-related constants. + // + // In the generic case, these are all zero + // which lets them gracefully degrade to ABI0. + + // IntArgRegs is the number of registers dedicated + // to passing integer argument values. Result registers are identical + // to argument registers, so this number is used for those too. + IntArgRegs = 0 + + // FloatArgRegs is the number of registers dedicated + // to passing floating-point argument values. Result registers are + // identical to argument registers, so this number is used for + // those too. + FloatArgRegs = 0 + + // EffectiveFloatRegSize describes the width of floating point + // registers on the current platform from the ABI's perspective. + // + // Since Go only supports 32-bit and 64-bit floating point primitives, + // this number should be either 0, 4, or 8. 0 indicates no floating + // point registers for the ABI or that floating point values will be + // passed via the softfloat ABI. + // + // For platforms that support larger floating point register widths, + // such as x87's 80-bit "registers" (not that we support x87 currently), + // use 8. + EffectiveFloatRegSize = 0 +) diff --git a/contrib/go/_std_1.22/src/internal/abi/abi_loong64.go b/contrib/go/_std_1.22/src/internal/abi/abi_loong64.go new file mode 100644 index 00000000000..c2306ae8d88 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/abi/abi_loong64.go @@ -0,0 +1,19 @@ +// Copyright 2023 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. + +//go:build goexperiment.regabiargs + +package abi + +const ( + // See abi_generic.go. + + // R4 - R19 + IntArgRegs = 16 + + // F0 - F15 + FloatArgRegs = 16 + + EffectiveFloatRegSize = 8 +) diff --git a/contrib/go/_std_1.22/src/internal/abi/abi_ppc64x.go b/contrib/go/_std_1.22/src/internal/abi/abi_ppc64x.go new file mode 100644 index 00000000000..73416d74d64 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/abi/abi_ppc64x.go @@ -0,0 +1,19 @@ +// Copyright 2021 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. + +//go:build ppc64 || ppc64le + +package abi + +const ( + // See abi_generic.go. + + // R3 - R10, R14 - R17. + IntArgRegs = 12 + + // F1 - F12. + FloatArgRegs = 12 + + EffectiveFloatRegSize = 8 +) diff --git a/contrib/go/_std_1.22/src/internal/abi/abi_riscv64.go b/contrib/go/_std_1.22/src/internal/abi/abi_riscv64.go new file mode 100644 index 00000000000..2bcd9d6db21 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/abi/abi_riscv64.go @@ -0,0 +1,17 @@ +// Copyright 2022 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 abi + +const ( + // See abi_generic.go. + + // X8 - X23 + IntArgRegs = 16 + + // F8 - F23. + FloatArgRegs = 16 + + EffectiveFloatRegSize = 8 +) diff --git a/contrib/go/_std_1.22/src/internal/abi/funcpc_gccgo.go b/contrib/go/_std_1.22/src/internal/abi/funcpc_gccgo.go new file mode 100644 index 00000000000..ad5fa52c542 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/abi/funcpc_gccgo.go @@ -0,0 +1,21 @@ +// Copyright 2023 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. + +// For bootstrapping with gccgo. + +//go:build gccgo + +package abi + +import "unsafe" + +func FuncPCABI0(f interface{}) uintptr { + words := (*[2]unsafe.Pointer)(unsafe.Pointer(&f)) + return *(*uintptr)(unsafe.Pointer(words[1])) +} + +func FuncPCABIInternal(f interface{}) uintptr { + words := (*[2]unsafe.Pointer)(unsafe.Pointer(&f)) + return *(*uintptr)(unsafe.Pointer(words[1])) +} diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_386.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_386.s new file mode 100644 index 00000000000..27b660ccf7c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_386.s @@ -0,0 +1,144 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Compare(SB),NOSPLIT,$0-28 + MOVL a_base+0(FP), SI + MOVL a_len+4(FP), BX + MOVL b_base+12(FP), DI + MOVL b_len+16(FP), DX + LEAL ret+24(FP), AX + JMP cmpbody<>(SB) + +TEXT runtime·cmpstring(SB),NOSPLIT,$0-20 + MOVL a_base+0(FP), SI + MOVL a_len+4(FP), BX + MOVL b_base+8(FP), DI + MOVL b_len+12(FP), DX + LEAL ret+16(FP), AX + JMP cmpbody<>(SB) + +// input: +// SI = a +// DI = b +// BX = alen +// DX = blen +// AX = address of return word (set to 1/0/-1) +TEXT cmpbody<>(SB),NOSPLIT,$0-0 + MOVL DX, BP + SUBL BX, DX // DX = blen-alen + JLE 2(PC) + MOVL BX, BP // BP = min(alen, blen) + CMPL SI, DI + JEQ allsame + CMPL BP, $4 + JB small +#ifdef GO386_softfloat + JMP mediumloop +#endif +largeloop: + CMPL BP, $16 + JB mediumloop + MOVOU (SI), X0 + MOVOU (DI), X1 + PCMPEQB X0, X1 + PMOVMSKB X1, BX + XORL $0xffff, BX // convert EQ to NE + JNE diff16 // branch if at least one byte is not equal + ADDL $16, SI + ADDL $16, DI + SUBL $16, BP + JMP largeloop + +diff16: + BSFL BX, BX // index of first byte that differs + XORL DX, DX + MOVB (SI)(BX*1), CX + CMPB CX, (DI)(BX*1) + SETHI DX + LEAL -1(DX*2), DX // convert 1/0 to +1/-1 + MOVL DX, (AX) + RET + +mediumloop: + CMPL BP, $4 + JBE _0through4 + MOVL (SI), BX + MOVL (DI), CX + CMPL BX, CX + JNE diff4 + ADDL $4, SI + ADDL $4, DI + SUBL $4, BP + JMP mediumloop + +_0through4: + MOVL -4(SI)(BP*1), BX + MOVL -4(DI)(BP*1), CX + CMPL BX, CX + JEQ allsame + +diff4: + BSWAPL BX // reverse order of bytes + BSWAPL CX + XORL BX, CX // find bit differences + BSRL CX, CX // index of highest bit difference + SHRL CX, BX // move a's bit to bottom + ANDL $1, BX // mask bit + LEAL -1(BX*2), BX // 1/0 => +1/-1 + MOVL BX, (AX) + RET + + // 0-3 bytes in common +small: + LEAL (BP*8), CX + NEGL CX + JEQ allsame + + // load si + CMPB SI, $0xfc + JA si_high + MOVL (SI), SI + JMP si_finish +si_high: + MOVL -4(SI)(BP*1), SI + SHRL CX, SI +si_finish: + SHLL CX, SI + + // same for di + CMPB DI, $0xfc + JA di_high + MOVL (DI), DI + JMP di_finish +di_high: + MOVL -4(DI)(BP*1), DI + SHRL CX, DI +di_finish: + SHLL CX, DI + + BSWAPL SI // reverse order of bytes + BSWAPL DI + XORL SI, DI // find bit differences + JEQ allsame + BSRL DI, CX // index of highest bit difference + SHRL CX, SI // move a's bit to bottom + ANDL $1, SI // mask bit + LEAL -1(SI*2), BX // 1/0 => +1/-1 + MOVL BX, (AX) + RET + + // all the bytes in common are the same, so we just need + // to compare the lengths. +allsame: + XORL BX, BX + XORL CX, CX + TESTL DX, DX + SETLT BX // 1 if alen > blen + SETEQ CX // 1 if alen == blen + LEAL -1(CX)(BX*2), BX // 1,0,-1 result + MOVL BX, (AX) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_arm.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_arm.s new file mode 100644 index 00000000000..80d01a217fb --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_arm.s @@ -0,0 +1,86 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-28 + MOVW a_base+0(FP), R2 + MOVW a_len+4(FP), R0 + MOVW b_base+12(FP), R3 + MOVW b_len+16(FP), R1 + ADD $28, R13, R7 + B cmpbody<>(SB) + +TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-20 + MOVW a_base+0(FP), R2 + MOVW a_len+4(FP), R0 + MOVW b_base+8(FP), R3 + MOVW b_len+12(FP), R1 + ADD $20, R13, R7 + B cmpbody<>(SB) + +// On entry: +// R0 is the length of a +// R1 is the length of b +// R2 points to the start of a +// R3 points to the start of b +// R7 points to return value (-1/0/1 will be written here) +// +// On exit: +// R4, R5, R6 and R8 are clobbered +TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0 + CMP R2, R3 + BEQ samebytes + CMP R0, R1 + MOVW R0, R6 + MOVW.LT R1, R6 // R6 is min(R0, R1) + + CMP $0, R6 + BEQ samebytes + CMP $4, R6 + ADD R2, R6 // R2 is current byte in a, R6 is the end of the range to compare + BLT byte_loop // length < 4 + AND $3, R2, R8 + CMP $0, R8 + BNE byte_loop // unaligned a, use byte-wise compare (TODO: try to align a) +aligned_a: + AND $3, R3, R8 + CMP $0, R8 + BNE byte_loop // unaligned b, use byte-wise compare + AND $0xfffffffc, R6, R8 + // length >= 4 +chunk4_loop: + MOVW.P 4(R2), R4 + MOVW.P 4(R3), R5 + CMP R4, R5 + BNE cmp + CMP R2, R8 + BNE chunk4_loop + CMP R2, R6 + BEQ samebytes // all compared bytes were the same; compare lengths +byte_loop: + MOVBU.P 1(R2), R4 + MOVBU.P 1(R3), R5 + CMP R4, R5 + BNE ret + CMP R2, R6 + BNE byte_loop +samebytes: + CMP R0, R1 + MOVW.LT $1, R0 + MOVW.GT $-1, R0 + MOVW.EQ $0, R0 + MOVW R0, (R7) + RET +ret: + // bytes differed + MOVW.LT $1, R0 + MOVW.GT $-1, R0 + MOVW R0, (R7) + RET +cmp: + SUB $4, R2, R2 + SUB $4, R3, R3 + B byte_loop diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_generic.go b/contrib/go/_std_1.22/src/internal/bytealg/compare_generic.go new file mode 100644 index 00000000000..b04e2750611 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_generic.go @@ -0,0 +1,60 @@ +// Copyright 2018 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. + +//go:build !386 && !amd64 && !s390x && !arm && !arm64 && !loong64 && !ppc64 && !ppc64le && !mips && !mipsle && !wasm && !mips64 && !mips64le && !riscv64 + +package bytealg + +import _ "unsafe" // for go:linkname + +func Compare(a, b []byte) int { + l := len(a) + if len(b) < l { + l = len(b) + } + if l == 0 || &a[0] == &b[0] { + goto samebytes + } + for i := 0; i < l; i++ { + c1, c2 := a[i], b[i] + if c1 < c2 { + return -1 + } + if c1 > c2 { + return +1 + } + } +samebytes: + if len(a) < len(b) { + return -1 + } + if len(a) > len(b) { + return +1 + } + return 0 +} + +//go:linkname runtime_cmpstring runtime.cmpstring +func runtime_cmpstring(a, b string) int { + l := len(a) + if len(b) < l { + l = len(b) + } + for i := 0; i < l; i++ { + c1, c2 := a[i], b[i] + if c1 < c2 { + return -1 + } + if c1 > c2 { + return +1 + } + } + if len(a) < len(b) { + return -1 + } + if len(a) > len(b) { + return +1 + } + return 0 +} diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_loong64.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_loong64.s new file mode 100644 index 00000000000..311449ab189 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_loong64.s @@ -0,0 +1,106 @@ +// Copyright 2022 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Compare<ABIInternal>(SB),NOSPLIT,$0-56 +#ifndef GOEXPERIMENT_regabiargs + MOVV a_base+0(FP), R4 + MOVV a_len+8(FP), R5 + MOVV b_base+24(FP), R6 + MOVV b_len+32(FP), R7 + MOVV $ret+48(FP), R13 +#else + // R4 = a_base + // R5 = a_len + // R6 = a_cap (unused) + // R7 = b_base (want in R6) + // R8 = b_len (want in R7) + // R9 = b_cap (unused) + MOVV R7, R6 + MOVV R8, R7 +#endif + JMP cmpbody<>(SB) + +TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT,$0-40 +#ifndef GOEXPERIMENT_regabiargs + MOVV a_base+0(FP), R4 + MOVV b_base+16(FP), R6 + MOVV a_len+8(FP), R5 + MOVV b_len+24(FP), R7 + MOVV $ret+32(FP), R13 +#endif + // R4 = a_base + // R5 = a_len + // R6 = b_base + // R7 = b_len + JMP cmpbody<>(SB) + +// On entry: +// R5 length of a +// R7 length of b +// R4 points to the start of a +// R6 points to the start of b +// R13 points to the return value (-1/0/1) +TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0 + BEQ R4, R6, samebytes // same start of a and b + + SGTU R5, R7, R9 + BNE R0, R9, r2_lt_r1 + MOVV R5, R14 + JMP entry +r2_lt_r1: + MOVV R7, R14 // R14 is min(R4, R5) +entry: + ADDV R4, R14, R12 // R6 start of a, R14 end of a + BEQ R4, R12, samebytes // length is 0 + + SRLV $4, R14 // R14 is number of chunks + BEQ R0, R14, byte_loop + + // make sure both a and b are aligned. + OR R4, R6, R15 + AND $7, R15 + BNE R0, R15, byte_loop + + PCALIGN $16 +chunk16_loop: + BEQ R0, R14, byte_loop + MOVV (R4), R8 + MOVV (R6), R9 + BNE R8, R9, byte_loop + MOVV 8(R4), R16 + MOVV 8(R6), R17 + ADDV $16, R4 + ADDV $16, R6 + SUBVU $1, R14 + BEQ R16, R17, chunk16_loop + SUBV $8, R4 + SUBV $8, R6 + +byte_loop: + BEQ R4, R12, samebytes + MOVBU (R4), R8 + ADDVU $1, R4 + MOVBU (R6), R9 + ADDVU $1, R6 + BEQ R8, R9, byte_loop + +byte_cmp: + SGTU R8, R9, R4 // R12 = 1 if (R8 > R9) + BNE R0, R4, ret + MOVV $-1, R4 + JMP ret + +samebytes: + SGTU R5, R7, R8 + SGTU R7, R5, R9 + SUBV R9, R8, R4 + +ret: +#ifndef GOEXPERIMENT_regabiargs + MOVV R4, (R13) +#endif + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_mips64x.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_mips64x.s new file mode 100644 index 00000000000..117a9ef631f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_mips64x.s @@ -0,0 +1,88 @@ +// Copyright 2019 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. + +//go:build mips64 || mips64le + +#include "go_asm.h" +#include "textflag.h" + +TEXT ·Compare(SB),NOSPLIT,$0-56 + MOVV a_base+0(FP), R3 + MOVV b_base+24(FP), R4 + MOVV a_len+8(FP), R1 + MOVV b_len+32(FP), R2 + MOVV $ret+48(FP), R9 + JMP cmpbody<>(SB) + +TEXT runtime·cmpstring(SB),NOSPLIT,$0-40 + MOVV a_base+0(FP), R3 + MOVV b_base+16(FP), R4 + MOVV a_len+8(FP), R1 + MOVV b_len+24(FP), R2 + MOVV $ret+32(FP), R9 + JMP cmpbody<>(SB) + +// On entry: +// R1 length of a +// R2 length of b +// R3 points to the start of a +// R4 points to the start of b +// R9 points to the return value (-1/0/1) +TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0 + BEQ R3, R4, samebytes // same start of a and b + + SGTU R1, R2, R7 + BNE R0, R7, r2_lt_r1 + MOVV R1, R10 + JMP entry +r2_lt_r1: + MOVV R2, R10 // R10 is min(R1, R2) +entry: + ADDV R3, R10, R8 // R3 start of a, R8 end of a + BEQ R3, R8, samebytes // length is 0 + + SRLV $4, R10 // R10 is number of chunks + BEQ R0, R10, byte_loop + + // make sure both a and b are aligned. + OR R3, R4, R11 + AND $7, R11 + BNE R0, R11, byte_loop + +chunk16_loop: + BEQ R0, R10, byte_loop + MOVV (R3), R6 + MOVV (R4), R7 + BNE R6, R7, byte_loop + MOVV 8(R3), R13 + MOVV 8(R4), R14 + ADDV $16, R3 + ADDV $16, R4 + SUBVU $1, R10 + BEQ R13, R14, chunk16_loop + SUBV $8, R3 + SUBV $8, R4 + +byte_loop: + BEQ R3, R8, samebytes + MOVBU (R3), R6 + ADDVU $1, R3 + MOVBU (R4), R7 + ADDVU $1, R4 + BEQ R6, R7, byte_loop + +byte_cmp: + SGTU R6, R7, R8 // R8 = 1 if (R6 > R7) + BNE R0, R8, ret + MOVV $-1, R8 + JMP ret + +samebytes: + SGTU R1, R2, R6 + SGTU R2, R1, R7 + SUBV R7, R6, R8 + +ret: + MOVV R8, (R9) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_mipsx.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_mipsx.s new file mode 100644 index 00000000000..857ac133890 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_mipsx.s @@ -0,0 +1,72 @@ +// Copyright 2018 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. + +//go:build mips || mipsle + +#include "go_asm.h" +#include "textflag.h" + +TEXT ·Compare(SB),NOSPLIT,$0-28 + MOVW a_base+0(FP), R3 + MOVW b_base+12(FP), R4 + MOVW a_len+4(FP), R1 + MOVW b_len+16(FP), R2 + BEQ R3, R4, samebytes + SGTU R1, R2, R7 + MOVW R1, R8 + CMOVN R7, R2, R8 // R8 is min(R1, R2) + + ADDU R3, R8 // R3 is current byte in a, R8 is last byte in a to compare +loop: + BEQ R3, R8, samebytes + + MOVBU (R3), R6 + ADDU $1, R3 + MOVBU (R4), R7 + ADDU $1, R4 + BEQ R6, R7 , loop + + SGTU R6, R7, R8 + MOVW $-1, R6 + CMOVZ R8, R6, R8 + JMP cmp_ret +samebytes: + SGTU R1, R2, R6 + SGTU R2, R1, R7 + SUBU R7, R6, R8 +cmp_ret: + MOVW R8, ret+24(FP) + RET + +TEXT runtime·cmpstring(SB),NOSPLIT,$0-20 + MOVW a_base+0(FP), R3 + MOVW a_len+4(FP), R1 + MOVW b_base+8(FP), R4 + MOVW b_len+12(FP), R2 + BEQ R3, R4, samebytes + SGTU R1, R2, R7 + MOVW R1, R8 + CMOVN R7, R2, R8 // R8 is min(R1, R2) + + ADDU R3, R8 // R3 is current byte in a, R8 is last byte in a to compare +loop: + BEQ R3, R8, samebytes // all compared bytes were the same; compare lengths + + MOVBU (R3), R6 + ADDU $1, R3 + MOVBU (R4), R7 + ADDU $1, R4 + BEQ R6, R7 , loop + // bytes differed + SGTU R6, R7, R8 + MOVW $-1, R6 + CMOVZ R8, R6, R8 + JMP cmp_ret +samebytes: + SGTU R1, R2, R6 + SGTU R2, R1, R7 + SUBU R7, R6, R8 +cmp_ret: + MOVW R8, ret+16(FP) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_ppc64x.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_ppc64x.s new file mode 100644 index 00000000000..2629251e430 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_ppc64x.s @@ -0,0 +1,342 @@ +// Copyright 2018 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. + +//go:build ppc64 || ppc64le + +#include "go_asm.h" +#include "textflag.h" + +// Helper names for x-form loads in BE ordering. +#ifdef GOARCH_ppc64le +#define _LDBEX MOVDBR +#define _LWBEX MOVWBR +#define _LHBEX MOVHBR +#else +#define _LDBEX MOVD +#define _LWBEX MOVW +#define _LHBEX MOVH +#endif + +#ifdef GOPPC64_power9 +#define SETB_CR0(rout) SETB CR0, rout +#define SETB_CR1(rout) SETB CR1, rout +#define SETB_INIT() +#define SETB_CR0_NE(rout) SETB_CR0(rout) +#else +// A helper macro to emulate SETB on P8. This assumes +// -1 is in R20, and 1 is in R21. crxlt and crxeq must +// also be the same CR field. +#define _SETB(crxlt, crxeq, rout) \ + ISEL crxeq,R0,R21,rout \ + ISEL crxlt,R20,rout,rout + +// A special case when it is know the comparison +// will always be not equal. The result must be -1 or 1. +#define SETB_CR0_NE(rout) \ + ISEL CR0LT,R20,R21,rout + +#define SETB_CR0(rout) _SETB(CR0LT, CR0EQ, rout) +#define SETB_CR1(rout) _SETB(CR1LT, CR1EQ, rout) +#define SETB_INIT() \ + MOVD $-1,R20 \ + MOVD $1,R21 +#endif + +TEXT ·Compare<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-56 + // incoming: + // R3 a addr + // R4 a len + // R6 b addr + // R7 b len + // + // on entry to cmpbody: + // R3 return value if len(a) == len(b) + // R5 a addr + // R6 b addr + // R9 min(len(a),len(b)) + SETB_INIT() + MOVD R3,R5 + CMP R4,R7,CR0 + CMP R3,R6,CR7 + ISEL CR0LT,R4,R7,R9 + SETB_CR0(R3) + BC $12,30,LR // beqlr cr7 + BR cmpbody<>(SB) + +TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40 + // incoming: + // R3 a addr -> R5 + // R4 a len -> R3 + // R5 b addr -> R6 + // R6 b len -> R4 + // + // on entry to cmpbody: + // R3 compare value if compared length is same. + // R5 a addr + // R6 b addr + // R9 min(len(a),len(b)) + SETB_INIT() + CMP R4,R6,CR0 + CMP R3,R5,CR7 + ISEL CR0LT,R4,R6,R9 + MOVD R5,R6 + MOVD R3,R5 + SETB_CR0(R3) + BC $12,30,LR // beqlr cr7 + BR cmpbody<>(SB) + +#ifdef GOARCH_ppc64le +DATA byteswap<>+0(SB)/8, $0x0706050403020100 +DATA byteswap<>+8(SB)/8, $0x0f0e0d0c0b0a0908 +GLOBL byteswap<>+0(SB), RODATA, $16 +#define SWAP V21 +#endif + +TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0 +start: + CMP R9,$16,CR0 + CMP R9,$32,CR1 + CMP R9,$64,CR2 + MOVD $16,R10 + BLT cmp8 + BLT CR1,cmp16 + BLT CR2,cmp32 + +cmp64: // >= 64B + DCBT (R5) // optimize for size>=64 + DCBT (R6) // cache hint + + SRD $6,R9,R14 // There is at least one iteration. + MOVD R14,CTR + ANDCC $63,R9,R9 + CMP R9,$16,CR1 // Do setup for tail check early on. + CMP R9,$32,CR2 + CMP R9,$48,CR3 + ADD $-16,R9,R9 + + MOVD $32,R11 // set offsets to load into vector + MOVD $48,R12 // set offsets to load into vector + + PCALIGN $16 +cmp64_loop: + LXVD2X (R5)(R0),V3 // load bytes of A at offset 0 into vector + LXVD2X (R6)(R0),V4 // load bytes of B at offset 0 into vector + VCMPEQUDCC V3,V4,V1 + BGE CR6,different // jump out if its different + + LXVD2X (R5)(R10),V3 // load bytes of A at offset 16 into vector + LXVD2X (R6)(R10),V4 // load bytes of B at offset 16 into vector + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + LXVD2X (R5)(R11),V3 // load bytes of A at offset 32 into vector + LXVD2X (R6)(R11),V4 // load bytes of B at offset 32 into vector + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + LXVD2X (R5)(R12),V3 // load bytes of A at offset 64 into vector + LXVD2X (R6)(R12),V4 // load bytes of B at offset 64 into vector + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + ADD $64,R5,R5 // increment to next 64 bytes of A + ADD $64,R6,R6 // increment to next 64 bytes of B + BDNZ cmp64_loop + BC $12,2,LR // beqlr + + // Finish out tail with minimal overlapped checking. + // Note, 0 tail is handled by beqlr above. + BLE CR1,cmp64_tail_gt0 + BLE CR2,cmp64_tail_gt16 + BLE CR3,cmp64_tail_gt32 + +cmp64_tail_gt48: // 49 - 63 B + LXVD2X (R0)(R5),V3 + LXVD2X (R0)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + LXVD2X (R5)(R10),V3 + LXVD2X (R6)(R10),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + LXVD2X (R5)(R11),V3 + LXVD2X (R6)(R11),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + BR cmp64_tail_gt0 + + PCALIGN $16 +cmp64_tail_gt32: // 33 - 48B + LXVD2X (R0)(R5),V3 + LXVD2X (R0)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + LXVD2X (R5)(R10),V3 + LXVD2X (R6)(R10),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + BR cmp64_tail_gt0 + + PCALIGN $16 +cmp64_tail_gt16: // 17 - 32B + LXVD2X (R0)(R5),V3 + LXVD2X (R0)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + BR cmp64_tail_gt0 + + PCALIGN $16 +cmp64_tail_gt0: // 1 - 16B + LXVD2X (R5)(R9),V3 + LXVD2X (R6)(R9),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + RET + + PCALIGN $16 +cmp32: // 32 - 63B + ANDCC $31,R9,R9 + + LXVD2X (R0)(R5),V3 + LXVD2X (R0)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + LXVD2X (R10)(R5),V3 + LXVD2X (R10)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + BC $12,2,LR // beqlr + ADD R9,R10,R10 + + LXVD2X (R9)(R5),V3 + LXVD2X (R9)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + + LXVD2X (R10)(R5),V3 + LXVD2X (R10)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + RET + + PCALIGN $16 +cmp16: // 16 - 31B + ANDCC $15,R9,R9 + LXVD2X (R0)(R5),V3 + LXVD2X (R0)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + BC $12,2,LR // beqlr + + LXVD2X (R9)(R5),V3 + LXVD2X (R9)(R6),V4 + VCMPEQUDCC V3,V4,V1 + BGE CR6,different + RET + + PCALIGN $16 +different: +#ifdef GOARCH_ppc64le + MOVD $byteswap<>+00(SB),R16 + LXVD2X (R16)(R0),SWAP // Set up swap string + + VPERM V3,V3,SWAP,V3 + VPERM V4,V4,SWAP,V4 +#endif + + MFVSRD VS35,R16 // move upper doublewords of A and B into GPR for comparison + MFVSRD VS36,R10 + + CMPU R16,R10 + BEQ lower + SETB_CR0_NE(R3) + RET + + PCALIGN $16 +lower: + VSLDOI $8,V3,V3,V3 // move lower doublewords of A and B into GPR for comparison + MFVSRD VS35,R16 + VSLDOI $8,V4,V4,V4 + MFVSRD VS36,R10 + + CMPU R16,R10 + SETB_CR0_NE(R3) + RET + + PCALIGN $16 +cmp8: // 8 - 15B (0 - 15B if GOPPC64_power10) +#ifdef GOPPC64_power10 + SLD $56,R9,R9 + LXVLL R5,R9,V3 // Load bytes starting from MSB to LSB, unused are zero filled. + LXVLL R6,R9,V4 + VCMPUQ V3,V4,CR0 // Compare as a 128b integer. + SETB_CR0(R6) + ISEL CR0EQ,R3,R6,R3 // If equal, length determines the return value. + RET +#else + CMP R9,$8 + BLT cmp4 + ANDCC $7,R9,R9 + _LDBEX (R0)(R5),R10 + _LDBEX (R0)(R6),R11 + _LDBEX (R9)(R5),R12 + _LDBEX (R9)(R6),R14 + CMPU R10,R11,CR0 + SETB_CR0(R5) + CMPU R12,R14,CR1 + SETB_CR1(R6) + CRAND CR0EQ,CR1EQ,CR1EQ // If both equal, length determines return value. + ISEL CR0EQ,R6,R5,R4 + ISEL CR1EQ,R3,R4,R3 + RET + + PCALIGN $16 +cmp4: // 4 - 7B + CMP R9,$4 + BLT cmp2 + ANDCC $3,R9,R9 + _LWBEX (R0)(R5),R10 + _LWBEX (R0)(R6),R11 + _LWBEX (R9)(R5),R12 + _LWBEX (R9)(R6),R14 + RLDIMI $32,R10,$0,R12 + RLDIMI $32,R11,$0,R14 + CMPU R12,R14 + BR cmp0 + + PCALIGN $16 +cmp2: // 2 - 3B + CMP R9,$2 + BLT cmp1 + ANDCC $1,R9,R9 + _LHBEX (R0)(R5),R10 + _LHBEX (R0)(R6),R11 + _LHBEX (R9)(R5),R12 + _LHBEX (R9)(R6),R14 + RLDIMI $32,R10,$0,R12 + RLDIMI $32,R11,$0,R14 + CMPU R12,R14 + BR cmp0 + + PCALIGN $16 +cmp1: + CMP R9,$0 + BEQ cmp0 + MOVBZ (R5),R10 + MOVBZ (R6),R11 + CMPU R10,R11 +cmp0: + SETB_CR0(R6) + ISEL CR0EQ,R3,R6,R3 + RET +#endif diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_riscv64.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_riscv64.s new file mode 100644 index 00000000000..b1e1f7bcc76 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_riscv64.s @@ -0,0 +1,222 @@ +// Copyright 2022 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Compare<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-56 + // X10 = a_base + // X11 = a_len + // X12 = a_cap (unused) + // X13 = b_base (want in X12) + // X14 = b_len (want in X13) + // X15 = b_cap (unused) + MOV X13, X12 + MOV X14, X13 + JMP compare<>(SB) + +TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40 + // X10 = a_base + // X11 = a_len + // X12 = b_base + // X13 = b_len + JMP compare<>(SB) + +// On entry: +// X10 points to start of a +// X11 length of a +// X12 points to start of b +// X13 length of b +// for non-regabi X14 points to the address to store the return value (-1/0/1) +// for regabi the return value in X10 +TEXT compare<>(SB),NOSPLIT|NOFRAME,$0 + BEQ X10, X12, cmp_len + + MOV X11, X5 + BGE X13, X5, use_a_len // X5 = min(len(a), len(b)) + MOV X13, X5 +use_a_len: + BEQZ X5, cmp_len + + MOV $32, X6 + BLT X5, X6, check8_unaligned + + // Check alignment - if alignment differs we have to do one byte at a time. + AND $7, X10, X7 + AND $7, X12, X8 + BNE X7, X8, check8_unaligned + BEQZ X7, compare32 + + // Check one byte at a time until we reach 8 byte alignment. + SUB X7, X0, X7 + ADD $8, X7, X7 + SUB X7, X5, X5 +align: + SUB $1, X7 + MOVBU 0(X10), X8 + MOVBU 0(X12), X9 + BNE X8, X9, cmp + ADD $1, X10 + ADD $1, X12 + BNEZ X7, align + +check32: + // X6 contains $32 + BLT X5, X6, compare16 +compare32: + MOV 0(X10), X15 + MOV 0(X12), X16 + MOV 8(X10), X17 + MOV 8(X12), X18 + BNE X15, X16, cmp8a + BNE X17, X18, cmp8b + MOV 16(X10), X15 + MOV 16(X12), X16 + MOV 24(X10), X17 + MOV 24(X12), X18 + BNE X15, X16, cmp8a + BNE X17, X18, cmp8b + ADD $32, X10 + ADD $32, X12 + SUB $32, X5 + BGE X5, X6, compare32 + BEQZ X5, cmp_len + +check16: + MOV $16, X6 + BLT X5, X6, check8_unaligned +compare16: + MOV 0(X10), X15 + MOV 0(X12), X16 + MOV 8(X10), X17 + MOV 8(X12), X18 + BNE X15, X16, cmp8a + BNE X17, X18, cmp8b + ADD $16, X10 + ADD $16, X12 + SUB $16, X5 + BEQZ X5, cmp_len + +check8_unaligned: + MOV $8, X6 + BLT X5, X6, check4_unaligned +compare8_unaligned: + MOVBU 0(X10), X8 + MOVBU 1(X10), X15 + MOVBU 2(X10), X17 + MOVBU 3(X10), X19 + MOVBU 4(X10), X21 + MOVBU 5(X10), X23 + MOVBU 6(X10), X25 + MOVBU 7(X10), X29 + MOVBU 0(X12), X9 + MOVBU 1(X12), X16 + MOVBU 2(X12), X18 + MOVBU 3(X12), X20 + MOVBU 4(X12), X22 + MOVBU 5(X12), X24 + MOVBU 6(X12), X28 + MOVBU 7(X12), X30 + BNE X8, X9, cmp1a + BNE X15, X16, cmp1b + BNE X17, X18, cmp1c + BNE X19, X20, cmp1d + BNE X21, X22, cmp1e + BNE X23, X24, cmp1f + BNE X25, X28, cmp1g + BNE X29, X30, cmp1h + ADD $8, X10 + ADD $8, X12 + SUB $8, X5 + BGE X5, X6, compare8_unaligned + BEQZ X5, cmp_len + +check4_unaligned: + MOV $4, X6 + BLT X5, X6, compare1 +compare4_unaligned: + MOVBU 0(X10), X8 + MOVBU 1(X10), X15 + MOVBU 2(X10), X17 + MOVBU 3(X10), X19 + MOVBU 0(X12), X9 + MOVBU 1(X12), X16 + MOVBU 2(X12), X18 + MOVBU 3(X12), X20 + BNE X8, X9, cmp1a + BNE X15, X16, cmp1b + BNE X17, X18, cmp1c + BNE X19, X20, cmp1d + ADD $4, X10 + ADD $4, X12 + SUB $4, X5 + BGE X5, X6, compare4_unaligned + +compare1: + BEQZ X5, cmp_len + MOVBU 0(X10), X8 + MOVBU 0(X12), X9 + BNE X8, X9, cmp + ADD $1, X10 + ADD $1, X12 + SUB $1, X5 + JMP compare1 + + // Compare 8 bytes of memory in X15/X16 that are known to differ. +cmp8a: + MOV X15, X17 + MOV X16, X18 + + // Compare 8 bytes of memory in X17/X18 that are known to differ. +cmp8b: + MOV $0xff, X19 +cmp8_loop: + AND X17, X19, X8 + AND X18, X19, X9 + BNE X8, X9, cmp + SLLI $8, X19 + JMP cmp8_loop + +cmp1a: + SLTU X9, X8, X5 + SLTU X8, X9, X6 + JMP cmp_ret +cmp1b: + SLTU X16, X15, X5 + SLTU X15, X16, X6 + JMP cmp_ret +cmp1c: + SLTU X18, X17, X5 + SLTU X17, X18, X6 + JMP cmp_ret +cmp1d: + SLTU X20, X19, X5 + SLTU X19, X20, X6 + JMP cmp_ret +cmp1e: + SLTU X22, X21, X5 + SLTU X21, X22, X6 + JMP cmp_ret +cmp1f: + SLTU X24, X23, X5 + SLTU X23, X24, X6 + JMP cmp_ret +cmp1g: + SLTU X28, X25, X5 + SLTU X25, X28, X6 + JMP cmp_ret +cmp1h: + SLTU X30, X29, X5 + SLTU X29, X30, X6 + JMP cmp_ret + +cmp_len: + MOV X11, X8 + MOV X13, X9 +cmp: + SLTU X9, X8, X5 + SLTU X8, X9, X6 +cmp_ret: + SUB X5, X6, X10 + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_s390x.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_s390x.s new file mode 100644 index 00000000000..539454870d3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_s390x.s @@ -0,0 +1,69 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-56 + MOVD a_base+0(FP), R3 + MOVD a_len+8(FP), R4 + MOVD b_base+24(FP), R5 + MOVD b_len+32(FP), R6 + LA ret+48(FP), R7 + BR cmpbody<>(SB) + +TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-40 + MOVD a_base+0(FP), R3 + MOVD a_len+8(FP), R4 + MOVD b_base+16(FP), R5 + MOVD b_len+24(FP), R6 + LA ret+32(FP), R7 + BR cmpbody<>(SB) + +// input: +// R3 = a +// R4 = alen +// R5 = b +// R6 = blen +// R7 = address of output word (stores -1/0/1 here) +TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0 + CMPBEQ R3, R5, cmplengths + MOVD R4, R8 + CMPBLE R4, R6, amin + MOVD R6, R8 +amin: + CMPBEQ R8, $0, cmplengths + CMP R8, $256 + BLE tail +loop: + CLC $256, 0(R3), 0(R5) + BGT gt + BLT lt + SUB $256, R8 + MOVD $256(R3), R3 + MOVD $256(R5), R5 + CMP R8, $256 + BGT loop +tail: + SUB $1, R8 + EXRL $cmpbodyclc<>(SB), R8 + BGT gt + BLT lt +cmplengths: + CMP R4, R6 + BEQ eq + BLT lt +gt: + MOVD $1, 0(R7) + RET +lt: + MOVD $-1, 0(R7) + RET +eq: + MOVD $0, 0(R7) + RET + +TEXT cmpbodyclc<>(SB),NOSPLIT|NOFRAME,$0-0 + CLC $1, 0(R3), 0(R5) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/compare_wasm.s b/contrib/go/_std_1.22/src/internal/bytealg/compare_wasm.s new file mode 100644 index 00000000000..dc8fb33cfb3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/compare_wasm.s @@ -0,0 +1,115 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Compare(SB), NOSPLIT, $0-56 + Get SP + I64Load a_base+0(FP) + I64Load a_len+8(FP) + I64Load b_base+24(FP) + I64Load b_len+32(FP) + Call cmpbody<>(SB) + I64Store ret+48(FP) + RET + +TEXT runtime·cmpstring(SB), NOSPLIT, $0-40 + Get SP + I64Load a_base+0(FP) + I64Load a_len+8(FP) + I64Load b_base+16(FP) + I64Load b_len+24(FP) + Call cmpbody<>(SB) + I64Store ret+32(FP) + RET + +// params: a, alen, b, blen +// ret: -1/0/1 +TEXT cmpbody<>(SB), NOSPLIT, $0-0 + // len = min(alen, blen) + Get R1 + Get R3 + Get R1 + Get R3 + I64LtU + Select + Set R4 + + Get R0 + I32WrapI64 + Get R2 + I32WrapI64 + Get R4 + I32WrapI64 + Call memcmp<>(SB) + I64ExtendI32S + Tee R5 + + I64Eqz + If + // check length + Get R1 + Get R3 + I64Sub + Set R5 + End + + I64Const $0 + I64Const $-1 + I64Const $1 + Get R5 + I64Const $0 + I64LtS + Select + Get R5 + I64Eqz + Select + Return + +// compiled with emscripten +// params: a, b, len +// ret: <0/0/>0 +TEXT memcmp<>(SB), NOSPLIT, $0-0 + Get R2 + If $1 + Loop + Get R0 + I32Load8S $0 + Tee R3 + Get R1 + I32Load8S $0 + Tee R4 + I32Eq + If + Get R0 + I32Const $1 + I32Add + Set R0 + Get R1 + I32Const $1 + I32Add + Set R1 + I32Const $0 + Get R2 + I32Const $-1 + I32Add + Tee R2 + I32Eqz + BrIf $3 + Drop + Br $1 + End + End + Get R3 + I32Const $255 + I32And + Get R4 + I32Const $255 + I32And + I32Sub + Else + I32Const $0 + End + Return diff --git a/contrib/go/_std_1.22/src/internal/bytealg/count_arm.s b/contrib/go/_std_1.22/src/internal/bytealg/count_arm.s new file mode 100644 index 00000000000..f704ea0c69e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/count_arm.s @@ -0,0 +1,43 @@ +// Copyright 2019 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Count(SB),NOSPLIT,$0-20 + MOVW b_base+0(FP), R0 + MOVW b_len+4(FP), R1 + MOVBU c+12(FP), R2 + MOVW $ret+16(FP), R7 + B countbytebody<>(SB) + +TEXT ·CountString(SB),NOSPLIT,$0-16 + MOVW s_base+0(FP), R0 + MOVW s_len+4(FP), R1 + MOVBU c+8(FP), R2 + MOVW $ret+12(FP), R7 + B countbytebody<>(SB) + +// Input: +// R0: data +// R1: data length +// R2: byte to find +// R7: address to put result +// +// On exit: +// R4 and R8 are clobbered +TEXT countbytebody<>(SB),NOSPLIT,$0 + MOVW $0, R8 // R8 = count of byte to search + CMP $0, R1 + B.EQ done // short path to handle 0-byte case + ADD R0, R1 // R1 is the end of the range +byte_loop: + MOVBU.P 1(R0), R4 + CMP R4, R2 + ADD.EQ $1, R8 + CMP R0, R1 + B.NE byte_loop +done: + MOVW R8, (R7) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/count_generic.go b/contrib/go/_std_1.22/src/internal/bytealg/count_generic.go new file mode 100644 index 00000000000..932a7c584c1 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/count_generic.go @@ -0,0 +1,27 @@ +// Copyright 2018 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. + +//go:build !amd64 && !arm && !arm64 && !ppc64le && !ppc64 && !riscv64 && !s390x + +package bytealg + +func Count(b []byte, c byte) int { + n := 0 + for _, x := range b { + if x == c { + n++ + } + } + return n +} + +func CountString(s string, c byte) int { + n := 0 + for i := 0; i < len(s); i++ { + if s[i] == c { + n++ + } + } + return n +} diff --git a/contrib/go/_std_1.22/src/internal/bytealg/count_ppc64x.s b/contrib/go/_std_1.22/src/internal/bytealg/count_ppc64x.s new file mode 100644 index 00000000000..55e02ce8a18 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/count_ppc64x.s @@ -0,0 +1,154 @@ +// Copyright 2018 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. + +//go:build ppc64le || ppc64 + +#include "go_asm.h" +#include "textflag.h" + +TEXT ·Count<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40 + // R3 = byte array pointer + // R4 = length + // R6 = byte to count + MTVRD R6, V1 // move compare byte + MOVD R6, R5 + VSPLTB $7, V1, V1 // replicate byte across V1 + BR countbytebody<>(SB) + +TEXT ·CountString<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-32 + // R3 = byte array pointer + // R4 = length + // R5 = byte to count + MTVRD R5, V1 // move compare byte + VSPLTB $7, V1, V1 // replicate byte across V1 + BR countbytebody<>(SB) + +// R3: addr of string +// R4: len of string +// R5: byte to count +// V1: byte to count, splatted. +// On exit: +// R3: return value +TEXT countbytebody<>(SB), NOSPLIT|NOFRAME, $0-0 + MOVD $0, R18 // byte count + +#ifndef GOPPC64_power10 + RLDIMI $8, R5, $48, R5 + RLDIMI $16, R5, $32, R5 + RLDIMI $32, R5, $0, R5 // fill reg with the byte to count +#endif + + CMPU R4, $32 // Check if it's a small string (<32 bytes) + BLT tail // Jump to the small string case + SRD $5, R4, R20 + MOVD R20, CTR + MOVD $16, R21 + XXLXOR V4, V4, V4 + XXLXOR V5, V5, V5 + + PCALIGN $16 +cmploop: + LXVD2X (R0)(R3), V0 // Count 32B per loop with two vector accumulators. + LXVD2X (R21)(R3), V2 + VCMPEQUB V2, V1, V2 + VCMPEQUB V0, V1, V0 + VPOPCNTD V2, V2 // A match is 0xFF or 0. Count the bits into doubleword buckets. + VPOPCNTD V0, V0 + VADDUDM V0, V4, V4 // Accumulate the popcounts. They are 8x the count. + VADDUDM V2, V5, V5 // The count will be fixed up afterwards. + ADD $32, R3 + BDNZ cmploop + + VADDUDM V4, V5, V5 + MFVSRD V5, R18 + VSLDOI $8, V5, V5, V5 + MFVSRD V5, R21 + ADD R21, R18, R18 + ANDCC $31, R4, R4 + // Skip the tail processing if no bytes remaining. + BEQ tail_0 + +#ifdef GOPPC64_power10 + SRD $3, R18, R18 // Fix the vector loop count before counting the tail on P10. + +tail: // Count the last 0 - 31 bytes. + CMP R4, $16 + BLE small_tail_p10 + LXV 0(R3), V0 + VCMPEQUB V0, V1, V0 + VCNTMBB V0, $1, R14 // Sum the value of bit 0 of each byte of the compare into R14. + SRD $56, R14, R14 // The result of VCNTMBB is shifted. Unshift it. + ADD R14, R18, R18 + ADD $16, R3, R3 + ANDCC $15, R4, R4 + +small_tail_p10: + SLD $56, R4, R6 + LXVLL R3, R6, V0 + VCMPEQUB V0, V1, V0 + VCLRRB V0, R4, V0 // If <16B being compared, clear matches of the 16-R4 bytes. + VCNTMBB V0, $1, R14 // Sum the value of bit 0 of each byte of the compare into R14. + SRD $56, R14, R14 // The result of VCNTMBB is shifted. Unshift it. + ADD R14, R18, R3 + RET + +#else +tail: // Count the last 0 - 31 bytes. + CMP R4, $16 + BLT tail_8 + MOVD (R3), R12 + MOVD 8(R3), R14 + CMPB R12, R5, R12 + CMPB R14, R5, R14 + POPCNTD R12, R12 + POPCNTD R14, R14 + ADD R12, R18, R18 + ADD R14, R18, R18 + ADD $16, R3, R3 + ADD $-16, R4, R4 + +tail_8: // Count the remaining 0 - 15 bytes. + CMP R4, $8 + BLT tail_4 + MOVD (R3), R12 + CMPB R12, R5, R12 + POPCNTD R12, R12 + ADD R12, R18, R18 + ADD $8, R3, R3 + ADD $-8, R4, R4 + +tail_4: // Count the remaining 0 - 7 bytes. + CMP R4, $4 + BLT tail_2 + MOVWZ (R3), R12 + CMPB R12, R5, R12 + SLD $32, R12, R12 // Remove non-participating matches. + POPCNTD R12, R12 + ADD R12, R18, R18 + ADD $4, R3, R3 + ADD $-4, R4, R4 + +tail_2: // Count the remaining 0 - 3 bytes. + CMP R4, $2 + BLT tail_1 + MOVHZ (R3), R12 + CMPB R12, R5, R12 + SLD $48, R12, R12 // Remove non-participating matches. + POPCNTD R12, R12 + ADD R12, R18, R18 + ADD $2, R3, R3 + ADD $-2, R4, R4 + +tail_1: // Count the remaining 0 - 1 bytes. + CMP R4, $1 + BLT tail_0 + MOVBZ (R3), R12 + CMPB R12, R5, R12 + ANDCC $0x8, R12, R12 + ADD R12, R18, R18 +#endif + +tail_0: // No remaining tail to count. + SRD $3, R18, R3 // Fixup count, it is off by 8x. + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/count_riscv64.s b/contrib/go/_std_1.22/src/internal/bytealg/count_riscv64.s new file mode 100644 index 00000000000..3f255cd2630 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/count_riscv64.s @@ -0,0 +1,49 @@ +// Copyright 2020 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Count<ABIInternal>(SB),NOSPLIT,$0-40 + // X10 = b_base + // X11 = b_len + // X12 = b_cap (unused) + // X13 = byte to count (want in X12) + AND $0xff, X13, X12 + MOV ZERO, X14 // count + ADD X10, X11 // end + + PCALIGN $16 +loop: + BEQ X10, X11, done + MOVBU (X10), X15 + ADD $1, X10 + BNE X12, X15, loop + ADD $1, X14 + JMP loop + +done: + MOV X14, X10 + RET + +TEXT ·CountString<ABIInternal>(SB),NOSPLIT,$0-32 + // X10 = s_base + // X11 = s_len + // X12 = byte to count + AND $0xff, X12 + MOV ZERO, X14 // count + ADD X10, X11 // end + + PCALIGN $16 +loop: + BEQ X10, X11, done + MOVBU (X10), X15 + ADD $1, X10 + BNE X12, X15, loop + ADD $1, X14 + JMP loop + +done: + MOV X14, X10 + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/count_s390x.s b/contrib/go/_std_1.22/src/internal/bytealg/count_s390x.s new file mode 100644 index 00000000000..2a3b5c03e94 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/count_s390x.s @@ -0,0 +1,169 @@ +// Copyright 2019 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 "go_asm.h" +#include "textflag.h" + +// condition code masks +#define EQ 8 +#define NE 7 + +// register assignments +#define R_ZERO R0 +#define R_VAL R1 +#define R_TMP R2 +#define R_PTR R3 +#define R_LEN R4 +#define R_CHAR R5 +#define R_RET R6 +#define R_ITER R7 +#define R_CNT R8 +#define R_MPTR R9 + +// vector register assignments +#define V_ZERO V0 +#define V_CHAR V1 +#define V_MASK V2 +#define V_VAL V3 +#define V_CNT V4 + +// mask for trailing bytes in vector implementation +GLOBL countbytemask<>(SB), RODATA, $16 +DATA countbytemask<>+0(SB)/8, $0x0101010101010101 +DATA countbytemask<>+8(SB)/8, $0x0101010101010101 + +// func Count(b []byte, c byte) int +TEXT ·Count(SB), NOSPLIT|NOFRAME, $0-40 + LMG b+0(FP), R_PTR, R_LEN + MOVBZ c+24(FP), R_CHAR + MOVD $ret+32(FP), R_RET + BR countbytebody<>(SB) + +// func CountString(s string, c byte) int +TEXT ·CountString(SB), NOSPLIT|NOFRAME, $0-32 + LMG s+0(FP), R_PTR, R_LEN + MOVBZ c+16(FP), R_CHAR + MOVD $ret+24(FP), R_RET + BR countbytebody<>(SB) + +// input: +// R_PTR = address of array of bytes +// R_LEN = number of bytes in array +// R_CHAR = byte value to count zero (extended to register width) +// R_RET = address of return value +TEXT countbytebody<>(SB), NOSPLIT|NOFRAME, $0-0 + MOVD $internal∕cpu·S390X+const_offsetS390xHasVX(SB), R_TMP + MOVD $countbytemask<>(SB), R_MPTR + CGIJ $EQ, R_LEN, $0, ret0 // return if length is 0. + SRD $4, R_LEN, R_ITER // R_ITER is the number of 16-byte chunks + MOVBZ (R_TMP), R_TMP // load bool indicating support for vector facility + CGIJ $EQ, R_TMP, $0, novx // jump to scalar code if the vector facility is not available + + // Start of vector code (have vector facility). + // + // Set R_LEN to be the length mod 16 minus 1 to use as an index for + // vector 'load with length' (VLL). It will be in the range [-1,14]. + // Also replicate c across a 16-byte vector and initialize V_ZERO. + ANDW $0xf, R_LEN + VLVGB $0, R_CHAR, V_CHAR // V_CHAR = [16]byte{c, 0, ..., 0, 0} + VZERO V_ZERO // V_ZERO = [1]uint128{0} + ADDW $-1, R_LEN + VREPB $0, V_CHAR, V_CHAR // V_CHAR = [16]byte{c, c, ..., c, c} + + // Jump to loop if we have more than 15 bytes to process. + CGIJ $NE, R_ITER, $0, vxchunks + + // Load 1-15 bytes and corresponding mask. + // Note: only the low 32-bits of R_LEN are used for the index. + VLL R_LEN, (R_PTR), V_VAL + VLL R_LEN, (R_MPTR), V_MASK + + // Compare each byte in input chunk against byte to be counted. + // Each byte element will be set to either 0 (no match) or 1 (match). + VCEQB V_CHAR, V_VAL, V_VAL // each byte will be either 0xff or 0x00 + VN V_MASK, V_VAL, V_VAL // mask out most significant 7 bits + + // Accumulate matched byte count in 128-bit integer value. + VSUMB V_VAL, V_ZERO, V_VAL // [16]byte{x0, x1, ..., x14, x15} → [4]uint32{x0+x1+x2+x3, ..., x12+x13+x14+x15} + VSUMQF V_VAL, V_ZERO, V_CNT // [4]uint32{x0, x1, x2, x3} → [1]uint128{x0+x1+x2+x3} + + // Return rightmost (lowest) 64-bit part of accumulator. + VSTEG $1, V_CNT, (R_RET) + RET + +vxchunks: + // Load 0x01 into every byte element in the 16-byte mask vector. + VREPIB $1, V_MASK // V_MASK = [16]byte{1, 1, ..., 1, 1} + VZERO V_CNT // initial uint128 count of 0 + +vxloop: + // Load input bytes in 16-byte chunks. + VL (R_PTR), V_VAL + + // Compare each byte in input chunk against byte to be counted. + // Each byte element will be set to either 0 (no match) or 1 (match). + VCEQB V_CHAR, V_VAL, V_VAL // each byte will be either 0xff or 0x00 + VN V_MASK, V_VAL, V_VAL // mask out most significant 7 bits + + // Increment input string address. + MOVD $16(R_PTR), R_PTR + + // Accumulate matched byte count in 128-bit integer value. + VSUMB V_VAL, V_ZERO, V_VAL // [16]byte{x0, x1, ..., x14, x15} → [4]uint32{x0+x1+x2+x3, ..., x12+x13+x14+x15} + VSUMQF V_VAL, V_ZERO, V_VAL // [4]uint32{x0, x1, x2, x3} → [1]uint128{x0+x1+x2+x3} + VAQ V_VAL, V_CNT, V_CNT // accumulate + + // Repeat until all 16-byte chunks are done. + BRCTG R_ITER, vxloop + + // Skip to end if there are no trailing bytes. + CIJ $EQ, R_LEN, $-1, vxret + + // Load 1-15 bytes and corresponding mask. + // Note: only the low 32-bits of R_LEN are used for the index. + VLL R_LEN, (R_PTR), V_VAL + VLL R_LEN, (R_MPTR), V_MASK + + // Compare each byte in input chunk against byte to be counted. + // Each byte element will be set to either 0 (no match) or 1 (match). + VCEQB V_CHAR, V_VAL, V_VAL + VN V_MASK, V_VAL, V_VAL + + // Accumulate matched byte count in 128-bit integer value. + VSUMB V_VAL, V_ZERO, V_VAL // [16]byte{x0, x1, ..., x14, x15} → [4]uint32{x0+x1+x2+x3, ..., x12+x13+x14+x15} + VSUMQF V_VAL, V_ZERO, V_VAL // [4]uint32{x0, x1, x2, x3} → [1]uint128{x0+x1+x2+x3} + VAQ V_VAL, V_CNT, V_CNT // accumulate + +vxret: + // Return rightmost (lowest) 64-bit part of accumulator. + VSTEG $1, V_CNT, (R_RET) + RET + +novx: + // Start of non-vector code (the vector facility not available). + // + // Initialise counter and constant zero. + MOVD $0, R_CNT + MOVD $0, R_ZERO + +loop: + // Read 1-byte from input and compare. + // Note: avoid putting LOCGR in critical path. + MOVBZ (R_PTR), R_VAL + MOVD $1, R_TMP + MOVD $1(R_PTR), R_PTR + CMPW R_VAL, R_CHAR + LOCGR $NE, R_ZERO, R_TMP // select 0 if no match (1 if there is a match) + ADD R_TMP, R_CNT // accumulate 64-bit result + + // Repeat until all bytes have been checked. + BRCTG R_LEN, loop + +ret: + MOVD R_CNT, (R_RET) + RET + +ret0: + MOVD $0, (R_RET) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_386.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_386.s new file mode 100644 index 00000000000..58b3cbe3d07 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_386.s @@ -0,0 +1,130 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +// memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal(SB),NOSPLIT,$0-13 + MOVL a+0(FP), SI + MOVL b+4(FP), DI + CMPL SI, DI + JEQ eq + MOVL size+8(FP), BX + LEAL ret+12(FP), AX + JMP memeqbody<>(SB) +eq: + MOVB $1, ret+12(FP) + RET + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-9 + MOVL a+0(FP), SI + MOVL b+4(FP), DI + CMPL SI, DI + JEQ eq + MOVL 4(DX), BX // compiler stores size at offset 4 in the closure + LEAL ret+8(FP), AX + JMP memeqbody<>(SB) +eq: + MOVB $1, ret+8(FP) + RET + +// a in SI +// b in DI +// count in BX +// address of result byte in AX +TEXT memeqbody<>(SB),NOSPLIT,$0-0 + CMPL BX, $4 + JB small + + // 64 bytes at a time using xmm registers +hugeloop: + CMPL BX, $64 + JB bigloop +#ifdef GO386_softfloat + JMP bigloop +#endif + MOVOU (SI), X0 + MOVOU (DI), X1 + MOVOU 16(SI), X2 + MOVOU 16(DI), X3 + MOVOU 32(SI), X4 + MOVOU 32(DI), X5 + MOVOU 48(SI), X6 + MOVOU 48(DI), X7 + PCMPEQB X1, X0 + PCMPEQB X3, X2 + PCMPEQB X5, X4 + PCMPEQB X7, X6 + PAND X2, X0 + PAND X6, X4 + PAND X4, X0 + PMOVMSKB X0, DX + ADDL $64, SI + ADDL $64, DI + SUBL $64, BX + CMPL DX, $0xffff + JEQ hugeloop + MOVB $0, (AX) + RET + + // 4 bytes at a time using 32-bit register +bigloop: + CMPL BX, $4 + JBE leftover + MOVL (SI), CX + MOVL (DI), DX + ADDL $4, SI + ADDL $4, DI + SUBL $4, BX + CMPL CX, DX + JEQ bigloop + MOVB $0, (AX) + RET + + // remaining 0-4 bytes +leftover: + MOVL -4(SI)(BX*1), CX + MOVL -4(DI)(BX*1), DX + CMPL CX, DX + SETEQ (AX) + RET + +small: + CMPL BX, $0 + JEQ equal + + LEAL 0(BX*8), CX + NEGL CX + + MOVL SI, DX + CMPB DX, $0xfc + JA si_high + + // load at SI won't cross a page boundary. + MOVL (SI), SI + JMP si_finish +si_high: + // address ends in 111111xx. Load up to bytes we want, move to correct position. + MOVL -4(SI)(BX*1), SI + SHRL CX, SI +si_finish: + + // same for DI. + MOVL DI, DX + CMPB DX, $0xfc + JA di_high + MOVL (DI), DI + JMP di_finish +di_high: + MOVL -4(DI)(BX*1), DI + SHRL CX, DI +di_finish: + + SUBL SI, DI + SHLL CX, DI +equal: + SETEQ (AX) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_arm.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_arm.s new file mode 100644 index 00000000000..a6c43696034 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_arm.s @@ -0,0 +1,91 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +// memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-13 + MOVW a+0(FP), R0 + MOVW b+4(FP), R2 + CMP R0, R2 + B.EQ eq + MOVW size+8(FP), R1 + CMP $0, R1 + B.EQ eq // short path to handle 0-byte case + MOVW $ret+12(FP), R7 + B memeqbody<>(SB) +eq: + MOVW $1, R0 + MOVB R0, ret+12(FP) + RET + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen(SB),NOSPLIT|NOFRAME,$0-9 + MOVW a+0(FP), R0 + MOVW b+4(FP), R2 + CMP R0, R2 + B.EQ eq + MOVW 4(R7), R1 // compiler stores size at offset 4 in the closure + CMP $0, R1 + B.EQ eq // short path to handle 0-byte case + MOVW $ret+8(FP), R7 + B memeqbody<>(SB) +eq: + MOVW $1, R0 + MOVB R0, ret+8(FP) + RET + +// Input: +// R0: data of a +// R1: length +// R2: data of b +// R7: points to return value +// +// On exit: +// R4, R5 and R6 are clobbered +TEXT memeqbody<>(SB),NOSPLIT|NOFRAME,$0-0 + CMP $1, R1 + B.EQ one // 1-byte special case for better performance + + CMP $4, R1 + ADD R0, R1 // R1 is the end of the range to compare + B.LT byte_loop // length < 4 + AND $3, R0, R6 + CMP $0, R6 + B.NE byte_loop // unaligned a, use byte-wise compare (TODO: try to align a) + AND $3, R2, R6 + CMP $0, R6 + B.NE byte_loop // unaligned b, use byte-wise compare + AND $0xfffffffc, R1, R6 + // length >= 4 +chunk4_loop: + MOVW.P 4(R0), R4 + MOVW.P 4(R2), R5 + CMP R4, R5 + B.NE notequal + CMP R0, R6 + B.NE chunk4_loop + CMP R0, R1 + B.EQ equal // reached the end +byte_loop: + MOVBU.P 1(R0), R4 + MOVBU.P 1(R2), R5 + CMP R4, R5 + B.NE notequal + CMP R0, R1 + B.NE byte_loop +equal: + MOVW $1, R0 + MOVB R0, (R7) + RET +one: + MOVBU (R0), R4 + MOVBU (R2), R5 + CMP R4, R5 + B.EQ equal +notequal: + MOVW $0, R0 + MOVB R0, (R7) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_loong64.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_loong64.s new file mode 100644 index 00000000000..a3ad5c1b35b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_loong64.s @@ -0,0 +1,68 @@ +// Copyright 2022 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 "go_asm.h" +#include "textflag.h" + +#define REGCTXT R29 + +// memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25 +#ifndef GOEXPERIMENT_regabiargs + MOVV a+0(FP), R4 + MOVV b+8(FP), R5 + MOVV size+16(FP), R6 +#endif + BEQ R4, R5, eq + ADDV R4, R6, R7 + PCALIGN $16 +loop: + BNE R4, R7, test + MOVV $1, R4 +#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+24(FP) +#endif + RET +test: + MOVBU (R4), R9 + ADDV $1, R4 + MOVBU (R5), R10 + ADDV $1, R5 + BEQ R9, R10, loop + + MOVB R0, R4 +#ifndef GOEXPERIMENT_regabiargs + MOVB R0, ret+24(FP) +#endif + RET +eq: + MOVV $1, R4 +#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+24(FP) +#endif + RET + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT,$40-17 +#ifndef GOEXPERIMENT_regabiargs + MOVV a+0(FP), R4 + MOVV b+8(FP), R5 +#endif + BEQ R4, R5, eq + MOVV 8(REGCTXT), R6 // compiler stores size at offset 8 in the closure + MOVV R4, 8(R3) + MOVV R5, 16(R3) + MOVV R6, 24(R3) + JAL runtime·memequal(SB) + MOVBU 32(R3), R4 +#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+16(FP) +#endif + RET +eq: + MOVV $1, R4 +#ifndef GOEXPERIMENT_regabiargs + MOVB R4, ret+16(FP) +#endif + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_mips64x.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_mips64x.s new file mode 100644 index 00000000000..d92f225e8d2 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_mips64x.s @@ -0,0 +1,118 @@ +// Copyright 2018 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. + +//go:build mips64 || mips64le + +#include "go_asm.h" +#include "textflag.h" + +#define REGCTXT R22 + +// memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 + MOVV a+0(FP), R1 + MOVV b+8(FP), R2 + BEQ R1, R2, eq + MOVV size+16(FP), R3 + ADDV R1, R3, R4 + + // chunk size is 16 + SGTU $16, R3, R8 + BEQ R0, R8, chunk_entry + +byte_loop: + BNE R1, R4, byte_test + MOVV $1, R1 + MOVB R1, ret+24(FP) + RET +byte_test: + MOVBU (R1), R6 + ADDV $1, R1 + MOVBU (R2), R7 + ADDV $1, R2 + BEQ R6, R7, byte_loop + JMP not_eq + +chunk_entry: + // make sure both a and b are aligned + OR R1, R2, R9 + AND $0x7, R9 + BNE R0, R9, byte_loop + JMP chunk_loop_1 + +chunk_loop: + // chunk size is 16 + SGTU $16, R3, R8 + BNE R0, R8, chunk_tail_8 +chunk_loop_1: + MOVV (R1), R6 + MOVV (R2), R7 + BNE R6, R7, not_eq + MOVV 8(R1), R12 + MOVV 8(R2), R13 + ADDV $16, R1 + ADDV $16, R2 + SUBV $16, R3 + BEQ R12, R13, chunk_loop + JMP not_eq + +chunk_tail_8: + AND $8, R3, R14 + BEQ R0, R14, chunk_tail_4 + MOVV (R1), R6 + MOVV (R2), R7 + BNE R6, R7, not_eq + ADDV $8, R1 + ADDV $8, R2 + +chunk_tail_4: + AND $4, R3, R14 + BEQ R0, R14, chunk_tail_2 + MOVWU (R1), R6 + MOVWU (R2), R7 + BNE R6, R7, not_eq + ADDV $4, R1 + ADDV $4, R2 + +chunk_tail_2: + AND $2, R3, R14 + BEQ R0, R14, chunk_tail_1 + MOVHU (R1), R6 + MOVHU (R2), R7 + BNE R6, R7, not_eq + ADDV $2, R1 + ADDV $2, R2 + +chunk_tail_1: + AND $1, R3, R14 + BEQ R0, R14, eq + MOVBU (R1), R6 + MOVBU (R2), R7 + BEQ R6, R7, eq + +not_eq: + MOVB R0, ret+24(FP) + RET +eq: + MOVV $1, R1 + MOVB R1, ret+24(FP) + RET + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 + MOVV a+0(FP), R1 + MOVV b+8(FP), R2 + BEQ R1, R2, eq + MOVV 8(REGCTXT), R3 // compiler stores size at offset 8 in the closure + MOVV R1, 8(R29) + MOVV R2, 16(R29) + MOVV R3, 24(R29) + JAL runtime·memequal(SB) + MOVBU 32(R29), R1 + MOVB R1, ret+16(FP) + RET +eq: + MOVV $1, R1 + MOVB R1, ret+16(FP) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_mipsx.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_mipsx.s new file mode 100644 index 00000000000..4c46dd4fce4 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_mipsx.s @@ -0,0 +1,62 @@ +// Copyright 2018 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. + +//go:build mips || mipsle + +#include "go_asm.h" +#include "textflag.h" + +#define REGCTXT R22 + +// memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal(SB),NOSPLIT,$0-13 + MOVW a+0(FP), R1 + MOVW b+4(FP), R2 + BEQ R1, R2, eq + MOVW size+8(FP), R3 + ADDU R1, R3, R4 +loop: + BNE R1, R4, test + MOVW $1, R1 + MOVB R1, ret+12(FP) + RET +test: + MOVBU (R1), R6 + ADDU $1, R1 + MOVBU (R2), R7 + ADDU $1, R2 + BEQ R6, R7, loop + + MOVB R0, ret+12(FP) + RET +eq: + MOVW $1, R1 + MOVB R1, ret+12(FP) + RET + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-9 + MOVW a+0(FP), R1 + MOVW b+4(FP), R2 + BEQ R1, R2, eq + MOVW 4(REGCTXT), R3 // compiler stores size at offset 4 in the closure + ADDU R1, R3, R4 +loop: + BNE R1, R4, test + MOVW $1, R1 + MOVB R1, ret+8(FP) + RET +test: + MOVBU (R1), R6 + ADDU $1, R1 + MOVBU (R2), R7 + ADDU $1, R2 + BEQ R6, R7, loop + + MOVB R0, ret+8(FP) + RET +eq: + MOVW $1, R1 + MOVB R1, ret+8(FP) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_ppc64x.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_ppc64x.s new file mode 100644 index 00000000000..07dce80d3e7 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_ppc64x.s @@ -0,0 +1,207 @@ +// Copyright 2018 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. + +//go:build ppc64 || ppc64le + +#include "go_asm.h" +#include "textflag.h" + +// 4K (smallest case) page size offset mask for PPC64. +#define PAGE_OFFSET 4095 + +// Likewise, the BC opcode is hard to read, and no extended +// mnemonics are offered for these forms. +#define BGELR_CR6 BC 4, CR6LT, (LR) +#define BEQLR BC 12, CR0EQ, (LR) + +// memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25 + // R3 = a + // R4 = b + // R5 = size + BR memeqbody<>(SB) + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-17 + // R3 = a + // R4 = b + CMP R3, R4 + BEQ eq + MOVD 8(R11), R5 // compiler stores size at offset 8 in the closure + BR memeqbody<>(SB) +eq: + MOVD $1, R3 + RET + +// Do an efficient memequal for ppc64 +// R3 = s1 +// R4 = s2 +// R5 = len +// On exit: +// R3 = return value +TEXT memeqbody<>(SB),NOSPLIT|NOFRAME,$0-0 + MOVD R3, R8 // Move s1 into R8 + ADD R5, R3, R9 // &s1[len(s1)] + ADD R5, R4, R10 // &s2[len(s2)] + MOVD $1, R11 + CMP R5, $16 // Use GPR checks for check for len <= 16 + BLE check0_16 + MOVD $0, R3 // Assume no-match in case BGELR CR6 returns + CMP R5, $32 // Use overlapping VSX loads for len <= 32 + BLE check17_32 // Do a pair of overlapping VSR compares + CMP R5, $64 + BLE check33_64 // Hybrid check + overlap compare. + +setup64: + SRD $6, R5, R6 // number of 64 byte chunks to compare + MOVD R6, CTR + MOVD $16, R14 // index for VSX loads and stores + MOVD $32, R15 + MOVD $48, R16 + ANDCC $0x3F, R5, R5 // len%64==0? + + PCALIGN $16 +loop64: + LXVD2X (R8+R0), V0 + LXVD2X (R4+R0), V1 + VCMPEQUBCC V0, V1, V2 // compare, setting CR6 + BGELR_CR6 + LXVD2X (R8+R14), V0 + LXVD2X (R4+R14), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + LXVD2X (R8+R15), V0 + LXVD2X (R4+R15), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + LXVD2X (R8+R16), V0 + LXVD2X (R4+R16), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + ADD $64,R8 // bump up to next 64 + ADD $64,R4 + BDNZ loop64 + + ISEL CR0EQ, R11, R3, R3 // If no tail, return 1, otherwise R3 remains 0. + BEQLR // return if no tail. + + ADD $-64, R9, R8 + ADD $-64, R10, R4 + LXVD2X (R8+R0), V0 + LXVD2X (R4+R0), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + LXVD2X (R8+R14), V0 + LXVD2X (R4+R14), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + LXVD2X (R8+R15), V0 + LXVD2X (R4+R15), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + LXVD2X (R8+R16), V0 + LXVD2X (R4+R16), V1 + VCMPEQUBCC V0, V1, V2 + ISEL CR6LT, R11, R0, R3 + RET + +check33_64: + // Bytes 0-15 + LXVD2X (R8+R0), V0 + LXVD2X (R4+R0), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + ADD $16, R8 + ADD $16, R4 + + // Bytes 16-31 + LXVD2X (R8+R0), V0 + LXVD2X (R4+R0), V1 + VCMPEQUBCC V0, V1, V2 + BGELR_CR6 + + // A little tricky, but point R4,R8 to &sx[len-32], + // and reuse check17_32 to check the next 1-31 bytes (with some overlap) + ADD $-32, R9, R8 + ADD $-32, R10, R4 + // Fallthrough + +check17_32: + LXVD2X (R8+R0), V0 + LXVD2X (R4+R0), V1 + VCMPEQUBCC V0, V1, V2 + ISEL CR6LT, R11, R0, R5 + + // Load sX[len(sX)-16:len(sX)] and compare. + ADD $-16, R9 + ADD $-16, R10 + LXVD2X (R9+R0), V0 + LXVD2X (R10+R0), V1 + VCMPEQUBCC V0, V1, V2 + ISEL CR6LT, R5, R0, R3 + RET + +check0_16: +#ifdef GOPPC64_power10 + SLD $56, R5, R7 + LXVL R8, R7, V0 + LXVL R4, R7, V1 + VCMPEQUDCC V0, V1, V2 + ISEL CR6LT, R11, R0, R3 + RET +#else + CMP R5, $8 + BLT check0_7 + // Load sX[0:7] and compare. + MOVD (R8), R6 + MOVD (R4), R7 + CMP R6, R7 + ISEL CR0EQ, R11, R0, R5 + // Load sX[len(sX)-8:len(sX)] and compare. + MOVD -8(R9), R6 + MOVD -8(R10), R7 + CMP R6, R7 + ISEL CR0EQ, R5, R0, R3 + RET + +check0_7: + CMP R5,$0 + MOVD $1, R3 + BEQLR // return if len == 0 + + // Check < 8B loads with a single compare, but select the load address + // such that it cannot cross a page boundary. Load a few bytes from the + // lower address if that does not cross the lower page. Or, load a few + // extra bytes from the higher addresses. And align those values + // consistently in register as either address may have differing + // alignment requirements. + ANDCC $PAGE_OFFSET, R8, R6 // &sX & PAGE_OFFSET + ANDCC $PAGE_OFFSET, R4, R9 + SUBC R5, $8, R12 // 8-len + SLD $3, R12, R14 // (8-len)*8 + CMPU R6, R12, CR1 // Enough bytes lower in the page to load lower? + CMPU R9, R12, CR0 + SUB R12, R8, R6 // compute lower load address + SUB R12, R4, R9 + ISEL CR1LT, R8, R6, R8 // R8 = R6 < 0 ? R8 (&s1) : R6 (&s1 - (8-len)) + ISEL CR0LT, R4, R9, R4 // Similar for s2 + MOVD (R8), R15 + MOVD (R4), R16 + SLD R14, R15, R7 + SLD R14, R16, R17 + SRD R14, R7, R7 // Clear the upper (8-len) bytes (with 2 shifts) + SRD R14, R17, R17 + SRD R14, R15, R6 // Clear the lower (8-len) bytes + SRD R14, R16, R9 +#ifdef GOARCH_ppc64le + ISEL CR1LT, R7, R6, R8 // Choose the correct len bytes to compare based on alignment + ISEL CR0LT, R17, R9, R4 +#else + ISEL CR1LT, R6, R7, R8 + ISEL CR0LT, R9, R17, R4 +#endif + CMP R4, R8 + ISEL CR0EQ, R11, R0, R3 + RET +#endif // tail processing if !defined(GOPPC64_power10) diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_riscv64.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_riscv64.s new file mode 100644 index 00000000000..7f470ce0a01 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_riscv64.s @@ -0,0 +1,126 @@ +// Copyright 2019 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 "go_asm.h" +#include "textflag.h" + +#define CTXT S10 + +// func memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25 + // X10 = a_base + // X11 = b_base + // X12 = size + JMP memequal<>(SB) + +// func memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-17 + MOV 8(CTXT), X12 // compiler stores size at offset 8 in the closure + // X10 = a_base + // X11 = b_base + JMP memequal<>(SB) + +// On entry X10 and X11 contain pointers, X12 contains length. +// For non-regabi X13 contains address for return value. +// For regabi return value in X10. +TEXT memequal<>(SB),NOSPLIT|NOFRAME,$0 + BEQ X10, X11, eq + + MOV $32, X23 + BLT X12, X23, loop4_check + + // Check alignment - if alignment differs we have to do one byte at a time. + AND $7, X10, X9 + AND $7, X11, X19 + BNE X9, X19, loop4_check + BEQZ X9, loop32_check + + // Check one byte at a time until we reach 8 byte alignment. + SUB X9, X0, X9 + ADD $8, X9, X9 + SUB X9, X12, X12 +align: + SUB $1, X9 + MOVBU 0(X10), X19 + MOVBU 0(X11), X20 + BNE X19, X20, not_eq + ADD $1, X10 + ADD $1, X11 + BNEZ X9, align + +loop32_check: + MOV $32, X9 + BLT X12, X9, loop16_check +loop32: + MOV 0(X10), X19 + MOV 0(X11), X20 + MOV 8(X10), X21 + MOV 8(X11), X22 + BNE X19, X20, not_eq + BNE X21, X22, not_eq + MOV 16(X10), X14 + MOV 16(X11), X15 + MOV 24(X10), X16 + MOV 24(X11), X17 + BNE X14, X15, not_eq + BNE X16, X17, not_eq + ADD $32, X10 + ADD $32, X11 + SUB $32, X12 + BGE X12, X9, loop32 + BEQZ X12, eq + +loop16_check: + MOV $16, X23 + BLT X12, X23, loop4_check +loop16: + MOV 0(X10), X19 + MOV 0(X11), X20 + MOV 8(X10), X21 + MOV 8(X11), X22 + BNE X19, X20, not_eq + BNE X21, X22, not_eq + ADD $16, X10 + ADD $16, X11 + SUB $16, X12 + BGE X12, X23, loop16 + BEQZ X12, eq + +loop4_check: + MOV $4, X23 + BLT X12, X23, loop1 +loop4: + MOVBU 0(X10), X19 + MOVBU 0(X11), X20 + MOVBU 1(X10), X21 + MOVBU 1(X11), X22 + BNE X19, X20, not_eq + BNE X21, X22, not_eq + MOVBU 2(X10), X14 + MOVBU 2(X11), X15 + MOVBU 3(X10), X16 + MOVBU 3(X11), X17 + BNE X14, X15, not_eq + BNE X16, X17, not_eq + ADD $4, X10 + ADD $4, X11 + SUB $4, X12 + BGE X12, X23, loop4 + +loop1: + BEQZ X12, eq + MOVBU 0(X10), X19 + MOVBU 0(X11), X20 + BNE X19, X20, not_eq + ADD $1, X10 + ADD $1, X11 + SUB $1, X12 + JMP loop1 + +not_eq: + MOVB ZERO, X10 + RET +eq: + MOV $1, X10 + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_s390x.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_s390x.s new file mode 100644 index 00000000000..67f814dfc1c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_s390x.s @@ -0,0 +1,92 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +// memequal(a, b unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 + MOVD a+0(FP), R3 + MOVD b+8(FP), R5 + MOVD size+16(FP), R6 + LA ret+24(FP), R7 + BR memeqbody<>(SB) + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen(SB),NOSPLIT|NOFRAME,$0-17 + MOVD a+0(FP), R3 + MOVD b+8(FP), R5 + MOVD 8(R12), R6 // compiler stores size at offset 8 in the closure + LA ret+16(FP), R7 + BR memeqbody<>(SB) + +// input: +// R3 = a +// R5 = b +// R6 = len +// R7 = address of output byte (stores 0 or 1 here) +// a and b have the same length +TEXT memeqbody<>(SB),NOSPLIT|NOFRAME,$0-0 + CMPBEQ R3, R5, equal +loop: + CMPBEQ R6, $0, equal + CMPBLT R6, $32, tiny + CMP R6, $256 + BLT tail + CLC $256, 0(R3), 0(R5) + BNE notequal + SUB $256, R6 + LA 256(R3), R3 + LA 256(R5), R5 + BR loop +tail: + SUB $1, R6, R8 + EXRL $memeqbodyclc<>(SB), R8 + BEQ equal +notequal: + MOVB $0, 0(R7) + RET +equal: + MOVB $1, 0(R7) + RET +tiny: + MOVD $0, R2 + CMPBLT R6, $16, lt16 + MOVD 0(R3), R8 + MOVD 0(R5), R9 + CMPBNE R8, R9, notequal + MOVD 8(R3), R8 + MOVD 8(R5), R9 + CMPBNE R8, R9, notequal + LA 16(R2), R2 + SUB $16, R6 +lt16: + CMPBLT R6, $8, lt8 + MOVD 0(R3)(R2*1), R8 + MOVD 0(R5)(R2*1), R9 + CMPBNE R8, R9, notequal + LA 8(R2), R2 + SUB $8, R6 +lt8: + CMPBLT R6, $4, lt4 + MOVWZ 0(R3)(R2*1), R8 + MOVWZ 0(R5)(R2*1), R9 + CMPBNE R8, R9, notequal + LA 4(R2), R2 + SUB $4, R6 +lt4: +#define CHECK(n) \ + CMPBEQ R6, $n, equal \ + MOVB n(R3)(R2*1), R8 \ + MOVB n(R5)(R2*1), R9 \ + CMPBNE R8, R9, notequal + CHECK(0) + CHECK(1) + CHECK(2) + CHECK(3) + BR equal + +TEXT memeqbodyclc<>(SB),NOSPLIT|NOFRAME,$0-0 + CLC $1, 0(R3), 0(R5) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/equal_wasm.s b/contrib/go/_std_1.22/src/internal/bytealg/equal_wasm.s new file mode 100644 index 00000000000..a2b76c13681 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/equal_wasm.s @@ -0,0 +1,77 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +// memequal(p, q unsafe.Pointer, size uintptr) bool +TEXT runtime·memequal(SB), NOSPLIT, $0-25 + Get SP + I64Load a+0(FP) + I64Load b+8(FP) + I64Load size+16(FP) + Call memeqbody<>(SB) + I64Store8 ret+24(FP) + RET + +// memequal_varlen(a, b unsafe.Pointer) bool +TEXT runtime·memequal_varlen(SB), NOSPLIT, $0-17 + Get SP + I64Load a+0(FP) + I64Load b+8(FP) + I64Load 8(CTXT) // compiler stores size at offset 8 in the closure + Call memeqbody<>(SB) + I64Store8 ret+16(FP) + RET + +// params: a, b, len +// ret: 0/1 +TEXT memeqbody<>(SB), NOSPLIT, $0-0 + Get R0 + Get R1 + I64Eq + If + I64Const $1 + Return + End + +loop: + Loop + Get R2 + I64Eqz + If + I64Const $1 + Return + End + + Get R0 + I32WrapI64 + I64Load8U $0 + Get R1 + I32WrapI64 + I64Load8U $0 + I64Ne + If + I64Const $0 + Return + End + + Get R0 + I64Const $1 + I64Add + Set R0 + + Get R1 + I64Const $1 + I64Add + Set R1 + + Get R2 + I64Const $1 + I64Sub + Set R2 + + Br loop + End + UNDEF diff --git a/contrib/go/_std_1.22/src/internal/bytealg/index_generic.go b/contrib/go/_std_1.22/src/internal/bytealg/index_generic.go new file mode 100644 index 00000000000..a59e32938e7 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/index_generic.go @@ -0,0 +1,29 @@ +// Copyright 2018 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. + +//go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64 + +package bytealg + +const MaxBruteForce = 0 + +// Index returns the index of the first instance of b in a, or -1 if b is not present in a. +// Requires 2 <= len(b) <= MaxLen. +func Index(a, b []byte) int { + panic("unimplemented") +} + +// IndexString returns the index of the first instance of b in a, or -1 if b is not present in a. +// Requires 2 <= len(b) <= MaxLen. +func IndexString(a, b string) int { + panic("unimplemented") +} + +// Cutover reports the number of failures of IndexByte we should tolerate +// before switching over to Index. +// n is the number of bytes processed so far. +// See the bytes.Index implementation for details. +func Cutover(n int) int { + panic("unimplemented") +} diff --git a/contrib/go/_std_1.22/src/internal/bytealg/index_ppc64x.go b/contrib/go/_std_1.22/src/internal/bytealg/index_ppc64x.go new file mode 100644 index 00000000000..720d51748d6 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/index_ppc64x.go @@ -0,0 +1,26 @@ +// Copyright 2021 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. + +//go:build ppc64 || ppc64le + +package bytealg + +import "internal/cpu" + +const MaxBruteForce = 16 + +var SupportsPower9 = cpu.PPC64.IsPOWER9 + +func init() { + MaxLen = 32 +} + +// Cutover reports the number of failures of IndexByte we should tolerate +// before switching over to Index. +// n is the number of bytes processed so far. +// See the bytes.Index implementation for details. +func Cutover(n int) int { + // 1 error per 8 characters, plus a few slop to start. + return (n + 16) / 8 +} diff --git a/contrib/go/_std_1.22/src/internal/bytealg/index_ppc64x.s b/contrib/go/_std_1.22/src/internal/bytealg/index_ppc64x.s new file mode 100644 index 00000000000..80a1f853d3d --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/index_ppc64x.s @@ -0,0 +1,841 @@ +// Copyright 2021 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. + +// This is an implementation based on the s390x +// implementation. + +// Find a separator with 2 <= len <= 32 within a string. +// Separators with lengths of 2, 3 or 4 are handled +// specially. + +// This works on power8 and above. The loads and +// compares are done in big endian order +// since that allows the used of VCLZD, and allows +// the same implementation to work on big and little +// endian platforms with minimal conditional changes. + +// NOTE: There is a power9 implementation that +// improves performance by 10-15% on little +// endian for some of the benchmarks. +// Unrolled index2to16 loop by 4 on ppc64le/power9 +// Work is still needed for a big endian +// implementation on power9. + +//go:build ppc64 || ppc64le + +#include "go_asm.h" +#include "textflag.h" + +// Needed to swap LXVD2X loads to the correct +// byte order to work on POWER8. + +#ifdef GOARCH_ppc64 +DATA byteswap<>+0(SB)/8, $0x0001020304050607 +DATA byteswap<>+8(SB)/8, $0x08090a0b0c0d0e0f +#else +DATA byteswap<>+0(SB)/8, $0x0706050403020100 +DATA byteswap<>+8(SB)/8, $0x0f0e0d0c0b0a0908 +#endif + +// Load bytes in big endian order. Address +// alignment does not need checking. +#define VLOADSWAP(base, index, vreg, vsreg) \ + LXVD2X (base)(index), vsreg; \ + VPERM vreg, vreg, SWAP, vreg + +GLOBL byteswap<>+0(SB), RODATA, $16 + +TEXT ·Index<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-56 + // R3 = byte array pointer + // R4 = length + MOVD R6, R5 // R5 = separator pointer + MOVD R7, R6 // R6 = separator length + +#ifdef GOARCH_ppc64le + MOVBZ internal∕cpu·PPC64+const_offsetPPC64HasPOWER9(SB), R7 + CMP R7, $1 + BNE power8 + BR indexbodyp9<>(SB) +#endif +power8: + BR indexbody<>(SB) + +TEXT ·IndexString<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40 + // R3 = string + // R4 = length + // R5 = separator pointer + // R6 = separator length + +#ifdef GOARCH_ppc64le + MOVBZ internal∕cpu·PPC64+const_offsetPPC64HasPOWER9(SB), R7 + CMP R7, $1 + BNE power8 + BR indexbodyp9<>(SB) + +#endif +power8: + BR indexbody<>(SB) + + // s: string we are searching + // sep: string to search for + // R3=&s[0], R4=len(s) + // R5=&sep[0], R6=len(sep) + // R14=&ret (index where sep found) + // R7=working addr of string + // R16=index value 16 + // R17=index value 17 + // R18=index value 18 + // R19=index value 1 + // R26=LASTBYTE of string + // R27=LASTSTR last start byte to compare with sep + // R8, R9 scratch + // V0=sep left justified zero fill + // CR4=sep length >= 16 + +#define SEPMASK V17 +#define LASTBYTE R26 +#define LASTSTR R27 +#define ONES V20 +#define SWAP V21 +#define SWAP_ VS53 +TEXT indexbody<>(SB), NOSPLIT|NOFRAME, $0 + CMP R6, R4 // Compare lengths + BGT notfound // If sep len is > string, notfound + ADD R4, R3, LASTBYTE // find last byte addr + SUB R6, LASTBYTE, LASTSTR // LAST=&s[len(s)-len(sep)] (last valid start index) + CMP R6, $0 // Check sep len + BEQ notfound // sep len 0 -- not found + MOVD R3, R7 // Copy of string addr + MOVD $16, R16 // Index value 16 + MOVD $17, R17 // Index value 17 + MOVD $18, R18 // Index value 18 + MOVD $1, R19 // Index value 1 + MOVD $byteswap<>+00(SB), R8 + VSPLTISB $0xFF, ONES // splat all 1s + LXVD2X (R8)(R0), SWAP_ // Set up swap string + + CMP R6, $16, CR4 // CR4 for len(sep) >= 16 + VOR ONES, ONES, SEPMASK // Set up full SEPMASK + BGE CR4, loadge16 // Load for len(sep) >= 16 + SUB R6, R16, R9 // 16-len of sep + SLD $3, R9 // Set up for VSLO + MTVSRD R9, V9 // Set up for VSLO + VSLDOI $8, V9, V9, V9 // Set up for VSLO + VSLO ONES, V9, SEPMASK // Mask for separator len(sep) < 16 + +loadge16: + ANDCC $15, R5, R9 // Find byte offset of sep + ADD R9, R6, R10 // Add sep len + CMP R10, $16 // Check if sep len+offset > 16 + BGT sepcross16 // Sep crosses 16 byte boundary + + RLDICR $0, R5, $59, R8 // Adjust addr to 16 byte container + VLOADSWAP(R8, R0, V0, V0) // Load 16 bytes @R8 into V0 + SLD $3, R9 // Set up shift count for VSLO + MTVSRD R9, V8 // Set up shift count for VSLO + VSLDOI $8, V8, V8, V8 + VSLO V0, V8, V0 // Shift by start byte + + VAND V0, SEPMASK, V0 // Mask separator (< 16) + BR index2plus + +sepcross16: + VLOADSWAP(R5, R0, V0, V0) // Load 16 bytes @R5 into V0 + + VAND V0, SEPMASK, V0 // mask out separator + BLE CR4, index2to16 + BR index17plus // Handle sep > 16 + +index2plus: + CMP R6, $2 // Check length of sep + BNE index3plus // If not 2, check for 3 + ADD $16, R7, R9 // Check if next 16 bytes past last + CMP R9, LASTBYTE // compare with last + BGE index2to16 // 2 <= len(string) <= 16 + MOVD $0xff00, R21 // Mask for later + MTVSRD R21, V25 // Move to Vreg + VSPLTH $3, V25, V31 // Splat mask + VSPLTH $0, V0, V1 // Splat 1st 2 bytes of sep + VSPLTISB $0, V10 // Clear V10 + + // First case: 2 byte separator + // V1: 2 byte separator splatted + // V2: 16 bytes at addr + // V4: 16 bytes at addr+1 + // Compare 2 byte separator at start + // and at start+1. Use VSEL to combine + // those results to find the first + // matching start byte, returning + // that value when found. Loop as + // long as len(string) > 16 +index2loop2: + VLOADSWAP(R7, R19, V3, V3) // Load 16 bytes @R7+1 into V3 + +index2loop: + VLOADSWAP(R7, R0, V2, V2) // Load 16 bytes @R7 into V2 + VCMPEQUH V1, V2, V5 // Search for sep + VCMPEQUH V1, V3, V6 // Search for sep offset by 1 + VSEL V6, V5, V31, V7 // merge even and odd indices + VCLZD V7, V18 // find index of first match + MFVSRD V18, R25 // get first value + CMP R25, $64 // Found if < 64 + BLT foundR25 // Return byte index where found + VSLDOI $8, V18, V18, V18 // Adjust 2nd value + MFVSRD V18, R25 // get second value + CMP R25, $64 // Found if < 64 + ADD $64, R25 // Update byte offset + BLT foundR25 // Return value + ADD $16, R7 // R7+=16 Update string pointer + ADD $17, R7, R9 // R9=F7+17 since loop unrolled + CMP R9, LASTBYTE // Compare addr+17 against last byte + BLT index2loop2 // If < last, continue loop + CMP R7, LASTBYTE // Compare addr+16 against last byte + BLT index2to16 // If < 16 handle specially + VLOADSWAP(R7, R0, V3, V3) // Load 16 bytes @R7 into V3 + VSLDOI $1, V3, V10, V3 // Shift left by 1 byte + BR index2loop + +index3plus: + CMP R6, $3 // Check if sep == 3 + BNE index4plus // If not check larger + ADD $19, R7, R9 // Find bytes for use in this loop + CMP R9, LASTBYTE // Compare against last byte + BGE index2to16 // Remaining string 2<=len<=16 + MOVD $0xff00, R21 // Set up mask for upcoming loop + MTVSRD R21, V25 // Move mask to Vreg + VSPLTH $3, V25, V31 // Splat mask + VSPLTH $0, V0, V1 // Splat 1st two bytes of sep + VSPLTB $2, V0, V8 // Splat 3rd byte of sep + + // Loop to process 3 byte separator. + // string[0:16] is in V2 + // string[2:18] is in V3 + // sep[0:2] splatted in V1 + // sec[3] splatted in v8 + // Load vectors at string, string+1 + // and string+2. Compare string, string+1 + // against first 2 bytes of separator + // splatted, and string+2 against 3rd + // byte splatted. Merge the results with + // VSEL to find the first byte of a match. + + // Special handling for last 16 bytes if the + // string fits in 16 byte multiple. +index3loop2: + MOVD $2, R21 // Set up index for 2 + VSPLTISB $0, V10 // Clear V10 + VLOADSWAP(R7, R21, V3, V3)// Load 16 bytes @R7+2 into V3 + VSLDOI $14, V3, V10, V3 // Left justify next 2 bytes + +index3loop: + VLOADSWAP(R7, R0, V2, V2) // Load with correct order + VSLDOI $1, V2, V3, V4 // string[1:17] + VSLDOI $2, V2, V3, V9 // string[2:18] + VCMPEQUH V1, V2, V5 // compare hw even indices + VCMPEQUH V1, V4, V6 // compare hw odd indices + VCMPEQUB V8, V9, V10 // compare 3rd to last byte + VSEL V6, V5, V31, V7 // Find 1st matching byte using mask + VAND V7, V10, V7 // AND matched bytes with matched 3rd byte + VCLZD V7, V18 // Find first nonzero indexes + MFVSRD V18, R25 // Move 1st doubleword + CMP R25, $64 // If < 64 found + BLT foundR25 // Return matching index + VSLDOI $8, V18, V18, V18 // Move value + MFVSRD V18, R25 // Move 2nd doubleword + CMP R25, $64 // If < 64 found + ADD $64, R25 // Update byte index + BLT foundR25 // Return matching index + ADD $16, R7 // R7+=16 string ptr + ADD $19, R7, R9 // Number of string bytes for loop + CMP R9, LASTBYTE // Compare against last byte of string + BLT index3loop2 // If within, continue this loop + CMP R7, LASTSTR // Compare against last start byte + BLT index2to16 // Process remainder + VSPLTISB $0, V3 // Special case for last 16 bytes + BR index3loop // Continue this loop + + // Loop to process 4 byte separator + // string[0:16] in V2 + // string[3:16] in V3 + // sep[0:4] splatted in V1 + // Set up vectors with strings at offsets + // 0, 1, 2, 3 and compare against the 4 byte + // separator also splatted. Use VSEL with the + // compare results to find the first byte where + // a separator match is found. +index4plus: + CMP R6, $4 // Check if 4 byte separator + BNE index5plus // If not next higher + ADD $20, R7, R9 // Check string size to load + CMP R9, LASTBYTE // Verify string length + BGE index2to16 // If not large enough, process remaining + MOVD $2, R15 // Set up index + + // Set up masks for use with VSEL + MOVD $0xff, R21 // Set up mask 0xff000000ff000000... + SLD $24, R21 + MTVSRD R21, V10 + VSPLTW $1, V10, V29 + VSLDOI $2, V29, V29, V30 // Mask 0x0000ff000000ff00... + MOVD $0xffff, R21 + SLD $16, R21 + MTVSRD R21, V10 + VSPLTW $1, V10, V31 // Mask 0xffff0000ffff0000... + VSPLTW $0, V0, V1 // Splat 1st word of separator + +index4loop: + VLOADSWAP(R7, R0, V2, V2) // Load 16 bytes @R7 into V2 + +next4: + VSPLTISB $0, V10 // Clear + MOVD $3, R9 // Number of bytes beyond 16 + VLOADSWAP(R7, R9, V3, V3) // Load 16 bytes @R7+3 into V3 + VSLDOI $13, V3, V10, V3 // Shift left last 3 bytes + VSLDOI $1, V2, V3, V4 // V4=(V2:V3)<<1 + VSLDOI $2, V2, V3, V9 // V9=(V2:V3)<<2 + VSLDOI $3, V2, V3, V10 // V10=(V2:v3)<<3 + VCMPEQUW V1, V2, V5 // compare index 0, 4, ... with sep + VCMPEQUW V1, V4, V6 // compare index 1, 5, ... with sep + VCMPEQUW V1, V9, V11 // compare index 2, 6, ... with sep + VCMPEQUW V1, V10, V12 // compare index 3, 7, ... with sep + VSEL V6, V5, V29, V13 // merge index 0, 1, 4, 5, using mask + VSEL V12, V11, V30, V14 // merge index 2, 3, 6, 7, using mask + VSEL V14, V13, V31, V7 // final merge + VCLZD V7, V18 // Find first index for each half + MFVSRD V18, R25 // Isolate value + CMP R25, $64 // If < 64, found + BLT foundR25 // Return found index + VSLDOI $8, V18, V18, V18 // Move for MFVSRD + MFVSRD V18, R25 // Isolate other value + CMP R25, $64 // If < 64, found + ADD $64, R25 // Update index for high doubleword + BLT foundR25 // Return found index + ADD $16, R7 // R7+=16 for next string + ADD $20, R7, R9 // R+20 for all bytes to load + CMP R9, LASTBYTE // Past end? Maybe check for extra? + BLT index4loop // If not, continue loop + CMP R7, LASTSTR // Check remainder + BLE index2to16 // Process remainder + BR notfound // Not found + +index5plus: + CMP R6, $16 // Check for sep > 16 + BGT index17plus // Handle large sep + + // Assumption is that the separator is smaller than the string at this point +index2to16: + CMP R7, LASTSTR // Compare last start byte + BGT notfound // last takes len(sep) into account + + ADD $16, R7, R9 // Check for last byte of string + CMP R9, LASTBYTE + BGT index2to16tail + + // At least 16 bytes of string left + // Mask the number of bytes in sep +index2to16loop: + VLOADSWAP(R7, R0, V1, V1) // Load 16 bytes @R7 into V1 + +compare: + VAND V1, SEPMASK, V2 // Mask out sep size + VCMPEQUBCC V0, V2, V3 // Compare masked string + BLT CR6, found // All equal + ADD $1, R7 // Update ptr to next byte + CMP R7, LASTSTR // Still less than last start byte + BGT notfound // Not found + ADD $16, R7, R9 // Verify remaining bytes + CMP R9, LASTBYTE // At least 16 + BLT index2to16loop // Try again + + // Less than 16 bytes remaining in string + // Separator >= 2 +index2to16tail: + ADD R3, R4, R9 // End of string + SUB R7, R9, R9 // Number of bytes left + ANDCC $15, R7, R10 // 16 byte offset + ADD R10, R9, R11 // offset + len + CMP R11, $16 // >= 16? + BLE short // Does not cross 16 bytes + VLOADSWAP(R7, R0, V1, V1) // Load 16 bytes @R7 into V1 + BR index2to16next // Continue on + +short: + RLDICR $0, R7, $59, R9 // Adjust addr to 16 byte container + VLOADSWAP(R9, R0, V1, V1)// Load 16 bytes @R9 into V1 + SLD $3, R10 // Set up shift + MTVSRD R10, V8 // Set up shift + VSLDOI $8, V8, V8, V8 + VSLO V1, V8, V1 // Shift by start byte + VSPLTISB $0, V25 // Clear for later use + +index2to16next: + VAND V1, SEPMASK, V2 // Just compare size of sep + VCMPEQUBCC V0, V2, V3 // Compare sep and partial string + BLT CR6, found // Found + ADD $1, R7 // Not found, try next partial string + CMP R7, LASTSTR // Check for end of string + BGT notfound // If at end, then not found + VSLDOI $1, V1, V25, V1 // Shift string left by 1 byte + BR index2to16next // Check the next partial string + +index17plus: + CMP R6, $32 // Check if 17 < len(sep) <= 32 + BGT index33plus + SUB $16, R6, R9 // Extra > 16 + SLD $56, R9, R10 // Shift to use in VSLO + MTVSRD R10, V9 // Set up for VSLO + VLOADSWAP(R5, R9, V1, V1)// Load 16 bytes @R5+R9 into V1 + VSLO V1, V9, V1 // Shift left + VSPLTISB $0xff, V7 // Splat 1s + VSPLTISB $0, V27 // Splat 0 + +index17to32loop: + VLOADSWAP(R7, R0, V2, V2) // Load 16 bytes @R7 into V2 + +next17: + VLOADSWAP(R7, R9, V3, V3) // Load 16 bytes @R7+R9 into V3 + VSLO V3, V9, V3 // Shift left + VCMPEQUB V0, V2, V4 // Compare first 16 bytes + VCMPEQUB V1, V3, V5 // Compare extra over 16 bytes + VAND V4, V5, V6 // Check if both equal + VCMPEQUBCC V6, V7, V8 // All equal? + BLT CR6, found // Yes + ADD $1, R7 // On to next byte + CMP R7, LASTSTR // Check if last start byte + BGT notfound // If too high, not found + BR index17to32loop // Continue + +notfound: + MOVD $-1, R3 // Return -1 if not found + RET + +index33plus: + MOVD $0, (R0) // Case not implemented + RET // Crash before return + +foundR25: + SRD $3, R25 // Convert from bits to bytes + ADD R25, R7 // Add to current string address + SUB R3, R7 // Subtract from start of string + MOVD R7, R3 // Return byte where found + RET + +found: + SUB R3, R7 // Return byte where found + MOVD R7, R3 + RET + +TEXT indexbodyp9<>(SB), NOSPLIT|NOFRAME, $0 + CMP R6, R4 // Compare lengths + BGT notfound // If sep len is > string, notfound + ADD R4, R3, LASTBYTE // find last byte addr + SUB R6, LASTBYTE, LASTSTR // LAST=&s[len(s)-len(sep)] (last valid start index) + CMP R6, $0 // Check sep len + BEQ notfound // sep len 0 -- not found + MOVD R3, R7 // Copy of string addr +#ifndef GOPPC64_power10 + MOVD $16, R16 // Index value 16 + MOVD $17, R17 // Index value 17 + MOVD $18, R18 // Index value 18 + VSPLTISB $0xFF, ONES // splat all 1s + VOR ONES, ONES, SEPMASK // Set up full SEPMASK +#else + SLD $56, R6, R14 // Set up separator length for LXVLL +#endif + MOVD $1, R19 // Index value 1 + CMP R6, $16, CR4 // CR4 for len(sep) >= 16 + BGE CR4, loadge16 // Load for len(sep) >= 16 +#ifndef GOPPC64_power10 + SUB R6, R16, R9 // 16-len of sep + SLD $3, R9 // Set up for VSLO + MTVSRD R9, V9 // Set up for VSLO + VSLDOI $8, V9, V9, V9 // Set up for VSLO + VSLO ONES, V9, SEPMASK // Mask for separator len(sep) < 16 +#endif +loadge16: + ANDCC $15, R5, R9 // Find byte offset of sep + ADD R9, R6, R10 // Add sep len + CMP R10, $16 // Check if sep len+offset > 16 + BGT sepcross16 // Sep crosses 16 byte boundary +#ifdef GOPPC64_power10 + LXVLL R5, R14, V0 // Load separator +#else + RLDICR $0, R5, $59, R8 // Adjust addr to 16 byte container + LXVB16X (R8)(R0), V0 // Load 16 bytes @R8 into V0 + SLD $3, R9 // Set up shift count for VSLO + MTVSRD R9, V8 // Set up shift count for VSLO + VSLDOI $8, V8, V8, V8 + VSLO V0, V8, V0 // Shift by start byte + VAND V0, SEPMASK, V0 // Mask separator (< 16) +#endif + BR index2plus +sepcross16: +#ifdef GOPPC64_power10 + LXVLL R5, R14, V0 // Load separator +#else + LXVB16X (R5)(R0), V0 // Load 16 bytes @R5 into V0\ + VAND V0, SEPMASK, V0 // mask out separator +#endif + BLE CR4, index2to16 + BR index17plus // Handle sep > 16 + +index2plus: + CMP R6, $2 // Check length of sep + BNE index3plus // If not 2, check for 3 + ADD $16, R7, R9 // Check if next 16 bytes past last + CMP R9, LASTBYTE // compare with last + BGE index2to16 // 2 <= len(string) <= 16 + MOVD $0xff00, R21 // Mask for later + MTVSRD R21, V25 // Move to Vreg + VSPLTH $3, V25, V31 // Splat mask + VSPLTH $0, V0, V1 // Splat 1st 2 bytes of sep + VSPLTISB $0, V10 // Clear V10 + + // First case: 2 byte separator + // V1: 2 byte separator splatted + // V2: 16 bytes at addr + // V4: 16 bytes at addr+1 + // Compare 2 byte separator at start + // and at start+1. Use VSEL to combine + // those results to find the first + // matching start byte, returning + // that value when found. Loop as + // long as len(string) > 16 +index2loop2: + LXVB16X (R7)(R19), V3 // Load 16 bytes @R7+1 into V3 + +index2loop: + LXVB16X (R7)(R0), V2 // Load 16 bytes @R7 into V2 + VCMPEQUH V1, V2, V5 // Search for sep + VCMPEQUH V1, V3, V6 // Search for sep offset by 1 + VSEL V6, V5, V31, V7 // merge even and odd indices + VCLZD V7, V18 // find index of first match + MFVSRD V18, R25 // get first value + CMP R25, $64 // Found if < 64 + BLT foundR25 // Return byte index where found + + MFVSRLD V18, R25 // get second value + CMP R25, $64 // Found if < 64 + ADD $64, R25 // Update byte offset + BLT foundR25 // Return value + ADD $16, R7 // R7+=16 Update string pointer + ADD $17, R7, R9 // R9=F7+17 since loop unrolled + CMP R9, LASTBYTE // Compare addr+17 against last byte + BLT index2loop2 // If < last, continue loop + CMP R7, LASTBYTE // Compare addr+16 against last byte + BLT index2to16 // If < 16 handle specially + LXVB16X (R7)(R0), V3 // Load 16 bytes @R7 into V3 + VSLDOI $1, V3, V10, V3 // Shift left by 1 byte + BR index2loop + +index3plus: + CMP R6, $3 // Check if sep == 3 + BNE index4plus // If not check larger + ADD $19, R7, R9 // Find bytes for use in this loop + CMP R9, LASTBYTE // Compare against last byte + BGE index2to16 // Remaining string 2<=len<=16 + MOVD $0xff00, R21 // Set up mask for upcoming loop + MTVSRD R21, V25 // Move mask to Vreg + VSPLTH $3, V25, V31 // Splat mask + VSPLTH $0, V0, V1 // Splat 1st two bytes of sep + VSPLTB $2, V0, V8 // Splat 3rd byte of sep + + // Loop to process 3 byte separator. + // string[0:16] is in V2 + // string[2:18] is in V3 + // sep[0:2] splatted in V1 + // sec[3] splatted in v8 + // Load vectors at string, string+1 + // and string+2. Compare string, string+1 + // against first 2 bytes of separator + // splatted, and string+2 against 3rd + // byte splatted. Merge the results with + // VSEL to find the first byte of a match. + + // Special handling for last 16 bytes if the + // string fits in 16 byte multiple. +index3loop2: + MOVD $2, R21 // Set up index for 2 + VSPLTISB $0, V10 // Clear V10 + LXVB16X (R7)(R21), V3 // Load 16 bytes @R7+2 into V3 + VSLDOI $14, V3, V10, V3 // Left justify next 2 bytes + +index3loop: + LXVB16X (R7)(R0), V2 // Load 16 bytes @R7 + VSLDOI $1, V2, V3, V4 // string[1:17] + VSLDOI $2, V2, V3, V9 // string[2:18] + VCMPEQUH V1, V2, V5 // compare hw even indices + VCMPEQUH V1, V4, V6 // compare hw odd indices + VCMPEQUB V8, V9, V10 // compare 3rd to last byte + VSEL V6, V5, V31, V7 // Find 1st matching byte using mask + VAND V7, V10, V7 // AND matched bytes with matched 3rd byte + VCLZD V7, V18 // Find first nonzero indexes + MFVSRD V18, R25 // Move 1st doubleword + CMP R25, $64 // If < 64 found + BLT foundR25 // Return matching index + + MFVSRLD V18, R25 // Move 2nd doubleword + CMP R25, $64 // If < 64 found + ADD $64, R25 // Update byte index + BLT foundR25 // Return matching index + ADD $16, R7 // R7+=16 string ptr + ADD $19, R7, R9 // Number of string bytes for loop + CMP R9, LASTBYTE // Compare against last byte of string + BLT index3loop2 // If within, continue this loop + CMP R7, LASTSTR // Compare against last start byte + BLT index2to16 // Process remainder + VSPLTISB $0, V3 // Special case for last 16 bytes + BR index3loop // Continue this loop + + // Loop to process 4 byte separator + // string[0:16] in V2 + // string[3:16] in V3 + // sep[0:4] splatted in V1 + // Set up vectors with strings at offsets + // 0, 1, 2, 3 and compare against the 4 byte + // separator also splatted. Use VSEL with the + // compare results to find the first byte where + // a separator match is found. +index4plus: + CMP R6, $4 // Check if 4 byte separator + BNE index5plus // If not next higher + ADD $20, R7, R9 // Check string size to load + CMP R9, LASTBYTE // Verify string length + BGE index2to16 // If not large enough, process remaining + + // Set up masks for use with VSEL + MOVD $0xff, R21 // Set up mask 0xff000000ff000000... + SLD $24, R21 + MTVSRWS R21, V29 + + VSLDOI $2, V29, V29, V30 // Mask 0x0000ff000000ff00... + MOVD $0xffff, R21 + SLD $16, R21 + MTVSRWS R21, V31 + + VSPLTW $0, V0, V1 // Splat 1st word of separator + +index4loop: + LXVB16X (R7)(R0), V2 // Load 16 bytes @R7 into V2 + +next4: + VSPLTISB $0, V10 // Clear + MOVD $3, R9 // Number of bytes beyond 16 + LXVB16X (R7)(R9), V3 // Load 16 bytes @R7 into V3 + VSLDOI $13, V3, V10, V3 // Shift left last 3 bytes + VSLDOI $1, V2, V3, V4 // V4=(V2:V3)<<1 + VSLDOI $2, V2, V3, V9 // V9=(V2:V3)<<2 + VSLDOI $3, V2, V3, V10 // V10=(V2:v3)<<3 + VCMPEQUW V1, V2, V5 // compare index 0, 4, ... with sep + VCMPEQUW V1, V4, V6 // compare index 1, 5, ... with sep + VCMPEQUW V1, V9, V11 // compare index 2, 6, ... with sep + VCMPEQUW V1, V10, V12 // compare index 3, 7, ... with sep + VSEL V6, V5, V29, V13 // merge index 0, 1, 4, 5, using mask + VSEL V12, V11, V30, V14 // merge index 2, 3, 6, 7, using mask + VSEL V14, V13, V31, V7 // final merge + VCLZD V7, V18 // Find first index for each half + MFVSRD V18, R25 // Isolate value + CMP R25, $64 // If < 64, found + BLT foundR25 // Return found index + + MFVSRLD V18, R25 // Isolate other value + CMP R25, $64 // If < 64, found + ADD $64, R25 // Update index for high doubleword + BLT foundR25 // Return found index + ADD $16, R7 // R7+=16 for next string + ADD $20, R7, R9 // R+20 for all bytes to load + CMP R9, LASTBYTE // Past end? Maybe check for extra? + BLT index4loop // If not, continue loop + CMP R7, LASTSTR // Check remainder + BLE index2to16 // Process remainder + BR notfound // Not found + +index5plus: + CMP R6, $16 // Check for sep > 16 + BGT index17plus // Handle large sep + + // Assumption is that the separator is smaller than the string at this point +index2to16: + CMP R7, LASTSTR // Compare last start byte + BGT notfound // last takes len(sep) into account + + ADD $19, R7, R9 // To check 4 indices per iteration, need at least 16+3 bytes + CMP R9, LASTBYTE + // At least 16 bytes of string left + // Mask the number of bytes in sep + VSPLTISB $0, V10 // Clear + BGT index2to16tail + +#ifdef GOPPC64_power10 + ADD $3,R7, R17 // Base+3 + ADD $2,R7, R8 // Base+2 + ADD $1,R7, R10 // Base+1 +#else + MOVD $3, R17 // Number of bytes beyond 16 +#endif + PCALIGN $16 + +index2to16loop: + +#ifdef GOPPC64_power10 + LXVLL R7, R14, V8 // Load next 16 bytes of string from Base + LXVLL R10, R14, V9 // Load next 16 bytes of string from Base+1 + LXVLL R8, R14, V11 // Load next 16 bytes of string from Base+2 + LXVLL R17,R14, V12 // Load next 16 bytes of string from Base+3 +#else + LXVB16X (R7)(R0), V1 // Load next 16 bytes of string into V1 from R7 + LXVB16X (R7)(R17), V5 // Load next 16 bytes of string into V5 from R7+3 + + VSLDOI $13, V5, V10, V2 // Shift left last 3 bytes + VSLDOI $1, V1, V2, V3 // V3=(V1:V2)<<1 + VSLDOI $2, V1, V2, V4 // V4=(V1:V2)<<2 + VAND V1, SEPMASK, V8 // Mask out sep size 0th index + VAND V3, SEPMASK, V9 // Mask out sep size 1st index + VAND V4, SEPMASK, V11 // Mask out sep size 2nd index + VAND V5, SEPMASK, V12 // Mask out sep size 3rd index +#endif + VCMPEQUBCC V0, V8, V8 // compare masked string + BLT CR6, found // All equal while comparing 0th index + VCMPEQUBCC V0, V9, V9 // compare masked string + BLT CR6, found2 // All equal while comparing 1st index + VCMPEQUBCC V0, V11, V11 // compare masked string + BLT CR6, found3 // All equal while comparing 2nd index + VCMPEQUBCC V0, V12, V12 // compare masked string + BLT CR6, found4 // All equal while comparing 3rd index + + ADD $4, R7 // Update ptr to next 4 bytes +#ifdef GOPPC64_power10 + ADD $4, R17 // Update ptr to next 4 bytes + ADD $4, R8 // Update ptr to next 4 bytes + ADD $4, R10 // Update ptr to next 4 bytes +#endif + CMP R7, LASTSTR // Still less than last start byte + BGT notfound // Not found + ADD $19, R7, R9 // Verify remaining bytes + CMP R9, LASTBYTE // length of string at least 19 + BLE index2to16loop // Try again, else do post processing and jump to index2to16next + PCALIGN $32 + // <19 bytes left, post process the remaining string +index2to16tail: +#ifdef GOPPC64_power10 +index2to16next_p10: + LXVLL R7,R14, V1 // Load 16 bytes @R7 into V1 + VCMPEQUBCC V1, V0, V3 // Compare sep and partial string + BLT CR6, found // Found + ADD $1, R7 // Not found, try next partial string + CMP R7, LASTSTR // Check for end of string + BLE index2to16next_p10 // If at end, then not found + BR notfound // go to remainder loop +#else + ADD R3, R4, R9 // End of string + SUB R7, R9, R9 // Number of bytes left + ANDCC $15, R7, R10 // 16 byte offset + ADD R10, R9, R11 // offset + len + CMP R11, $16 // >= 16? + BLE short // Does not cross 16 bytes + LXVB16X (R7)(R0), V1 // Load 16 bytes @R7 into V1 + CMP R9, $16 // Post-processing of unrolled loop + BLE index2to16next // continue to index2to16next if <= 16 bytes + SUB R16, R9, R10 // R9 should be 18 or 17 hence R10 is 1 or 2 + LXVB16X (R7)(R10), V9 + CMP R10, $1 // string length is 17, compare 1 more byte + BNE extra2 // string length is 18, compare 2 more bytes + VSLDOI $15, V9, V10, V25 + VAND V1, SEPMASK, V2 // Just compare size of sep + VCMPEQUBCC V0, V2, V3 // Compare sep and partial string + BLT CR6, found // Found + ADD $1, R7 // Not found, try next partial string + CMP R7, LASTSTR // Check for end of string + BGT notfound // If at end, then not found + VSLDOI $1, V1, V25, V1 // Shift string left by 1 byte + BR index2to16next // go to remainder loop +extra2: + VSLDOI $14, V9, V10, V25 + VAND V1, SEPMASK, V2 // Just compare size of sep + VCMPEQUBCC V0, V2, V3 // Compare sep and partial string + BLT CR6, found // Found + ADD $1, R7 // Not found, try next partial string + CMP R7, LASTSTR // Check for end of string + BGT notfound // If at end, then not found + VOR V1, V1, V4 // save remaining string + VSLDOI $1, V1, V25, V1 // Shift string left by 1 byte for 17th byte + VAND V1, SEPMASK, V2 // Just compare size of sep + VCMPEQUBCC V0, V2, V3 // Compare sep and partial string + BLT CR6, found // Found + ADD $1, R7 // Not found, try next partial string + CMP R7, LASTSTR // Check for end of string + BGT notfound // If at end, then not found + VSLDOI $2, V4, V25, V1 // Shift saved string left by 2 bytes for 18th byte + BR index2to16next // Check the remaining partial string in index2to16next + +short: + RLDICR $0, R7, $59, R9 // Adjust addr to 16 byte container + LXVB16X (R9)(R0), V1 // Load 16 bytes @R9 into V1 + SLD $3, R10 // Set up shift + MTVSRD R10, V8 // Set up shift + VSLDOI $8, V8, V8, V8 + VSLO V1, V8, V1 // Shift by start byte + PCALIGN $16 +index2to16next: + VAND V1, SEPMASK, V2 // Just compare size of sep + VCMPEQUBCC V0, V2, V3 // Compare sep and partial string + BLT CR6, found // Found + ADD $1, R7 // Not found, try next partial string + CMP R7, LASTSTR // Check for end of string + BGT notfound // If at end, then not found + VSLDOI $1, V1, V10, V1 // Shift string left by 1 byte + BR index2to16next // Check the next partial string +#endif // Tail processing if GOPPC64!=power10 + +index17plus: + CMP R6, $32 // Check if 17 < len(sep) <= 32 + BGT index33plus + SUB $16, R6, R9 // Extra > 16 + SLD $56, R9, R10 // Shift to use in VSLO + MTVSRD R10, V9 // Set up for VSLO + LXVB16X (R5)(R9), V1 // Load 16 bytes @R5+R9 into V1 + VSLO V1, V9, V1 // Shift left + VSPLTISB $0xff, V7 // Splat 1s + VSPLTISB $0, V27 // Splat 0 + +index17to32loop: + LXVB16X (R7)(R0), V2 // Load 16 bytes @R7 into V2 + +next17: + LXVB16X (R7)(R9), V3 // Load 16 bytes @R7+R9 into V3 + VSLO V3, V9, V3 // Shift left + VCMPEQUB V0, V2, V4 // Compare first 16 bytes + VCMPEQUB V1, V3, V5 // Compare extra over 16 bytes + VAND V4, V5, V6 // Check if both equal + VCMPEQUBCC V6, V7, V8 // All equal? + BLT CR6, found // Yes + ADD $1, R7 // On to next byte + CMP R7, LASTSTR // Check if last start byte + BGT notfound // If too high, not found + BR index17to32loop // Continue + +notfound: + MOVD $-1, R3 // Return -1 if not found + RET + +index33plus: + MOVD $0, (R0) // Case not implemented + RET // Crash before return + +foundR25: + SRD $3, R25 // Convert from bits to bytes + ADD R25, R7 // Add to current string address + SUB R3, R7 // Subtract from start of string + MOVD R7, R3 // Return byte where found + RET +found4: + ADD $1, R7 // found from unrolled loop at index 3 +found3: + ADD $1, R7 // found from unrolled loop at index 2 +found2: + ADD $1, R7 // found from unrolled loop at index 1 +found: // found at index 0 + SUB R3, R7 // Return byte where found + MOVD R7, R3 + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/index_s390x.go b/contrib/go/_std_1.22/src/internal/bytealg/index_s390x.go new file mode 100644 index 00000000000..9340cf11354 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/index_s390x.go @@ -0,0 +1,31 @@ +// Copyright 2018 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 bytealg + +import "internal/cpu" + +const MaxBruteForce = 64 + +func init() { + // Note: we're kind of lucky that this flag is available at this point. + // The runtime sets HasVX when processing auxv records, and that happens + // to happen *before* running the init functions of packages that + // the runtime depends on. + // TODO: it would really be nicer for internal/cpu to figure out this + // flag by itself. Then we wouldn't need to depend on quirks of + // early startup initialization order. + if cpu.S390X.HasVX { + MaxLen = 64 + } +} + +// Cutover reports the number of failures of IndexByte we should tolerate +// before switching over to Index. +// n is the number of bytes processed so far. +// See the bytes.Index implementation for details. +func Cutover(n int) int { + // 1 error per 8 characters, plus a few slop to start. + return (n + 16) / 8 +} diff --git a/contrib/go/_std_1.22/src/internal/bytealg/index_s390x.s b/contrib/go/_std_1.22/src/internal/bytealg/index_s390x.s new file mode 100644 index 00000000000..491d5bcfd25 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/index_s390x.s @@ -0,0 +1,216 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +// Caller must confirm availability of vx facility before calling. +TEXT ·Index(SB),NOSPLIT|NOFRAME,$0-56 + LMG a_base+0(FP), R1, R2 // R1=&s[0], R2=len(s) + LMG b_base+24(FP), R3, R4 // R3=&sep[0], R4=len(sep) + MOVD $ret+48(FP), R5 + BR indexbody<>(SB) + +// Caller must confirm availability of vx facility before calling. +TEXT ·IndexString(SB),NOSPLIT|NOFRAME,$0-40 + LMG a_base+0(FP), R1, R2 // R1=&s[0], R2=len(s) + LMG b_base+16(FP), R3, R4 // R3=&sep[0], R4=len(sep) + MOVD $ret+32(FP), R5 + BR indexbody<>(SB) + +// s: string we are searching +// sep: string to search for +// R1=&s[0], R2=len(s) +// R3=&sep[0], R4=len(sep) +// R5=&ret (int) +// Caller must confirm availability of vx facility before calling. +TEXT indexbody<>(SB),NOSPLIT|NOFRAME,$0 + CMPBGT R4, R2, notfound + ADD R1, R2 + SUB R4, R2 // R2=&s[len(s)-len(sep)] (last valid index) + CMPBEQ R4, $0, notfound + SUB $1, R4 // R4=len(sep)-1 for use as VLL index + VLL R4, (R3), V0 // contains first 16 bytes of sep + MOVD R1, R7 +index2plus: + CMPBNE R4, $1, index3plus + MOVD $15(R7), R9 + CMPBGE R9, R2, index2to16 + VGBM $0xaaaa, V31 // 0xff00ff00ff00ff00... + VONE V16 + VREPH $0, V0, V1 + CMPBGE R9, R2, index2to16 +index2loop: + VL 0(R7), V2 // 16 bytes, even indices + VL 1(R7), V4 // 16 bytes, odd indices + VCEQH V1, V2, V5 // compare even indices + VCEQH V1, V4, V6 // compare odd indices + VSEL V5, V6, V31, V7 // merge even and odd indices + VFEEBS V16, V7, V17 // find leftmost index, set condition to 1 if found + BLT foundV17 + MOVD $16(R7), R7 // R7+=16 + ADD $15, R7, R9 + CMPBLE R9, R2, index2loop // continue if (R7+15) <= R2 (last index to search) + CMPBLE R7, R2, index2to16 + BR notfound + +index3plus: + CMPBNE R4, $2, index4plus + ADD $15, R7, R9 + CMPBGE R9, R2, index2to16 + MOVD $1, R0 + VGBM $0xaaaa, V31 // 0xff00ff00ff00ff00... + VONE V16 + VREPH $0, V0, V1 + VREPB $2, V0, V8 +index3loop: + VL (R7), V2 // load 16-bytes into V2 + VLL R0, 16(R7), V3 // load 2-bytes into V3 + VSLDB $1, V2, V3, V4 // V4=(V2:V3)<<1 + VSLDB $2, V2, V3, V9 // V9=(V2:V3)<<2 + VCEQH V1, V2, V5 // compare 2-byte even indices + VCEQH V1, V4, V6 // compare 2-byte odd indices + VCEQB V8, V9, V10 // compare last bytes + VSEL V5, V6, V31, V7 // merge even and odd indices + VN V7, V10, V7 // AND indices with last byte + VFEEBS V16, V7, V17 // find leftmost index, set condition to 1 if found + BLT foundV17 + MOVD $16(R7), R7 // R7+=16 + ADD $15, R7, R9 + CMPBLE R9, R2, index3loop // continue if (R7+15) <= R2 (last index to search) + CMPBLE R7, R2, index2to16 + BR notfound + +index4plus: + CMPBNE R4, $3, index5plus + ADD $15, R7, R9 + CMPBGE R9, R2, index2to16 + MOVD $2, R0 + VGBM $0x8888, V29 // 0xff000000ff000000... + VGBM $0x2222, V30 // 0x0000ff000000ff00... + VGBM $0xcccc, V31 // 0xffff0000ffff0000... + VONE V16 + VREPF $0, V0, V1 +index4loop: + VL (R7), V2 // load 16-bytes into V2 + VLL R0, 16(R7), V3 // load 3-bytes into V3 + VSLDB $1, V2, V3, V4 // V4=(V2:V3)<<1 + VSLDB $2, V2, V3, V9 // V9=(V2:V3)<<1 + VSLDB $3, V2, V3, V10 // V10=(V2:V3)<<1 + VCEQF V1, V2, V5 // compare index 0, 4, ... + VCEQF V1, V4, V6 // compare index 1, 5, ... + VCEQF V1, V9, V11 // compare index 2, 6, ... + VCEQF V1, V10, V12 // compare index 3, 7, ... + VSEL V5, V6, V29, V13 // merge index 0, 1, 4, 5, ... + VSEL V11, V12, V30, V14 // merge index 2, 3, 6, 7, ... + VSEL V13, V14, V31, V7 // final merge + VFEEBS V16, V7, V17 // find leftmost index, set condition to 1 if found + BLT foundV17 + MOVD $16(R7), R7 // R7+=16 + ADD $15, R7, R9 + CMPBLE R9, R2, index4loop // continue if (R7+15) <= R2 (last index to search) + CMPBLE R7, R2, index2to16 + BR notfound + +index5plus: + CMPBGT R4, $15, index17plus +index2to16: + CMPBGT R7, R2, notfound + MOVD $1(R7), R8 + CMPBGT R8, R2, index2to16tail +index2to16loop: + // unrolled 2x + VLL R4, (R7), V1 + VLL R4, 1(R7), V2 + VCEQGS V0, V1, V3 + BEQ found + MOVD $1(R7), R7 + VCEQGS V0, V2, V4 + BEQ found + MOVD $1(R7), R7 + CMPBLT R7, R2, index2to16loop + CMPBGT R7, R2, notfound +index2to16tail: + VLL R4, (R7), V1 + VCEQGS V0, V1, V2 + BEQ found + BR notfound + +index17plus: + CMPBGT R4, $31, index33plus + SUB $16, R4, R0 + VLL R0, 16(R3), V1 + VONE V7 +index17to32loop: + VL (R7), V2 + VLL R0, 16(R7), V3 + VCEQG V0, V2, V4 + VCEQG V1, V3, V5 + VN V4, V5, V6 + VCEQGS V6, V7, V8 + BEQ found + MOVD $1(R7), R7 + CMPBLE R7, R2, index17to32loop + BR notfound + +index33plus: + CMPBGT R4, $47, index49plus + SUB $32, R4, R0 + VL 16(R3), V1 + VLL R0, 32(R3), V2 + VONE V11 +index33to48loop: + VL (R7), V3 + VL 16(R7), V4 + VLL R0, 32(R7), V5 + VCEQG V0, V3, V6 + VCEQG V1, V4, V7 + VCEQG V2, V5, V8 + VN V6, V7, V9 + VN V8, V9, V10 + VCEQGS V10, V11, V12 + BEQ found + MOVD $1(R7), R7 + CMPBLE R7, R2, index33to48loop + BR notfound + +index49plus: + CMPBGT R4, $63, index65plus + SUB $48, R4, R0 + VL 16(R3), V1 + VL 32(R3), V2 + VLL R0, 48(R3), V3 + VONE V15 +index49to64loop: + VL (R7), V4 + VL 16(R7), V5 + VL 32(R7), V6 + VLL R0, 48(R7), V7 + VCEQG V0, V4, V8 + VCEQG V1, V5, V9 + VCEQG V2, V6, V10 + VCEQG V3, V7, V11 + VN V8, V9, V12 + VN V10, V11, V13 + VN V12, V13, V14 + VCEQGS V14, V15, V16 + BEQ found + MOVD $1(R7), R7 + CMPBLE R7, R2, index49to64loop +notfound: + MOVD $-1, (R5) + RET + +index65plus: + // not implemented + MOVD $0, (R0) + RET + +foundV17: // index is in doubleword V17[0] + VLGVG $0, V17, R8 + ADD R8, R7 +found: + SUB R1, R7 + MOVD R7, (R5) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_386.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_386.s new file mode 100644 index 00000000000..8a030542d4c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_386.s @@ -0,0 +1,34 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte(SB),NOSPLIT,$0-20 + MOVL b_base+0(FP), SI + MOVL b_len+4(FP), CX + MOVB c+12(FP), AL + MOVL SI, DI + CLD; REPN; SCASB + JZ 3(PC) + MOVL $-1, ret+16(FP) + RET + SUBL SI, DI + SUBL $1, DI + MOVL DI, ret+16(FP) + RET + +TEXT ·IndexByteString(SB),NOSPLIT,$0-16 + MOVL s_base+0(FP), SI + MOVL s_len+4(FP), CX + MOVB c+8(FP), AL + MOVL SI, DI + CLD; REPN; SCASB + JZ 3(PC) + MOVL $-1, ret+12(FP) + RET + SUBL SI, DI + SUBL $1, DI + MOVL DI, ret+12(FP) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_arm.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_arm.s new file mode 100644 index 00000000000..faf97977a63 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_arm.s @@ -0,0 +1,46 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte(SB),NOSPLIT,$0-20 + MOVW b_base+0(FP), R0 + MOVW b_len+4(FP), R1 + MOVBU c+12(FP), R2 // byte to find + MOVW $ret+16(FP), R5 + B indexbytebody<>(SB) + +TEXT ·IndexByteString(SB),NOSPLIT,$0-16 + MOVW s_base+0(FP), R0 + MOVW s_len+4(FP), R1 + MOVBU c+8(FP), R2 // byte to find + MOVW $ret+12(FP), R5 + B indexbytebody<>(SB) + +// input: +// R0: data +// R1: data length +// R2: byte to find +// R5: address to put result +TEXT indexbytebody<>(SB),NOSPLIT,$0-0 + MOVW R0, R4 // store base for later + ADD R0, R1 // end + +loop: + CMP R0, R1 + B.EQ notfound + MOVBU.P 1(R0), R3 + CMP R2, R3 + B.NE loop + + SUB $1, R0 // R0 will be one beyond the position we want + SUB R4, R0 // remove base + MOVW R0, (R5) + RET + +notfound: + MOVW $-1, R0 + MOVW R0, (R5) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_generic.go b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_generic.go new file mode 100644 index 00000000000..b7fffcf460c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_generic.go @@ -0,0 +1,29 @@ +// Copyright 2018 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. + +// Avoid IndexByte and IndexByteString on Plan 9 because it uses +// SSE instructions on x86 machines, and those are classified as +// floating point instructions, which are illegal in a note handler. + +//go:build !386 && (!amd64 || plan9) && !s390x && !arm && !arm64 && !loong64 && !ppc64 && !ppc64le && !mips && !mipsle && !mips64 && !mips64le && !riscv64 && !wasm + +package bytealg + +func IndexByte(b []byte, c byte) int { + for i, x := range b { + if x == c { + return i + } + } + return -1 +} + +func IndexByteString(s string, c byte) int { + for i := 0; i < len(s); i++ { + if s[i] == c { + return i + } + } + return -1 +} diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_loong64.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_loong64.s new file mode 100644 index 00000000000..03e06609731 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_loong64.s @@ -0,0 +1,74 @@ +// Copyright 2022 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 "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte<ABIInternal>(SB),NOSPLIT,$0-40 +#ifndef GOEXPERIMENT_regabiargs + MOVV b_base+0(FP), R4 + MOVV b_len+8(FP), R5 + MOVBU c+24(FP), R7 // byte to find +#endif + // R4 = b_base + // R5 = b_len + // R6 = b_cap (unused) + // R7 = byte to find + AND $0xff, R7 + MOVV R4, R6 // store base for later + ADDV R4, R5 // end + ADDV $-1, R4 + + PCALIGN $16 +loop: + ADDV $1, R4 + BEQ R4, R5, notfound + MOVBU (R4), R8 + BNE R7, R8, loop + + SUBV R6, R4 // remove base +#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+32(FP) +#endif + RET + +notfound: + MOVV $-1, R4 +#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+32(FP) +#endif + RET + +TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT,$0-32 +#ifndef GOEXPERIMENT_regabiargs + MOVV s_base+0(FP), R4 + MOVV s_len+8(FP), R5 + MOVBU c+16(FP), R6 // byte to find +#endif + // R4 = s_base + // R5 = s_len + // R6 = byte to find + MOVV R4, R7 // store base for later + ADDV R4, R5 // end + ADDV $-1, R4 + + PCALIGN $16 +loop: + ADDV $1, R4 + BEQ R4, R5, notfound + MOVBU (R4), R8 + BNE R6, R8, loop + + SUBV R7, R4 // remove base +#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+24(FP) +#endif + RET + +notfound: + MOVV $-1, R4 +#ifndef GOEXPERIMENT_regabiargs + MOVV R4, ret+24(FP) +#endif + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_mips64x.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_mips64x.s new file mode 100644 index 00000000000..5689f84b47a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_mips64x.s @@ -0,0 +1,54 @@ +// Copyright 2018 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. + +//go:build mips64 || mips64le + +#include "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte(SB),NOSPLIT,$0-40 + MOVV b_base+0(FP), R1 + MOVV b_len+8(FP), R2 + MOVBU c+24(FP), R3 // byte to find + MOVV R1, R4 // store base for later + ADDV R1, R2 // end + ADDV $-1, R1 + +loop: + ADDV $1, R1 + BEQ R1, R2, notfound + MOVBU (R1), R5 + BNE R3, R5, loop + + SUBV R4, R1 // remove base + MOVV R1, ret+32(FP) + RET + +notfound: + MOVV $-1, R1 + MOVV R1, ret+32(FP) + RET + +TEXT ·IndexByteString(SB),NOSPLIT,$0-32 + MOVV s_base+0(FP), R1 + MOVV s_len+8(FP), R2 + MOVBU c+16(FP), R3 // byte to find + MOVV R1, R4 // store base for later + ADDV R1, R2 // end + ADDV $-1, R1 + +loop: + ADDV $1, R1 + BEQ R1, R2, notfound + MOVBU (R1), R5 + BNE R3, R5, loop + + SUBV R4, R1 // remove base + MOVV R1, ret+24(FP) + RET + +notfound: + MOVV $-1, R1 + MOVV R1, ret+24(FP) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_mipsx.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_mipsx.s new file mode 100644 index 00000000000..1c2b104d3c9 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_mipsx.s @@ -0,0 +1,52 @@ +// Copyright 2018 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. + +//go:build mips || mipsle + +#include "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte(SB),NOSPLIT,$0-20 + MOVW b_base+0(FP), R1 + MOVW b_len+4(FP), R2 + MOVBU c+12(FP), R3 // byte to find + ADDU $1, R1, R4 // store base+1 for later + ADDU R1, R2 // end + +loop: + BEQ R1, R2, notfound + MOVBU (R1), R5 + ADDU $1, R1 + BNE R3, R5, loop + + SUBU R4, R1 // R1 will be one beyond the position we want so remove (base+1) + MOVW R1, ret+16(FP) + RET + +notfound: + MOVW $-1, R1 + MOVW R1, ret+16(FP) + RET + +TEXT ·IndexByteString(SB),NOSPLIT,$0-16 + MOVW s_base+0(FP), R1 + MOVW s_len+4(FP), R2 + MOVBU c+8(FP), R3 // byte to find + ADDU $1, R1, R4 // store base+1 for later + ADDU R1, R2 // end + +loop: + BEQ R1, R2, notfound + MOVBU (R1), R5 + ADDU $1, R1 + BNE R3, R5, loop + + SUBU R4, R1 // remove (base+1) + MOVW R1, ret+12(FP) + RET + +notfound: + MOVW $-1, R1 + MOVW R1, ret+12(FP) + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_ppc64x.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_ppc64x.s new file mode 100644 index 00000000000..b6714f45aae --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_ppc64x.s @@ -0,0 +1,314 @@ +// Copyright 2018 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. + +//go:build ppc64 || ppc64le + +#include "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40 + // R3 = byte array pointer + // R4 = length + MOVD R6, R5 // R5 = byte + BR indexbytebody<>(SB) + +TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32 + // R3 = string + // R4 = length + // R5 = byte + BR indexbytebody<>(SB) + +#ifndef GOPPC64_power9 +#ifdef GOARCH_ppc64le +DATA indexbytevbperm<>+0(SB)/8, $0x3830282018100800 +DATA indexbytevbperm<>+8(SB)/8, $0x7870686058504840 +#else +DATA indexbytevbperm<>+0(SB)/8, $0x0008101820283038 +DATA indexbytevbperm<>+8(SB)/8, $0x4048505860687078 +#endif +GLOBL indexbytevbperm<>+0(SB), RODATA, $16 +#endif + +// Some operations are endian specific, choose the correct opcode base on GOARCH. +// Note, _VCZBEBB is only available on power9 and newer. +#ifdef GOARCH_ppc64le +#define _LDBEX MOVDBR +#define _LWBEX MOVWBR +#define _LHBEX MOVHBR +#define _VCZBEBB VCTZLSBB +#else +#define _LDBEX MOVD +#define _LWBEX MOVW +#define _LHBEX MOVH +#define _VCZBEBB VCLZLSBB +#endif + +// R3 = addr of string +// R4 = len of string +// R5 = byte to find +// On exit: +// R3 = return value +TEXT indexbytebody<>(SB),NOSPLIT|NOFRAME,$0-0 + CMPU R4,$32 + +#ifndef GOPPC64_power9 + // Load VBPERMQ constant to reduce compare into an ordered bit mask. + MOVD $indexbytevbperm<>+00(SB),R16 + LXVD2X (R16),V0 // Set up swap string +#endif + + MTVRD R5,V1 + VSPLTB $7,V1,V1 // Replicate byte across V1 + + BLT cmp16 // Jump to the small string case if it's <32 bytes. + + CMP R4,$64,CR1 + MOVD $16,R11 + MOVD R3,R8 + BLT CR1,cmp32 // Special case for length 32 - 63 + MOVD $32,R12 + MOVD $48,R6 + + RLDICR $0,R4,$63-6,R9 // R9 = len &^ 63 + ADD R3,R9,R9 // R9 = &s[len &^ 63] + ANDCC $63,R4 // (len &= 63) cmp 0. + + PCALIGN $16 +loop64: + LXVD2X (R0)(R8),V2 // Scan 64 bytes at a time, starting at &s[0] + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat0 // Match found at R8, jump out + + LXVD2X (R11)(R8),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat1 // Match found at R8+16 bytes, jump out + + LXVD2X (R12)(R8),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat2 // Match found at R8+32 bytes, jump out + + LXVD2X (R6)(R8),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat3 // Match found at R8+48 bytes, jump out + + ADD $64,R8 + CMPU R8,R9,CR1 + BNE CR1,loop64 // R8 != &s[len &^ 63]? + + PCALIGN $32 + BEQ notfound // Is tail length 0? CR0 is set before entering loop64. + + CMP R4,$32 // Tail length >= 32, use cmp32 path. + CMP R4,$16,CR1 + BGE cmp32 + + ADD R8,R4,R9 + ADD $-16,R9 + BLE CR1,cmp64_tail_gt0 + +cmp64_tail_gt16: // Tail length 17 - 32 + LXVD2X (R0)(R8),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat0 + +cmp64_tail_gt0: // Tail length 1 - 16 + MOVD R9,R8 + LXVD2X (R0)(R9),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat0 + + BR notfound + +cmp32: // Length 32 - 63 + + // Bytes 0 - 15 + LXVD2X (R0)(R8),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat0 + + // Bytes 16 - 31 + LXVD2X (R8)(R11),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat1 // Match found at R8+16 bytes, jump out + + BEQ notfound // Is length <= 32? (CR0 holds this comparison on entry to cmp32) + CMP R4,$48 + + ADD R4,R8,R9 // Compute &s[len(s)-16] + ADD $32,R8,R8 + ADD $-16,R9,R9 + ISEL CR0GT,R8,R9,R8 // R8 = len(s) <= 48 ? R9 : R8 + + // Bytes 33 - 47 + LXVD2X (R0)(R8),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat0 // match found at R8+32 bytes, jump out + + BLE notfound + + // Bytes 48 - 63 + MOVD R9,R8 // R9 holds the final check. + LXVD2X (R0)(R9),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat0 // Match found at R8+48 bytes, jump out + + BR notfound + +// If ISA 3.0 instructions are unavailable, we need to account for the extra 16 added by CNTLZW. +#ifndef GOPPC64_power9 +#define ADJUST_FOR_CNTLZW -16 +#else +#define ADJUST_FOR_CNTLZW 0 +#endif + +// Now, find the index of the 16B vector the match was discovered in. If CNTLZW is used +// to determine the offset into the 16B vector, it will overcount by 16. Account for it here. +foundat3: + SUB R3,R8,R3 + ADD $48+ADJUST_FOR_CNTLZW,R3 + BR vfound +foundat2: + SUB R3,R8,R3 + ADD $32+ADJUST_FOR_CNTLZW,R3 + BR vfound +foundat1: + SUB R3,R8,R3 + ADD $16+ADJUST_FOR_CNTLZW,R3 + BR vfound +foundat0: + SUB R3,R8,R3 + ADD $0+ADJUST_FOR_CNTLZW,R3 +vfound: + // Map equal values into a 16 bit value with earlier matches setting higher bits. +#ifndef GOPPC64_power9 + VBPERMQ V6,V0,V6 + MFVRD V6,R4 + CNTLZW R4,R4 +#else +#ifdef GOARCH_ppc64le + // Put the value back into LE ordering by swapping doublewords. + XXPERMDI V6,V6,$2,V6 +#endif + _VCZBEBB V6,R4 +#endif + ADD R3,R4,R3 + RET + +cmp16: // Length 16 - 31 + CMPU R4,$16 + ADD R4,R3,R9 + BLT cmp8 + + ADD $-16,R9,R9 // &s[len(s)-16] + + // Bytes 0 - 15 + LXVD2X (R0)(R3),V2 + VCMPEQUBCC V2,V1,V6 + MOVD R3,R8 + BNE CR6,foundat0 // Match found at R8+32 bytes, jump out + + BEQ notfound + + // Bytes 16 - 30 + MOVD R9,R8 // R9 holds the final check. + LXVD2X (R0)(R9),V2 + VCMPEQUBCC V2,V1,V6 + BNE CR6,foundat0 // Match found at R8+48 bytes, jump out + + BR notfound + + +cmp8: // Length 8 - 15 +#ifdef GOPPC64_power10 + // Load all the bytes into a single VSR in BE order. + SLD $56,R4,R5 + LXVLL R3,R5,V2 + // Compare and count the number which don't match. + VCMPEQUB V2,V1,V6 + VCLZLSBB V6,R3 + // If count is the number of bytes, or more. No matches are found. + CMPU R3,R4 + MOVD $-1,R5 + // Otherwise, the count is the index of the first match. + ISEL CR0LT,R3,R5,R3 + RET +#else + RLDIMI $8,R5,$48,R5 // Replicating the byte across the register. + RLDIMI $16,R5,$32,R5 + RLDIMI $32,R5,$0,R5 + CMPU R4,$8 + BLT cmp4 + MOVD $-8,R11 + ADD $-8,R4,R4 + + _LDBEX (R0)(R3),R10 + _LDBEX (R11)(R9),R11 + CMPB R10,R5,R10 + CMPB R11,R5,R11 + CMPU R10,$0 + CMPU R11,$0,CR1 + CNTLZD R10,R10 + CNTLZD R11,R11 + SRD $3,R10,R3 + SRD $3,R11,R11 + BNE found + + ADD R4,R11,R4 + MOVD $-1,R3 + ISEL CR1EQ,R3,R4,R3 + RET + +cmp4: // Length 4 - 7 + CMPU R4,$4 + BLT cmp2 + MOVD $-4,R11 + ADD $-4,R4,R4 + + _LWBEX (R0)(R3),R10 + _LWBEX (R11)(R9),R11 + CMPB R10,R5,R10 + CMPB R11,R5,R11 + CNTLZW R10,R10 + CNTLZW R11,R11 + CMPU R10,$32 + CMPU R11,$32,CR1 + SRD $3,R10,R3 + SRD $3,R11,R11 + BNE found + + ADD R4,R11,R4 + MOVD $-1,R3 + ISEL CR1EQ,R3,R4,R3 + RET + +cmp2: // Length 2 - 3 + CMPU R4,$2 + BLT cmp1 + + _LHBEX (R0)(R3),R10 + CMPB R10,R5,R10 + SLDCC $48,R10,R10 + CNTLZD R10,R10 + SRD $3,R10,R3 + BNE found + +cmp1: // Length 1 + MOVD $-1,R3 + ANDCC $1,R4,R31 + BEQ found + + MOVBZ -1(R9),R10 + CMPB R10,R5,R10 + ANDCC $1,R10 + ADD $-1,R4 + ISEL CR0EQ,R3,R4,R3 + +found: + RET +#endif + +notfound: + MOVD $-1,R3 + RET + diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_riscv64.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_riscv64.s new file mode 100644 index 00000000000..de00983c7b9 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_riscv64.s @@ -0,0 +1,51 @@ +// Copyright 2019 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 "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte<ABIInternal>(SB),NOSPLIT,$0-40 + // X10 = b_base + // X11 = b_len + // X12 = b_cap (unused) + // X13 = byte to find + AND $0xff, X13 + MOV X10, X12 // store base for later + ADD X10, X11 // end + SUB $1, X10 + +loop: + ADD $1, X10 + BEQ X10, X11, notfound + MOVBU (X10), X14 + BNE X13, X14, loop + + SUB X12, X10 // remove base + RET + +notfound: + MOV $-1, X10 + RET + +TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT,$0-32 + // X10 = b_base + // X11 = b_len + // X12 = byte to find + AND $0xff, X12 + MOV X10, X13 // store base for later + ADD X10, X11 // end + SUB $1, X10 + +loop: + ADD $1, X10 + BEQ X10, X11, notfound + MOVBU (X10), X14 + BNE X12, X14, loop + + SUB X13, X10 // remove base + RET + +notfound: + MOV $-1, X10 + RET diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_s390x.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_s390x.s new file mode 100644 index 00000000000..cf88d92a24b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_s390x.s @@ -0,0 +1,108 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte(SB),NOSPLIT|NOFRAME,$0-40 + MOVD b_base+0(FP), R3// b_base => R3 + MOVD b_len+8(FP), R4 // b_len => R4 + MOVBZ c+24(FP), R5 // c => R5 + MOVD $ret+32(FP), R2 // &ret => R9 + BR indexbytebody<>(SB) + +TEXT ·IndexByteString(SB),NOSPLIT|NOFRAME,$0-32 + MOVD s_base+0(FP), R3// s_base => R3 + MOVD s_len+8(FP), R4 // s_len => R4 + MOVBZ c+16(FP), R5 // c => R5 + MOVD $ret+24(FP), R2 // &ret => R9 + BR indexbytebody<>(SB) + +// input: +// R3: s +// R4: s_len +// R5: c -- byte sought +// R2: &ret -- address to put index into +TEXT indexbytebody<>(SB),NOSPLIT|NOFRAME,$0 + CMPBEQ R4, $0, notfound + MOVD R3, R6 // store base for later + ADD R3, R4, R8 // the address after the end of the string + //if the length is small, use loop; otherwise, use vector or srst search + CMPBGE R4, $16, large + +residual: + CMPBEQ R3, R8, notfound + MOVBZ 0(R3), R7 + LA 1(R3), R3 + CMPBNE R7, R5, residual + +found: + SUB R6, R3 + SUB $1, R3 + MOVD R3, 0(R2) + RET + +notfound: + MOVD $-1, 0(R2) + RET + +large: + MOVBZ internal∕cpu·S390X+const_offsetS390xHasVX(SB), R1 + CMPBNE R1, $0, vectorimpl + +srstimpl: // no vector facility + MOVBZ R5, R0 // c needs to be in R0, leave until last minute as currently R0 is expected to be 0 +srstloop: + WORD $0xB25E0083 // srst %r8, %r3 (search the range [R3, R8)) + BVS srstloop // interrupted - continue + BGT notfoundr0 +foundr0: + XOR R0, R0 // reset R0 + SUB R6, R8 // remove base + MOVD R8, 0(R2) + RET +notfoundr0: + XOR R0, R0 // reset R0 + MOVD $-1, 0(R2) + RET + +vectorimpl: + //if the address is not 16byte aligned, use loop for the header + MOVD R3, R8 + AND $15, R8 + CMPBGT R8, $0, notaligned + +aligned: + ADD R6, R4, R8 + MOVD R8, R7 + AND $-16, R7 + // replicate c across V17 + VLVGB $0, R5, V19 + VREPB $0, V19, V17 + +vectorloop: + CMPBGE R3, R7, residual + VL 0(R3), V16 // load string to be searched into V16 + ADD $16, R3 + VFEEBS V16, V17, V18 // search V17 in V16 and set conditional code accordingly + BVS vectorloop + + // when vector search found c in the string + VLGVB $7, V18, R7 // load 7th element of V18 containing index into R7 + SUB $16, R3 + SUB R6, R3 + ADD R3, R7 + MOVD R7, 0(R2) + RET + +notaligned: + MOVD R3, R8 + AND $-16, R8 + ADD $16, R8 +notalignedloop: + CMPBEQ R3, R8, aligned + MOVBZ 0(R3), R7 + LA 1(R3), R3 + CMPBNE R7, R5, notalignedloop + BR found diff --git a/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_wasm.s b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_wasm.s new file mode 100644 index 00000000000..ef4bd93070f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/bytealg/indexbyte_wasm.s @@ -0,0 +1,195 @@ +// Copyright 2018 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 "go_asm.h" +#include "textflag.h" + +TEXT ·IndexByte(SB), NOSPLIT, $0-40 + I64Load b_base+0(FP) + I32WrapI64 + I32Load8U c+24(FP) + I64Load b_len+8(FP) + I32WrapI64 + Call memchr<>(SB) + I64ExtendI32S + Set R0 + + Get SP + I64Const $-1 + Get R0 + I64Load b_base+0(FP) + I64Sub + Get R0 + I64Eqz $0 + Select + I64Store ret+32(FP) + + RET + +TEXT ·IndexByteString(SB), NOSPLIT, $0-32 + Get SP + I64Load s_base+0(FP) + I32WrapI64 + I32Load8U c+16(FP) + I64Load s_len+8(FP) + I32WrapI64 + Call memchr<>(SB) + I64ExtendI32S + Set R0 + + I64Const $-1 + Get R0 + I64Load s_base+0(FP) + I64Sub + Get R0 + I64Eqz $0 + Select + I64Store ret+24(FP) + + RET + +// initially compiled with emscripten and then modified over time. +// params: +// R0: s +// R1: c +// R2: len +// ret: index +TEXT memchr<>(SB), NOSPLIT, $0 + Get R1 + Set R4 + Block + Block + Get R2 + I32Const $0 + I32Ne + Tee R3 + Get R0 + I32Const $3 + I32And + I32Const $0 + I32Ne + I32And + If + Loop + Get R0 + I32Load8U $0 + Get R1 + I32Eq + BrIf $2 + Get R2 + I32Const $-1 + I32Add + Tee R2 + I32Const $0 + I32Ne + Tee R3 + Get R0 + I32Const $1 + I32Add + Tee R0 + I32Const $3 + I32And + I32Const $0 + I32Ne + I32And + BrIf $0 + End + End + Get R3 + BrIf $0 + I32Const $0 + Set R1 + Br $1 + End + Get R0 + I32Load8U $0 + Get R4 + Tee R3 + I32Eq + If + Get R2 + Set R1 + Else + Get R4 + I32Const $16843009 + I32Mul + Set R4 + Block + Block + Get R2 + I32Const $3 + I32GtU + If + Get R2 + Set R1 + Loop + Get R0 + I32Load $0 + Get R4 + I32Xor + Tee R2 + I32Const $-2139062144 + I32And + I32Const $-2139062144 + I32Xor + Get R2 + I32Const $-16843009 + I32Add + I32And + I32Eqz + If + Get R0 + I32Const $4 + I32Add + Set R0 + Get R1 + I32Const $-4 + I32Add + Tee R1 + I32Const $3 + I32GtU + BrIf $1 + Br $3 + End + End + Else + Get R2 + Set R1 + Br $1 + End + Br $1 + End + Get R1 + I32Eqz + If + I32Const $0 + Set R1 + Br $3 + End + End + Loop + Get R0 + I32Load8U $0 + Get R3 + I32Eq + BrIf $2 + Get R0 + I32Const $1 + I32Add + Set R0 + Get R1 + I32Const $-1 + I32Add + Tee R1 + BrIf $0 + I32Const $0 + Set R1 + End + End + End + Get R0 + I32Const $0 + Get R1 + Select + Return diff --git a/contrib/go/_std_1.22/src/internal/chacha8rand/chacha8_stub.s b/contrib/go/_std_1.22/src/internal/chacha8rand/chacha8_stub.s new file mode 100644 index 00000000000..09be558fcb5 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/chacha8rand/chacha8_stub.s @@ -0,0 +1,12 @@ +// Copyright 2023 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. + +//go:build !amd64 && !arm64 + +#include "textflag.h" + +// func block(counter uint64, seed *[8]uint32, blocks *[16][4]uint32) +TEXT ·block(SB), NOSPLIT, $0 + JMP ·block_generic(SB) + diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_arm.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm.go new file mode 100644 index 00000000000..080e788112d --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm.go @@ -0,0 +1,48 @@ +// Copyright 2017 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 cpu + +const CacheLinePadSize = 32 + +// arm doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. +// These are initialized by archauxv() and should not be changed after they are +// initialized. +var HWCap uint +var HWCap2 uint +var Platform string + +// HWCAP/HWCAP2 bits. These are exposed by Linux and FreeBSD. +const ( + hwcap_VFPv4 = 1 << 16 + hwcap_IDIVA = 1 << 17 + hwcap_LPAE = 1 << 20 +) + +func doinit() { + options = []option{ + {Name: "vfpv4", Feature: &ARM.HasVFPv4}, + {Name: "idiva", Feature: &ARM.HasIDIVA}, + {Name: "v7atomics", Feature: &ARM.HasV7Atomics}, + } + + // HWCAP feature bits + ARM.HasVFPv4 = isSet(HWCap, hwcap_VFPv4) + ARM.HasIDIVA = isSet(HWCap, hwcap_IDIVA) + // lpae is required to make the 64-bit instructions LDRD and STRD (and variants) atomic. + // See ARMv7 manual section B1.6. + // We also need at least a v7 chip, for the DMB instruction. + ARM.HasV7Atomics = isSet(HWCap, hwcap_LPAE) && isV7(Platform) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} + +func isV7(s string) bool { + if s == "aarch64" { + return true + } + return s >= "v7" // will be something like v5, v7, v8, v8l +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_android.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_android.go new file mode 100644 index 00000000000..fbdf7baca2f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_android.go @@ -0,0 +1,11 @@ +// Copyright 2020 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. + +//go:build arm64 + +package cpu + +func osInit() { + hwcapInit("android") +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_freebsd.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_freebsd.go new file mode 100644 index 00000000000..96ed359ca0b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_freebsd.go @@ -0,0 +1,14 @@ +// Copyright 2020 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. + +//go:build arm64 + +package cpu + +func osInit() { + // Retrieve info from system register ID_AA64ISAR0_EL1. + isar0 := getisar0() + + parseARM64SystemRegisters(isar0) +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_openbsd.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_openbsd.go new file mode 100644 index 00000000000..12593098eb1 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_openbsd.go @@ -0,0 +1,28 @@ +// Copyright 2022 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. + +//go:build arm64 + +package cpu + +const ( + // From OpenBSD's sys/sysctl.h. + _CTL_MACHDEP = 7 + + // From OpenBSD's machine/cpu.h. + _CPU_ID_AA64ISAR0 = 2 + _CPU_ID_AA64ISAR1 = 3 +) + +//go:noescape +func sysctlUint64(mib []uint32) (uint64, bool) + +func osInit() { + // Get ID_AA64ISAR0 from sysctl. + isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0}) + if !ok { + return + } + parseARM64SystemRegisters(isar0) +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_other.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_other.go new file mode 100644 index 00000000000..44592cfcede --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_arm64_other.go @@ -0,0 +1,13 @@ +// Copyright 2020 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. + +//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios) && !openbsd + +package cpu + +func osInit() { + // Other operating systems do not support reading HWCap from auxiliary vector, + // reading privileged aarch64 system registers or sysctl in user space to detect + // CPU features at runtime. +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_loong64.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_loong64.go new file mode 100644 index 00000000000..1c90c24fe31 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_loong64.go @@ -0,0 +1,13 @@ +// Copyright 2022 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. + +//go:build loong64 + +package cpu + +// CacheLinePadSize is used to prevent false sharing of cache lines. +// We choose 64 because Loongson 3A5000 the L1 Dcache is 4-way 256-line 64-byte-per-line. +const CacheLinePadSize = 64 + +func doinit() {} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_mips.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_mips.go new file mode 100644 index 00000000000..14a9c975eae --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_mips.go @@ -0,0 +1,10 @@ +// Copyright 2017 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 cpu + +const CacheLinePadSize = 32 + +func doinit() { +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_mips64x.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_mips64x.go new file mode 100644 index 00000000000..c452ffd8b30 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_mips64x.go @@ -0,0 +1,32 @@ +// Copyright 2019 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. + +//go:build mips64 || mips64le + +package cpu + +const CacheLinePadSize = 32 + +// This is initialized by archauxv and should not be changed after it is +// initialized. +var HWCap uint + +// HWCAP bits. These are exposed by the Linux kernel 5.4. +const ( + // CPU features + hwcap_MIPS_MSA = 1 << 1 +) + +func doinit() { + options = []option{ + {Name: "msa", Feature: &MIPS64X.HasMSA}, + } + + // HWCAP feature bits + MIPS64X.HasMSA = isSet(HWCap, hwcap_MIPS_MSA) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_mipsle.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_mipsle.go new file mode 100644 index 00000000000..14a9c975eae --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_mipsle.go @@ -0,0 +1,10 @@ +// Copyright 2017 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 cpu + +const CacheLinePadSize = 32 + +func doinit() { +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x.go new file mode 100644 index 00000000000..c4a08fe1bd9 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x.go @@ -0,0 +1,35 @@ +// Copyright 2017 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. + +//go:build ppc64 || ppc64le + +package cpu + +const CacheLinePadSize = 128 + +func doinit() { + options = []option{ + {Name: "darn", Feature: &PPC64.HasDARN}, + {Name: "scv", Feature: &PPC64.HasSCV}, + {Name: "power9", Feature: &PPC64.IsPOWER9}, + } + + osinit() +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} + +func Name() string { + switch { + case PPC64.IsPOWER10: + return "POWER10" + case PPC64.IsPOWER9: + return "POWER9" + case PPC64.IsPOWER8: + return "POWER8" + } + return "" +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_aix.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_aix.go new file mode 100644 index 00000000000..f05ed6fad8a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_aix.go @@ -0,0 +1,25 @@ +// Copyright 2020 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. + +//go:build ppc64 || ppc64le + +package cpu + +const ( + // getsystemcfg constants + _SC_IMPL = 2 + _IMPL_POWER8 = 0x10000 + _IMPL_POWER9 = 0x20000 + _IMPL_POWER10 = 0x40000 +) + +func osinit() { + impl := getsystemcfg(_SC_IMPL) + PPC64.IsPOWER8 = isSet(impl, _IMPL_POWER8) + PPC64.IsPOWER9 = isSet(impl, _IMPL_POWER9) + PPC64.IsPOWER10 = isSet(impl, _IMPL_POWER10) +} + +// getsystemcfg is defined in runtime/os2_aix.go +func getsystemcfg(label uint) uint diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_linux.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_linux.go new file mode 100644 index 00000000000..9df82ca8a50 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_linux.go @@ -0,0 +1,33 @@ +// Copyright 2020 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. + +//go:build ppc64 || ppc64le + +package cpu + +// ppc64 doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. +// These are initialized by archauxv and should not be changed after they are +// initialized. +var HWCap uint +var HWCap2 uint + +// HWCAP bits. These are exposed by Linux. +const ( + // ISA Level + hwcap2_ARCH_2_07 = 0x80000000 + hwcap2_ARCH_3_00 = 0x00800000 + hwcap2_ARCH_3_1 = 0x00040000 + + // CPU features + hwcap2_DARN = 0x00200000 + hwcap2_SCV = 0x00100000 +) + +func osinit() { + PPC64.IsPOWER8 = isSet(HWCap2, hwcap2_ARCH_2_07) + PPC64.IsPOWER9 = isSet(HWCap2, hwcap2_ARCH_3_00) + PPC64.IsPOWER10 = isSet(HWCap2, hwcap2_ARCH_3_1) + PPC64.HasDARN = isSet(HWCap2, hwcap2_DARN) + PPC64.HasSCV = isSet(HWCap2, hwcap2_SCV) +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_other.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_other.go new file mode 100644 index 00000000000..d5b629dbebb --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_ppc64x_other.go @@ -0,0 +1,13 @@ +// Copyright 2023 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. + +//go:build (ppc64 || ppc64le) && !aix && !linux + +package cpu + +func osinit() { + // Other operating systems do not support reading HWCap from auxiliary vector, + // reading privileged system registers or sysctl in user space to detect CPU + // features at runtime. +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_riscv64.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_riscv64.go new file mode 100644 index 00000000000..2173fe88860 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_riscv64.go @@ -0,0 +1,10 @@ +// Copyright 2019 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 cpu + +const CacheLinePadSize = 64 + +func doinit() { +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_s390x.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_s390x.go new file mode 100644 index 00000000000..45d8ed27f07 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_s390x.go @@ -0,0 +1,205 @@ +// Copyright 2017 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 cpu + +const CacheLinePadSize = 256 + +var HWCap uint + +// bitIsSet reports whether the bit at index is set. The bit index +// is in big endian order, so bit index 0 is the leftmost bit. +func bitIsSet(bits []uint64, index uint) bool { + return bits[index/64]&((1<<63)>>(index%64)) != 0 +} + +// function is the function code for the named function. +type function uint8 + +const ( + // KM{,A,C,CTR} function codes + aes128 function = 18 // AES-128 + aes192 function = 19 // AES-192 + aes256 function = 20 // AES-256 + + // K{I,L}MD function codes + sha1 function = 1 // SHA-1 + sha256 function = 2 // SHA-256 + sha512 function = 3 // SHA-512 + sha3_224 function = 32 // SHA3-224 + sha3_256 function = 33 // SHA3-256 + sha3_384 function = 34 // SHA3-384 + sha3_512 function = 35 // SHA3-512 + shake128 function = 36 // SHAKE-128 + shake256 function = 37 // SHAKE-256 + + // KLMD function codes + ghash function = 65 // GHASH +) + +const ( + // KDSA function codes + ecdsaVerifyP256 function = 1 // NIST P256 + ecdsaVerifyP384 function = 2 // NIST P384 + ecdsaVerifyP521 function = 3 // NIST P521 + ecdsaSignP256 function = 9 // NIST P256 + ecdsaSignP384 function = 10 // NIST P384 + ecdsaSignP521 function = 11 // NIST P521 + eddsaVerifyEd25519 function = 32 // Curve25519 + eddsaVerifyEd448 function = 36 // Curve448 + eddsaSignEd25519 function = 40 // Curve25519 + eddsaSignEd448 function = 44 // Curve448 +) + +// queryResult contains the result of a Query function +// call. Bits are numbered in big endian order so the +// leftmost bit (the MSB) is at index 0. +type queryResult struct { + bits [2]uint64 +} + +// Has reports whether the given functions are present. +func (q *queryResult) Has(fns ...function) bool { + if len(fns) == 0 { + panic("no function codes provided") + } + for _, f := range fns { + if !bitIsSet(q.bits[:], uint(f)) { + return false + } + } + return true +} + +// facility is a bit index for the named facility. +type facility uint8 + +const ( + // mandatory facilities + zarch facility = 1 // z architecture mode is active + stflef facility = 7 // store-facility-list-extended + ldisp facility = 18 // long-displacement + eimm facility = 21 // extended-immediate + + // miscellaneous facilities + dfp facility = 42 // decimal-floating-point + etf3eh facility = 30 // extended-translation 3 enhancement + + // cryptography facilities + msa facility = 17 // message-security-assist + msa3 facility = 76 // message-security-assist extension 3 + msa4 facility = 77 // message-security-assist extension 4 + msa5 facility = 57 // message-security-assist extension 5 + msa8 facility = 146 // message-security-assist extension 8 + msa9 facility = 155 // message-security-assist extension 9 + + // vector facilities + vxe facility = 135 // vector-enhancements 1 + + // Note: vx requires kernel support + // and so must be fetched from HWCAP. + + hwcap_VX = 1 << 11 // vector facility +) + +// facilityList contains the result of an STFLE call. +// Bits are numbered in big endian order so the +// leftmost bit (the MSB) is at index 0. +type facilityList struct { + bits [4]uint64 +} + +// Has reports whether the given facilities are present. +func (s *facilityList) Has(fs ...facility) bool { + if len(fs) == 0 { + panic("no facility bits provided") + } + for _, f := range fs { + if !bitIsSet(s.bits[:], uint(f)) { + return false + } + } + return true +} + +// The following feature detection functions are defined in cpu_s390x.s. +// They are likely to be expensive to call so the results should be cached. +func stfle() facilityList +func kmQuery() queryResult +func kmcQuery() queryResult +func kmctrQuery() queryResult +func kmaQuery() queryResult +func kimdQuery() queryResult +func klmdQuery() queryResult +func kdsaQuery() queryResult + +func doinit() { + options = []option{ + {Name: "zarch", Feature: &S390X.HasZARCH}, + {Name: "stfle", Feature: &S390X.HasSTFLE}, + {Name: "ldisp", Feature: &S390X.HasLDISP}, + {Name: "msa", Feature: &S390X.HasMSA}, + {Name: "eimm", Feature: &S390X.HasEIMM}, + {Name: "dfp", Feature: &S390X.HasDFP}, + {Name: "etf3eh", Feature: &S390X.HasETF3EH}, + {Name: "vx", Feature: &S390X.HasVX}, + {Name: "vxe", Feature: &S390X.HasVXE}, + {Name: "kdsa", Feature: &S390X.HasKDSA}, + } + + aes := []function{aes128, aes192, aes256} + facilities := stfle() + + S390X.HasZARCH = facilities.Has(zarch) + S390X.HasSTFLE = facilities.Has(stflef) + S390X.HasLDISP = facilities.Has(ldisp) + S390X.HasEIMM = facilities.Has(eimm) + S390X.HasDFP = facilities.Has(dfp) + S390X.HasETF3EH = facilities.Has(etf3eh) + S390X.HasMSA = facilities.Has(msa) + + if S390X.HasMSA { + // cipher message + km, kmc := kmQuery(), kmcQuery() + S390X.HasAES = km.Has(aes...) + S390X.HasAESCBC = kmc.Has(aes...) + if facilities.Has(msa4) { + kmctr := kmctrQuery() + S390X.HasAESCTR = kmctr.Has(aes...) + } + if facilities.Has(msa8) { + kma := kmaQuery() + S390X.HasAESGCM = kma.Has(aes...) + } + + // compute message digest + kimd := kimdQuery() // intermediate (no padding) + klmd := klmdQuery() // last (padding) + S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) + S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) + S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) + S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist + sha3 := []function{ + sha3_224, sha3_256, sha3_384, sha3_512, + shake128, shake256, + } + S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) + S390X.HasKDSA = facilities.Has(msa9) // elliptic curves + if S390X.HasKDSA { + kdsa := kdsaQuery() + S390X.HasECDSA = kdsa.Has(ecdsaVerifyP256, ecdsaSignP256, ecdsaVerifyP384, ecdsaSignP384, ecdsaVerifyP521, ecdsaSignP521) + S390X.HasEDDSA = kdsa.Has(eddsaVerifyEd25519, eddsaSignEd25519, eddsaVerifyEd448, eddsaSignEd448) + } + } + + S390X.HasVX = isSet(HWCap, hwcap_VX) + + if S390X.HasVX { + S390X.HasVXE = facilities.Has(vxe) + } +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_s390x.s b/contrib/go/_std_1.22/src/internal/cpu/cpu_s390x.s new file mode 100644 index 00000000000..4ffbbde38dd --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_s390x.s @@ -0,0 +1,63 @@ +// Copyright 2018 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 "textflag.h" + +// func stfle() facilityList +TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32 + MOVD $ret+0(FP), R1 + MOVD $3, R0 // last doubleword index to store + XC $32, (R1), (R1) // clear 4 doublewords (32 bytes) + WORD $0xb2b01000 // store facility list extended (STFLE) + RET + +// func kmQuery() queryResult +TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KM-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + KM R2, R4 // cipher message (KM) + RET + +// func kmcQuery() queryResult +TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KMC-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + KMC R2, R4 // cipher message with chaining (KMC) + RET + +// func kmctrQuery() queryResult +TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KMCTR-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + KMCTR R2, R4, R4 // cipher message with counter (KMCTR) + RET + +// func kmaQuery() queryResult +TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KMA-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + KMA R2, R6, R4 // cipher message with authentication (KMA) + RET + +// func kimdQuery() queryResult +TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KIMD-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + KIMD R2, R4 // compute intermediate message digest (KIMD) + RET + +// func klmdQuery() queryResult +TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KLMD-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + KLMD R2, R4 // compute last message digest (KLMD) + RET + +// func kdsaQuery() queryResult +TEXT ·kdsaQuery(SB), NOSPLIT|NOFRAME, $0-16 + MOVD $0, R0 // set function code to 0 (KLMD-Query) + MOVD $ret+0(FP), R1 // address of 16-byte return value + KDSA R0, R4 // compute digital signature authentication + RET + diff --git a/contrib/go/_std_1.22/src/internal/cpu/cpu_wasm.go b/contrib/go/_std_1.22/src/internal/cpu/cpu_wasm.go new file mode 100644 index 00000000000..2310ad6a481 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/cpu/cpu_wasm.go @@ -0,0 +1,10 @@ +// Copyright 2018 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 cpu + +const CacheLinePadSize = 64 + +func doinit() { +} diff --git a/contrib/go/_std_1.22/src/internal/goarch/gengoarch.go b/contrib/go/_std_1.22/src/internal/goarch/gengoarch.go new file mode 100644 index 00000000000..0b0be5cd157 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/gengoarch.go @@ -0,0 +1,60 @@ +// 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. + +//go:build ignore + +package main + +import ( + "bytes" + "fmt" + "log" + "os" + "strings" +) + +var goarches []string + +func main() { + data, err := os.ReadFile("../../go/build/syslist.go") + if err != nil { + log.Fatal(err) + } + const goarchPrefix = `var knownArch = map[string]bool{` + inGOARCH := false + for _, line := range strings.Split(string(data), "\n") { + if strings.HasPrefix(line, goarchPrefix) { + inGOARCH = true + } else if inGOARCH && strings.HasPrefix(line, "}") { + break + } else if inGOARCH { + goarch := strings.Fields(line)[0] + goarch = strings.TrimPrefix(goarch, `"`) + goarch = strings.TrimSuffix(goarch, `":`) + goarches = append(goarches, goarch) + } + } + + for _, target := range goarches { + if target == "amd64p32" { + continue + } + var buf bytes.Buffer + fmt.Fprintf(&buf, "// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT.\n\n") + fmt.Fprintf(&buf, "//go:build %s\n\n", target) // must explicitly include target for bootstrapping purposes + fmt.Fprintf(&buf, "package goarch\n\n") + fmt.Fprintf(&buf, "const GOARCH = `%s`\n\n", target) + for _, goarch := range goarches { + value := 0 + if goarch == target { + value = 1 + } + fmt.Fprintf(&buf, "const Is%s = %d\n", strings.Title(goarch), value) + } + err := os.WriteFile("zgoarch_"+target+".go", buf.Bytes(), 0666) + if err != nil { + log.Fatal(err) + } + } +} diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_386.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_386.go new file mode 100644 index 00000000000..c6214217fcf --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_386.go @@ -0,0 +1,13 @@ +// 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 goarch + +const ( + _ArchFamily = I386 + _DefaultPhysPageSize = 4096 + _PCQuantum = 1 + _MinFrameSize = 0 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_arm.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_arm.go new file mode 100644 index 00000000000..a6591713c82 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_arm.go @@ -0,0 +1,13 @@ +// 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 goarch + +const ( + _ArchFamily = ARM + _DefaultPhysPageSize = 65536 + _PCQuantum = 4 + _MinFrameSize = 4 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_loong64.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_loong64.go new file mode 100644 index 00000000000..dae1f4da315 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_loong64.go @@ -0,0 +1,15 @@ +// Copyright 2022 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. + +//go:build loong64 + +package goarch + +const ( + _ArchFamily = LOONG64 + _DefaultPhysPageSize = 16384 + _PCQuantum = 4 + _MinFrameSize = 8 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_mips.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_mips.go new file mode 100644 index 00000000000..59f3995e2a5 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_mips.go @@ -0,0 +1,13 @@ +// Copyright 2015 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 goarch + +const ( + _ArchFamily = MIPS + _DefaultPhysPageSize = 65536 + _PCQuantum = 4 + _MinFrameSize = 4 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_mips64.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_mips64.go new file mode 100644 index 00000000000..9e4f82797d4 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_mips64.go @@ -0,0 +1,13 @@ +// Copyright 2015 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 goarch + +const ( + _ArchFamily = MIPS64 + _DefaultPhysPageSize = 16384 + _PCQuantum = 4 + _MinFrameSize = 8 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_mips64le.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_mips64le.go new file mode 100644 index 00000000000..9e4f82797d4 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_mips64le.go @@ -0,0 +1,13 @@ +// Copyright 2015 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 goarch + +const ( + _ArchFamily = MIPS64 + _DefaultPhysPageSize = 16384 + _PCQuantum = 4 + _MinFrameSize = 8 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_mipsle.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_mipsle.go new file mode 100644 index 00000000000..3e6642bb863 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_mipsle.go @@ -0,0 +1,13 @@ +// Copyright 2016 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 goarch + +const ( + _ArchFamily = MIPS + _DefaultPhysPageSize = 65536 + _PCQuantum = 4 + _MinFrameSize = 4 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_ppc64.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_ppc64.go new file mode 100644 index 00000000000..60cc846e6a3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_ppc64.go @@ -0,0 +1,13 @@ +// 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 goarch + +const ( + _ArchFamily = PPC64 + _DefaultPhysPageSize = 65536 + _PCQuantum = 4 + _MinFrameSize = 32 + _StackAlign = 16 +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_ppc64le.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_ppc64le.go new file mode 100644 index 00000000000..60cc846e6a3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_ppc64le.go @@ -0,0 +1,13 @@ +// 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 goarch + +const ( + _ArchFamily = PPC64 + _DefaultPhysPageSize = 65536 + _PCQuantum = 4 + _MinFrameSize = 32 + _StackAlign = 16 +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_riscv64.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_riscv64.go new file mode 100644 index 00000000000..3b6da1e02fe --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_riscv64.go @@ -0,0 +1,13 @@ +// Copyright 2016 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 goarch + +const ( + _ArchFamily = RISCV64 + _DefaultPhysPageSize = 4096 + _PCQuantum = 4 + _MinFrameSize = 8 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_s390x.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_s390x.go new file mode 100644 index 00000000000..20c5705581e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_s390x.go @@ -0,0 +1,13 @@ +// Copyright 2016 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 goarch + +const ( + _ArchFamily = S390X + _DefaultPhysPageSize = 4096 + _PCQuantum = 2 + _MinFrameSize = 8 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/goarch_wasm.go b/contrib/go/_std_1.22/src/internal/goarch/goarch_wasm.go new file mode 100644 index 00000000000..98618d6980e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/goarch_wasm.go @@ -0,0 +1,13 @@ +// Copyright 2018 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 goarch + +const ( + _ArchFamily = WASM + _DefaultPhysPageSize = 65536 + _PCQuantum = 1 + _MinFrameSize = 0 + _StackAlign = PtrSize +) diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_386.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_386.go new file mode 100644 index 00000000000..4a9b0e67c45 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_386.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build 386 + +package goarch + +const GOARCH = `386` + +const Is386 = 1 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_arm.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_arm.go new file mode 100644 index 00000000000..6c03b8b060c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_arm.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build arm + +package goarch + +const GOARCH = `arm` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 1 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_arm64be.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_arm64be.go new file mode 100644 index 00000000000..0f260030908 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_arm64be.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build arm64be + +package goarch + +const GOARCH = `arm64be` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 1 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_armbe.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_armbe.go new file mode 100644 index 00000000000..6092fee7516 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_armbe.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build armbe + +package goarch + +const GOARCH = `armbe` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 1 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_loong64.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_loong64.go new file mode 100644 index 00000000000..21c67e11768 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_loong64.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build loong64 + +package goarch + +const GOARCH = `loong64` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 1 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips.go new file mode 100644 index 00000000000..0db19746556 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build mips + +package goarch + +const GOARCH = `mips` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 1 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64.go new file mode 100644 index 00000000000..738806f0aef --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build mips64 + +package goarch + +const GOARCH = `mips64` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 1 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64le.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64le.go new file mode 100644 index 00000000000..8de5beb8819 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64le.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build mips64le + +package goarch + +const GOARCH = `mips64le` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 1 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64p32.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64p32.go new file mode 100644 index 00000000000..ea461bed70c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64p32.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build mips64p32 + +package goarch + +const GOARCH = `mips64p32` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 1 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64p32le.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64p32le.go new file mode 100644 index 00000000000..15473ce6c7a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mips64p32le.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build mips64p32le + +package goarch + +const GOARCH = `mips64p32le` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 1 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mipsle.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mipsle.go new file mode 100644 index 00000000000..4955142e876 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_mipsle.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build mipsle + +package goarch + +const GOARCH = `mipsle` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 1 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc.go new file mode 100644 index 00000000000..ec01763b3c3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build ppc + +package goarch + +const GOARCH = `ppc` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 1 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc64.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc64.go new file mode 100644 index 00000000000..39be3925c8e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc64.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build ppc64 + +package goarch + +const GOARCH = `ppc64` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 1 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc64le.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc64le.go new file mode 100644 index 00000000000..5f959e0e024 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_ppc64le.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build ppc64le + +package goarch + +const GOARCH = `ppc64le` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 1 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_riscv.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_riscv.go new file mode 100644 index 00000000000..8d81a14dd9b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_riscv.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build riscv + +package goarch + +const GOARCH = `riscv` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 1 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_riscv64.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_riscv64.go new file mode 100644 index 00000000000..1df989c2a69 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_riscv64.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build riscv64 + +package goarch + +const GOARCH = `riscv64` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 1 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_s390.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_s390.go new file mode 100644 index 00000000000..56815b9f435 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_s390.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build s390 + +package goarch + +const GOARCH = `s390` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 1 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_s390x.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_s390x.go new file mode 100644 index 00000000000..e61e9bd5938 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_s390x.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build s390x + +package goarch + +const GOARCH = `s390x` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 1 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_sparc.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_sparc.go new file mode 100644 index 00000000000..ee5b746566d --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_sparc.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build sparc + +package goarch + +const GOARCH = `sparc` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 1 +const IsSparc64 = 0 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_sparc64.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_sparc64.go new file mode 100644 index 00000000000..519aaa10c13 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_sparc64.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build sparc64 + +package goarch + +const GOARCH = `sparc64` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 1 +const IsWasm = 0 diff --git a/contrib/go/_std_1.22/src/internal/goarch/zgoarch_wasm.go b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_wasm.go new file mode 100644 index 00000000000..25567a1b648 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goarch/zgoarch_wasm.go @@ -0,0 +1,32 @@ +// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. + +//go:build wasm + +package goarch + +const GOARCH = `wasm` + +const Is386 = 0 +const IsAmd64 = 0 +const IsAmd64p32 = 0 +const IsArm = 0 +const IsArmbe = 0 +const IsArm64 = 0 +const IsArm64be = 0 +const IsLoong64 = 0 +const IsMips = 0 +const IsMipsle = 0 +const IsMips64 = 0 +const IsMips64le = 0 +const IsMips64p32 = 0 +const IsMips64p32le = 0 +const IsPpc = 0 +const IsPpc64 = 0 +const IsPpc64le = 0 +const IsRiscv = 0 +const IsRiscv64 = 0 +const IsS390 = 0 +const IsS390x = 0 +const IsSparc = 0 +const IsSparc64 = 0 +const IsWasm = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_allocheaders_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_allocheaders_on.go new file mode 100644 index 00000000000..f9f2965fe2e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_allocheaders_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.allocheaders + +package goexperiment + +const AllocHeaders = true +const AllocHeadersInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_arenas_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_arenas_on.go new file mode 100644 index 00000000000..609dfbca99f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_arenas_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.arenas + +package goexperiment + +const Arenas = true +const ArenasInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_boringcrypto_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_boringcrypto_on.go new file mode 100644 index 00000000000..ce476faa057 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_boringcrypto_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.boringcrypto + +package goexperiment + +const BoringCrypto = true +const BoringCryptoInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_cacheprog_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_cacheprog_on.go new file mode 100644 index 00000000000..b959dd68b9f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_cacheprog_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.cacheprog + +package goexperiment + +const CacheProg = true +const CacheProgInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_cgocheck2_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_cgocheck2_on.go new file mode 100644 index 00000000000..f6d1790d4ca --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_cgocheck2_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.cgocheck2 + +package goexperiment + +const CgoCheck2 = true +const CgoCheck2Int = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_coverageredesign_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_coverageredesign_on.go new file mode 100644 index 00000000000..3fc6c2f70a9 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_coverageredesign_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.coverageredesign + +package goexperiment + +const CoverageRedesign = true +const CoverageRedesignInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_exectracer2_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_exectracer2_on.go new file mode 100644 index 00000000000..f94a29247fa --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_exectracer2_on.go @@ -0,0 +1,9 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.exectracer2 +// +build goexperiment.exectracer2 + +package goexperiment + +const ExecTracer2 = true +const ExecTracer2Int = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_fieldtrack_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_fieldtrack_on.go new file mode 100644 index 00000000000..a49756750a3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_fieldtrack_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.fieldtrack + +package goexperiment + +const FieldTrack = true +const FieldTrackInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_heapminimum512kib_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_heapminimum512kib_on.go new file mode 100644 index 00000000000..2d29c98e1b1 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_heapminimum512kib_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.heapminimum512kib + +package goexperiment + +const HeapMinimum512KiB = true +const HeapMinimum512KiBInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_loopvar_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_loopvar_on.go new file mode 100644 index 00000000000..e158e0a666a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_loopvar_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.loopvar + +package goexperiment + +const LoopVar = true +const LoopVarInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_newinliner_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_newinliner_on.go new file mode 100644 index 00000000000..6777dbc0487 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_newinliner_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.newinliner + +package goexperiment + +const NewInliner = true +const NewInlinerInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_pagetrace_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_pagetrace_on.go new file mode 100644 index 00000000000..f3b16147890 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_pagetrace_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.pagetrace + +package goexperiment + +const PageTrace = true +const PageTraceInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_preemptibleloops_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_preemptibleloops_on.go new file mode 100644 index 00000000000..7f474c03577 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_preemptibleloops_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.preemptibleloops + +package goexperiment + +const PreemptibleLoops = true +const PreemptibleLoopsInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_rangefunc_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_rangefunc_on.go new file mode 100644 index 00000000000..25e7bd361b7 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_rangefunc_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.rangefunc + +package goexperiment + +const RangeFunc = true +const RangeFuncInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_regabiargs_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_regabiargs_on.go new file mode 100644 index 00000000000..def3b940047 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_regabiargs_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.regabiargs + +package goexperiment + +const RegabiArgs = true +const RegabiArgsInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_regabiwrappers_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_regabiwrappers_on.go new file mode 100644 index 00000000000..d525c9a86d1 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_regabiwrappers_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.regabiwrappers + +package goexperiment + +const RegabiWrappers = true +const RegabiWrappersInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/exp_staticlockranking_on.go b/contrib/go/_std_1.22/src/internal/goexperiment/exp_staticlockranking_on.go new file mode 100644 index 00000000000..dfd32a8ad9c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/exp_staticlockranking_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.staticlockranking + +package goexperiment + +const StaticLockRanking = true +const StaticLockRankingInt = 1 diff --git a/contrib/go/_std_1.22/src/internal/goexperiment/mkconsts.go b/contrib/go/_std_1.22/src/internal/goexperiment/mkconsts.go new file mode 100644 index 00000000000..65c100fa3a6 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goexperiment/mkconsts.go @@ -0,0 +1,72 @@ +// Copyright 2021 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. + +//go:build ignore + +// mkconsts generates const definition files for each GOEXPERIMENT. +package main + +import ( + "bytes" + "fmt" + "internal/goexperiment" + "log" + "os" + "reflect" + "strings" +) + +func main() { + // Delete existing experiment constant files. + ents, err := os.ReadDir(".") + if err != nil { + log.Fatal(err) + } + for _, ent := range ents { + name := ent.Name() + if !strings.HasPrefix(name, "exp_") { + continue + } + // Check that this is definitely a generated file. + data, err := os.ReadFile(name) + if err != nil { + log.Fatalf("reading %s: %v", name, err) + } + if !bytes.Contains(data, []byte("Code generated by mkconsts")) { + log.Fatalf("%s: expected generated file", name) + } + if err := os.Remove(name); err != nil { + log.Fatal(err) + } + } + + // Generate new experiment constant files. + rt := reflect.TypeOf(&goexperiment.Flags{}).Elem() + for i := 0; i < rt.NumField(); i++ { + f := rt.Field(i).Name + buildTag := "goexperiment." + strings.ToLower(f) + for _, val := range []bool{false, true} { + name := fmt.Sprintf("exp_%s_%s.go", strings.ToLower(f), pick(val, "off", "on")) + data := fmt.Sprintf(`// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build %s%s + +package goexperiment + +const %s = %v +const %sInt = %s +`, pick(val, "!", ""), buildTag, f, val, f, pick(val, "0", "1")) + if err := os.WriteFile(name, []byte(data), 0666); err != nil { + log.Fatalf("writing %s: %v", name, err) + } + } + } +} + +func pick(v bool, f, t string) string { + if v { + return t + } + return f +} diff --git a/contrib/go/_std_1.22/src/internal/goos/gengoos.go b/contrib/go/_std_1.22/src/internal/goos/gengoos.go new file mode 100644 index 00000000000..37d9706d1e8 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/gengoos.go @@ -0,0 +1,71 @@ +// 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. + +//go:build ignore + +package main + +import ( + "bytes" + "fmt" + "log" + "os" + "strings" +) + +var gooses []string + +func main() { + data, err := os.ReadFile("../../go/build/syslist.go") + if err != nil { + log.Fatal(err) + } + const goosPrefix = `var knownOS = map[string]bool{` + inGOOS := false + for _, line := range strings.Split(string(data), "\n") { + if strings.HasPrefix(line, goosPrefix) { + inGOOS = true + } else if inGOOS && strings.HasPrefix(line, "}") { + break + } else if inGOOS { + goos := strings.Fields(line)[0] + goos = strings.TrimPrefix(goos, `"`) + goos = strings.TrimSuffix(goos, `":`) + gooses = append(gooses, goos) + } + } + + for _, target := range gooses { + if target == "nacl" { + continue + } + var tags []string + if target == "linux" { + tags = append(tags, "!android") // must explicitly exclude android for linux + } + if target == "solaris" { + tags = append(tags, "!illumos") // must explicitly exclude illumos for solaris + } + if target == "darwin" { + tags = append(tags, "!ios") // must explicitly exclude ios for darwin + } + tags = append(tags, target) // must explicitly include target for bootstrapping purposes + var buf bytes.Buffer + fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n") + fmt.Fprintf(&buf, "//go:build %s\n\n", strings.Join(tags, " && ")) + fmt.Fprintf(&buf, "package goos\n\n") + fmt.Fprintf(&buf, "const GOOS = `%s`\n\n", target) + for _, goos := range gooses { + value := 0 + if goos == target { + value = 1 + } + fmt.Fprintf(&buf, "const Is%s = %d\n", strings.Title(goos), value) + } + err := os.WriteFile("zgoos_"+target+".go", buf.Bytes(), 0666) + if err != nil { + log.Fatal(err) + } + } +} diff --git a/contrib/go/_std_1.22/src/internal/goos/nonunix.go b/contrib/go/_std_1.22/src/internal/goos/nonunix.go new file mode 100644 index 00000000000..2ba5c8555a3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/nonunix.go @@ -0,0 +1,9 @@ +// Copyright 2022 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. + +//go:build !unix + +package goos + +const IsUnix = false diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_aix.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_aix.go new file mode 100644 index 00000000000..24e05c933e5 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_aix.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build aix + +package goos + +const GOOS = `aix` + +const IsAix = 1 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_android.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_android.go new file mode 100644 index 00000000000..3c4a318590a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_android.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build android + +package goos + +const GOOS = `android` + +const IsAix = 0 +const IsAndroid = 1 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_dragonfly.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_dragonfly.go new file mode 100644 index 00000000000..b92d1269f1f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_dragonfly.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build dragonfly + +package goos + +const GOOS = `dragonfly` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 1 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_freebsd.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_freebsd.go new file mode 100644 index 00000000000..f547591ab1e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_freebsd.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build freebsd + +package goos + +const GOOS = `freebsd` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 1 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_hurd.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_hurd.go new file mode 100644 index 00000000000..1189d65d745 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_hurd.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build hurd + +package goos + +const GOOS = `hurd` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 1 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_illumos.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_illumos.go new file mode 100644 index 00000000000..4f0254081c3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_illumos.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build illumos + +package goos + +const GOOS = `illumos` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 1 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_ios.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_ios.go new file mode 100644 index 00000000000..02f3586fa40 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_ios.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build ios + +package goos + +const GOOS = `ios` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 1 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_js.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_js.go new file mode 100644 index 00000000000..48187418919 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_js.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build js + +package goos + +const GOOS = `js` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 1 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_netbsd.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_netbsd.go new file mode 100644 index 00000000000..948603df0df --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_netbsd.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build netbsd + +package goos + +const GOOS = `netbsd` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 1 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_openbsd.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_openbsd.go new file mode 100644 index 00000000000..f4b201457b5 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_openbsd.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build openbsd + +package goos + +const GOOS = `openbsd` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 1 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_plan9.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_plan9.go new file mode 100644 index 00000000000..95572dff370 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_plan9.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build plan9 + +package goos + +const GOOS = `plan9` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 1 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_solaris.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_solaris.go new file mode 100644 index 00000000000..c7058260f8e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_solaris.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build !illumos && solaris + +package goos + +const GOOS = `solaris` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 1 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_wasip1.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_wasip1.go new file mode 100644 index 00000000000..ae35eebac61 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_wasip1.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build wasip1 + +package goos + +const GOOS = `wasip1` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 1 +const IsWindows = 0 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_windows.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_windows.go new file mode 100644 index 00000000000..f89f4cf8294 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_windows.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build windows + +package goos + +const GOOS = `windows` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 1 +const IsZos = 0 diff --git a/contrib/go/_std_1.22/src/internal/goos/zgoos_zos.go b/contrib/go/_std_1.22/src/internal/goos/zgoos_zos.go new file mode 100644 index 00000000000..29fb0f8babb --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/goos/zgoos_zos.go @@ -0,0 +1,26 @@ +// Code generated by gengoos.go using 'go generate'. DO NOT EDIT. + +//go:build zos + +package goos + +const GOOS = `zos` + +const IsAix = 0 +const IsAndroid = 0 +const IsDarwin = 0 +const IsDragonfly = 0 +const IsFreebsd = 0 +const IsHurd = 0 +const IsIllumos = 0 +const IsIos = 0 +const IsJs = 0 +const IsLinux = 0 +const IsNacl = 0 +const IsNetbsd = 0 +const IsOpenbsd = 0 +const IsPlan9 = 0 +const IsSolaris = 0 +const IsWasip1 = 0 +const IsWindows = 0 +const IsZos = 1 diff --git a/contrib/go/_std_1.22/src/internal/poll/errno_windows.go b/contrib/go/_std_1.22/src/internal/poll/errno_windows.go new file mode 100644 index 00000000000..63814793fda --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/errno_windows.go @@ -0,0 +1,31 @@ +// Copyright 2019 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. + +//go:build windows + +package poll + +import "syscall" + +// Do the interface allocations only once for common +// Errno values. + +var ( + errERROR_IO_PENDING error = syscall.Errno(syscall.ERROR_IO_PENDING) +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return nil + case syscall.ERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} diff --git a/contrib/go/_std_1.22/src/internal/poll/fd_fsync_windows.go b/contrib/go/_std_1.22/src/internal/poll/fd_fsync_windows.go new file mode 100644 index 00000000000..fb1211985db --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/fd_fsync_windows.go @@ -0,0 +1,16 @@ +// Copyright 2018 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 poll + +import "syscall" + +// Fsync wraps syscall.Fsync. +func (fd *FD) Fsync() error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + return syscall.Fsync(fd.Sysfd) +} diff --git a/contrib/go/_std_1.22/src/internal/poll/fd_io_plan9.go b/contrib/go/_std_1.22/src/internal/poll/fd_io_plan9.go new file mode 100644 index 00000000000..3205ac8513e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/fd_io_plan9.go @@ -0,0 +1,92 @@ +// Copyright 2016 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 poll + +import ( + "internal/itoa" + "runtime" + "sync" + "syscall" +) + +// asyncIO implements asynchronous cancelable I/O. +// An asyncIO represents a single asynchronous Read or Write +// operation. The result is returned on the result channel. +// The undergoing I/O system call can either complete or be +// interrupted by a note. +type asyncIO struct { + res chan result + + // mu guards the pid field. + mu sync.Mutex + + // pid holds the process id of + // the process running the IO operation. + pid int +} + +// result is the return value of a Read or Write operation. +type result struct { + n int + err error +} + +// newAsyncIO returns a new asyncIO that performs an I/O +// operation by calling fn, which must do one and only one +// interruptible system call. +func newAsyncIO(fn func([]byte) (int, error), b []byte) *asyncIO { + aio := &asyncIO{ + res: make(chan result, 0), + } + aio.mu.Lock() + go func() { + // Lock the current goroutine to its process + // and store the pid in io so that Cancel can + // interrupt it. We ignore the "hangup" signal, + // so the signal does not take down the entire + // Go runtime. + runtime.LockOSThread() + runtime_ignoreHangup() + aio.pid = syscall.Getpid() + aio.mu.Unlock() + + n, err := fn(b) + + aio.mu.Lock() + aio.pid = -1 + runtime_unignoreHangup() + aio.mu.Unlock() + + aio.res <- result{n, err} + }() + return aio +} + +// Cancel interrupts the I/O operation, causing +// the Wait function to return. +func (aio *asyncIO) Cancel() { + aio.mu.Lock() + defer aio.mu.Unlock() + if aio.pid == -1 { + return + } + f, e := syscall.Open("/proc/"+itoa.Itoa(aio.pid)+"/note", syscall.O_WRONLY) + if e != nil { + return + } + syscall.Write(f, []byte("hangup")) + syscall.Close(f) +} + +// Wait for the I/O operation to complete. +func (aio *asyncIO) Wait() (int, error) { + res := <-aio.res + return res.n, res.err +} + +// The following functions, provided by the runtime, are used to +// ignore and unignore the "hangup" signal received by the process. +func runtime_ignoreHangup() +func runtime_unignoreHangup() diff --git a/contrib/go/_std_1.22/src/internal/poll/fd_plan9.go b/contrib/go/_std_1.22/src/internal/poll/fd_plan9.go new file mode 100644 index 00000000000..7cc178a9d5a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/fd_plan9.go @@ -0,0 +1,232 @@ +// 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. + +package poll + +import ( + "errors" + "io" + "sync" + "time" +) + +type FD struct { + // Lock sysfd and serialize access to Read and Write methods. + fdmu fdMutex + + Destroy func() + + // deadlines + rmu sync.Mutex + wmu sync.Mutex + raio *asyncIO + waio *asyncIO + rtimer *time.Timer + wtimer *time.Timer + rtimedout bool // set true when read deadline has been reached + wtimedout bool // set true when write deadline has been reached + + // Whether this is a normal file. + // On Plan 9 we do not use this package for ordinary files, + // so this is always false, but the field is present because + // shared code in fd_mutex.go checks it. + isFile bool +} + +// We need this to close out a file descriptor when it is unlocked, +// but the real implementation has to live in the net package because +// it uses os.File's. +func (fd *FD) destroy() error { + if fd.Destroy != nil { + fd.Destroy() + } + return nil +} + +// Close handles the locking for closing an FD. The real operation +// is in the net package. +func (fd *FD) Close() error { + if !fd.fdmu.increfAndClose() { + return errClosing(fd.isFile) + } + return nil +} + +// Read implements io.Reader. +func (fd *FD) Read(fn func([]byte) (int, error), b []byte) (int, error) { + if err := fd.readLock(); err != nil { + return 0, err + } + defer fd.readUnlock() + if len(b) == 0 { + return 0, nil + } + fd.rmu.Lock() + if fd.rtimedout { + fd.rmu.Unlock() + return 0, ErrDeadlineExceeded + } + fd.raio = newAsyncIO(fn, b) + fd.rmu.Unlock() + n, err := fd.raio.Wait() + fd.raio = nil + if isHangup(err) { + err = io.EOF + } + if isInterrupted(err) { + err = ErrDeadlineExceeded + } + return n, err +} + +// Write implements io.Writer. +func (fd *FD) Write(fn func([]byte) (int, error), b []byte) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + fd.wmu.Lock() + if fd.wtimedout { + fd.wmu.Unlock() + return 0, ErrDeadlineExceeded + } + fd.waio = newAsyncIO(fn, b) + fd.wmu.Unlock() + n, err := fd.waio.Wait() + fd.waio = nil + if isInterrupted(err) { + err = ErrDeadlineExceeded + } + return n, err +} + +// SetDeadline sets the read and write deadlines associated with fd. +func (fd *FD) SetDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'r'+'w') +} + +// SetReadDeadline sets the read deadline associated with fd. +func (fd *FD) SetReadDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'r') +} + +// SetWriteDeadline sets the write deadline associated with fd. +func (fd *FD) SetWriteDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'w') +} + +func setDeadlineImpl(fd *FD, t time.Time, mode int) error { + d := t.Sub(time.Now()) + if mode == 'r' || mode == 'r'+'w' { + fd.rmu.Lock() + defer fd.rmu.Unlock() + if fd.rtimer != nil { + fd.rtimer.Stop() + fd.rtimer = nil + } + fd.rtimedout = false + } + if mode == 'w' || mode == 'r'+'w' { + fd.wmu.Lock() + defer fd.wmu.Unlock() + if fd.wtimer != nil { + fd.wtimer.Stop() + fd.wtimer = nil + } + fd.wtimedout = false + } + if !t.IsZero() && d > 0 { + // Interrupt I/O operation once timer has expired + if mode == 'r' || mode == 'r'+'w' { + var timer *time.Timer + timer = time.AfterFunc(d, func() { + fd.rmu.Lock() + defer fd.rmu.Unlock() + if fd.rtimer != timer { + // deadline was changed + return + } + fd.rtimedout = true + if fd.raio != nil { + fd.raio.Cancel() + } + }) + fd.rtimer = timer + } + if mode == 'w' || mode == 'r'+'w' { + var timer *time.Timer + timer = time.AfterFunc(d, func() { + fd.wmu.Lock() + defer fd.wmu.Unlock() + if fd.wtimer != timer { + // deadline was changed + return + } + fd.wtimedout = true + if fd.waio != nil { + fd.waio.Cancel() + } + }) + fd.wtimer = timer + } + } + if !t.IsZero() && d <= 0 { + // Interrupt current I/O operation + if mode == 'r' || mode == 'r'+'w' { + fd.rtimedout = true + if fd.raio != nil { + fd.raio.Cancel() + } + } + if mode == 'w' || mode == 'r'+'w' { + fd.wtimedout = true + if fd.waio != nil { + fd.waio.Cancel() + } + } + } + return nil +} + +// On Plan 9 only, expose the locking for the net code. + +// ReadLock wraps FD.readLock. +func (fd *FD) ReadLock() error { + return fd.readLock() +} + +// ReadUnlock wraps FD.readUnlock. +func (fd *FD) ReadUnlock() { + fd.readUnlock() +} + +func isHangup(err error) bool { + return err != nil && stringsHasSuffix(err.Error(), "Hangup") +} + +func isInterrupted(err error) bool { + return err != nil && stringsHasSuffix(err.Error(), "interrupted") +} + +// IsPollDescriptor reports whether fd is the descriptor being used by the poller. +// This is only used for testing. +func IsPollDescriptor(fd uintptr) bool { + return false +} + +// RawControl invokes the user-defined function f for a non-IO +// operation. +func (fd *FD) RawControl(f func(uintptr)) error { + return errors.New("not implemented") +} + +// RawRead invokes the user-defined function f for a read operation. +func (fd *FD) RawRead(f func(uintptr) bool) error { + return errors.New("not implemented") +} + +// RawWrite invokes the user-defined function f for a write operation. +func (fd *FD) RawWrite(f func(uintptr) bool) error { + return errors.New("not implemented") +} diff --git a/contrib/go/_std_1.22/src/internal/poll/fd_poll_js.go b/contrib/go/_std_1.22/src/internal/poll/fd_poll_js.go new file mode 100644 index 00000000000..fe5e73a149f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/fd_poll_js.go @@ -0,0 +1,99 @@ +// Copyright 2013 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. + +//go:build js && wasm + +package poll + +import ( + "syscall" + "time" +) + +type pollDesc struct { + fd *FD + closing bool +} + +func (pd *pollDesc) init(fd *FD) error { pd.fd = fd; return nil } + +func (pd *pollDesc) close() {} + +func (pd *pollDesc) evict() { + pd.closing = true + if pd.fd != nil { + syscall.StopIO(pd.fd.Sysfd) + } +} + +func (pd *pollDesc) prepare(mode int, isFile bool) error { + if pd.closing { + return errClosing(isFile) + } + return nil +} + +func (pd *pollDesc) prepareRead(isFile bool) error { return pd.prepare('r', isFile) } + +func (pd *pollDesc) prepareWrite(isFile bool) error { return pd.prepare('w', isFile) } + +func (pd *pollDesc) wait(mode int, isFile bool) error { + if pd.closing { + return errClosing(isFile) + } + if isFile { // TODO(neelance): js/wasm: Use callbacks from JS to block until the read/write finished. + return nil + } + return ErrDeadlineExceeded +} + +func (pd *pollDesc) waitRead(isFile bool) error { return pd.wait('r', isFile) } + +func (pd *pollDesc) waitWrite(isFile bool) error { return pd.wait('w', isFile) } + +func (pd *pollDesc) waitCanceled(mode int) {} + +func (pd *pollDesc) pollable() bool { return true } + +// SetDeadline sets the read and write deadlines associated with fd. +func (fd *FD) SetDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'r'+'w') +} + +// SetReadDeadline sets the read deadline associated with fd. +func (fd *FD) SetReadDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'r') +} + +// SetWriteDeadline sets the write deadline associated with fd. +func (fd *FD) SetWriteDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'w') +} + +func setDeadlineImpl(fd *FD, t time.Time, mode int) error { + d := t.UnixNano() + if t.IsZero() { + d = 0 + } + if err := fd.incref(); err != nil { + return err + } + switch mode { + case 'r': + syscall.SetReadDeadline(fd.Sysfd, d) + case 'w': + syscall.SetWriteDeadline(fd.Sysfd, d) + case 'r' + 'w': + syscall.SetReadDeadline(fd.Sysfd, d) + syscall.SetWriteDeadline(fd.Sysfd, d) + } + fd.decref() + return nil +} + +// IsPollDescriptor reports whether fd is the descriptor being used by the poller. +// This is only used for testing. +func IsPollDescriptor(fd uintptr) bool { + return false +} diff --git a/contrib/go/_std_1.22/src/internal/poll/fd_wasip1.go b/contrib/go/_std_1.22/src/internal/poll/fd_wasip1.go new file mode 100644 index 00000000000..aecd89669b4 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/fd_wasip1.go @@ -0,0 +1,239 @@ +// Copyright 2023 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 poll + +import ( + "sync/atomic" + "syscall" + "unsafe" +) + +type SysFile struct { + // RefCountPtr is a pointer to the reference count of Sysfd. + // + // WASI preview 1 lacks a dup(2) system call. When the os and net packages + // need to share a file/socket, instead of duplicating the underlying file + // descriptor, we instead provide a way to copy FD instances and manage the + // underlying file descriptor with reference counting. + RefCountPtr *int32 + + // RefCount is the reference count of Sysfd. When a copy of an FD is made, + // it points to the reference count of the original FD instance. + RefCount int32 + + // Cache for the file type, lazily initialized when Seek is called. + Filetype uint32 + + // If the file represents a directory, this field contains the current + // readdir position. It is reset to zero if the program calls Seek(0, 0). + Dircookie uint64 + + // Absolute path of the file, as returned by syscall.PathOpen; + // this is used by Fchdir to emulate setting the current directory + // to an open file descriptor. + Path string + + // TODO(achille): it could be meaningful to move isFile from FD to a method + // on this struct type, and expose it as `IsFile() bool` which derives the + // result from the Filetype field. We would need to ensure that Filetype is + // always set instead of being lazily initialized. +} + +func (s *SysFile) init() { + if s.RefCountPtr == nil { + s.RefCount = 1 + s.RefCountPtr = &s.RefCount + } +} + +func (s *SysFile) ref() SysFile { + atomic.AddInt32(s.RefCountPtr, +1) + return SysFile{RefCountPtr: s.RefCountPtr} +} + +func (s *SysFile) destroy(fd int) error { + if s.RefCountPtr != nil && atomic.AddInt32(s.RefCountPtr, -1) > 0 { + return nil + } + + // We don't use ignoringEINTR here because POSIX does not define + // whether the descriptor is closed if close returns EINTR. + // If the descriptor is indeed closed, using a loop would race + // with some other goroutine opening a new descriptor. + // (The Linux kernel guarantees that it is closed on an EINTR error.) + return CloseFunc(fd) +} + +// Copy creates a copy of the FD. +// +// The FD instance points to the same underlying file descriptor. The file +// descriptor isn't closed until all FD instances that refer to it have been +// closed/destroyed. +func (fd *FD) Copy() FD { + return FD{ + Sysfd: fd.Sysfd, + SysFile: fd.SysFile.ref(), + IsStream: fd.IsStream, + ZeroReadIsEOF: fd.ZeroReadIsEOF, + isBlocking: fd.isBlocking, + isFile: fd.isFile, + } +} + +// dupCloseOnExecOld always errors on wasip1 because there is no mechanism to +// duplicate file descriptors. +func dupCloseOnExecOld(fd int) (int, string, error) { + return -1, "dup", syscall.ENOSYS +} + +// Fchdir wraps syscall.Fchdir. +func (fd *FD) Fchdir() error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + return syscall.Chdir(fd.Path) +} + +// ReadDir wraps syscall.ReadDir. +// We treat this like an ordinary system call rather than a call +// that tries to fill the buffer. +func (fd *FD) ReadDir(buf []byte, cookie syscall.Dircookie) (int, error) { + if err := fd.incref(); err != nil { + return 0, err + } + defer fd.decref() + for { + n, err := syscall.ReadDir(fd.Sysfd, buf, cookie) + if err != nil { + n = 0 + if err == syscall.EAGAIN && fd.pd.pollable() { + if err = fd.pd.waitRead(fd.isFile); err == nil { + continue + } + } + } + // Do not call eofError; caller does not expect to see io.EOF. + return n, err + } +} + +func (fd *FD) ReadDirent(buf []byte) (int, error) { + n, err := fd.ReadDir(buf, fd.Dircookie) + if err != nil { + return 0, err + } + if n <= 0 { + return n, nil // EOF + } + + // We assume that the caller of ReadDirent will consume the entire buffer + // up to the last full entry, so we scan through the buffer looking for the + // value of the last next cookie. + b := buf[:n] + + for len(b) > 0 { + next, ok := direntNext(b) + if !ok { + break + } + size, ok := direntReclen(b) + if !ok { + break + } + if size > uint64(len(b)) { + break + } + fd.Dircookie = syscall.Dircookie(next) + b = b[size:] + } + + // Trim a potentially incomplete trailing entry; this is necessary because + // the code in src/os/dir_unix.go does not deal well with partial values in + // calls to direntReclen, etc... and ends up causing an early EOF before all + // directory entries were consumed. ReadDirent is called with a large enough + // buffer (8 KiB) that at least one entry should always fit, tho this seems + // a bit brittle but cannot be addressed without a large change of the + // algorithm in the os.(*File).readdir method. + return n - len(b), nil +} + +// Seek wraps syscall.Seek. +func (fd *FD) Seek(offset int64, whence int) (int64, error) { + if err := fd.incref(); err != nil { + return 0, err + } + defer fd.decref() + // syscall.Filetype is a uint8 but we store it as a uint32 in SysFile in + // order to use atomic load/store on the field, which is why we have to + // perform this type conversion. + fileType := syscall.Filetype(atomic.LoadUint32(&fd.Filetype)) + + if fileType == syscall.FILETYPE_UNKNOWN { + var stat syscall.Stat_t + if err := fd.Fstat(&stat); err != nil { + return 0, err + } + fileType = stat.Filetype + atomic.StoreUint32(&fd.Filetype, uint32(fileType)) + } + + if fileType == syscall.FILETYPE_DIRECTORY { + // If the file descriptor is opened on a directory, we reset the readdir + // cookie when seeking back to the beginning to allow reusing the file + // descriptor to scan the directory again. + if offset == 0 && whence == 0 { + fd.Dircookie = 0 + return 0, nil + } else { + return 0, syscall.EINVAL + } + } + + return syscall.Seek(fd.Sysfd, offset, whence) +} + +// https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-dirent-record +const sizeOfDirent = 24 + +func direntReclen(buf []byte) (uint64, bool) { + namelen, ok := direntNamlen(buf) + return sizeOfDirent + namelen, ok +} + +func direntNamlen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(syscall.Dirent{}.Namlen), unsafe.Sizeof(syscall.Dirent{}.Namlen)) +} + +func direntNext(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(syscall.Dirent{}.Next), unsafe.Sizeof(syscall.Dirent{}.Next)) +} + +// readInt returns the size-bytes unsigned integer in native byte order at offset off. +func readInt(b []byte, off, size uintptr) (u uint64, ok bool) { + if len(b) < int(off+size) { + return 0, false + } + return readIntLE(b[off:], size), true +} + +func readIntLE(b []byte, size uintptr) uint64 { + switch size { + case 1: + return uint64(b[0]) + case 2: + _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 + case 4: + _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 + case 8: + _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + default: + panic("internal/poll: readInt with unsupported size") + } +} diff --git a/contrib/go/_std_1.22/src/internal/poll/fd_windows.go b/contrib/go/_std_1.22/src/internal/poll/fd_windows.go new file mode 100644 index 00000000000..2095a6aa292 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/fd_windows.go @@ -0,0 +1,1331 @@ +// Copyright 2017 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 poll + +import ( + "errors" + "internal/race" + "internal/syscall/windows" + "io" + "sync" + "syscall" + "unicode/utf16" + "unicode/utf8" + "unsafe" +) + +var ( + initErr error + ioSync uint64 +) + +// This package uses the SetFileCompletionNotificationModes Windows +// API to skip calling GetQueuedCompletionStatus if an IO operation +// completes synchronously. There is a known bug where +// SetFileCompletionNotificationModes crashes on some systems (see +// https://support.microsoft.com/kb/2568167 for details). + +var useSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and safe to use + +// checkSetFileCompletionNotificationModes verifies that +// SetFileCompletionNotificationModes Windows API is present +// on the system and is safe to use. +// See https://support.microsoft.com/kb/2568167 for details. +func checkSetFileCompletionNotificationModes() { + err := syscall.LoadSetFileCompletionNotificationModes() + if err != nil { + return + } + protos := [2]int32{syscall.IPPROTO_TCP, 0} + var buf [32]syscall.WSAProtocolInfo + len := uint32(unsafe.Sizeof(buf)) + n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len) + if err != nil { + return + } + for i := int32(0); i < n; i++ { + if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 { + return + } + } + useSetFileCompletionNotificationModes = true +} + +func init() { + var d syscall.WSAData + e := syscall.WSAStartup(uint32(0x202), &d) + if e != nil { + initErr = e + } + checkSetFileCompletionNotificationModes() +} + +// operation contains superset of data necessary to perform all async IO. +type operation struct { + // Used by IOCP interface, it must be first field + // of the struct, as our code rely on it. + o syscall.Overlapped + + // fields used by runtime.netpoll + runtimeCtx uintptr + mode int32 + errno int32 + qty uint32 + + // fields used only by net package + fd *FD + buf syscall.WSABuf + msg windows.WSAMsg + sa syscall.Sockaddr + rsa *syscall.RawSockaddrAny + rsan int32 + handle syscall.Handle + flags uint32 + bufs []syscall.WSABuf +} + +func (o *operation) InitBuf(buf []byte) { + o.buf.Len = uint32(len(buf)) + o.buf.Buf = nil + if len(buf) != 0 { + o.buf.Buf = &buf[0] + } +} + +func (o *operation) InitBufs(buf *[][]byte) { + if o.bufs == nil { + o.bufs = make([]syscall.WSABuf, 0, len(*buf)) + } else { + o.bufs = o.bufs[:0] + } + for _, b := range *buf { + if len(b) == 0 { + o.bufs = append(o.bufs, syscall.WSABuf{}) + continue + } + for len(b) > maxRW { + o.bufs = append(o.bufs, syscall.WSABuf{Len: maxRW, Buf: &b[0]}) + b = b[maxRW:] + } + if len(b) > 0 { + o.bufs = append(o.bufs, syscall.WSABuf{Len: uint32(len(b)), Buf: &b[0]}) + } + } +} + +// ClearBufs clears all pointers to Buffers parameter captured +// by InitBufs, so it can be released by garbage collector. +func (o *operation) ClearBufs() { + for i := range o.bufs { + o.bufs[i].Buf = nil + } + o.bufs = o.bufs[:0] +} + +func (o *operation) InitMsg(p []byte, oob []byte) { + o.InitBuf(p) + o.msg.Buffers = &o.buf + o.msg.BufferCount = 1 + + o.msg.Name = nil + o.msg.Namelen = 0 + + o.msg.Flags = 0 + o.msg.Control.Len = uint32(len(oob)) + o.msg.Control.Buf = nil + if len(oob) != 0 { + o.msg.Control.Buf = &oob[0] + } +} + +// execIO executes a single IO operation o. It submits and cancels +// IO in the current thread for systems where Windows CancelIoEx API +// is available. Alternatively, it passes the request onto +// runtime netpoll and waits for completion or cancels request. +func execIO(o *operation, submit func(o *operation) error) (int, error) { + if o.fd.pd.runtimeCtx == 0 { + return 0, errors.New("internal error: polling on unsupported descriptor type") + } + + fd := o.fd + // Notify runtime netpoll about starting IO. + err := fd.pd.prepare(int(o.mode), fd.isFile) + if err != nil { + return 0, err + } + // Start IO. + err = submit(o) + switch err { + case nil: + // IO completed immediately + if o.fd.skipSyncNotif { + // No completion message will follow, so return immediately. + return int(o.qty), nil + } + // Need to get our completion message anyway. + case syscall.ERROR_IO_PENDING: + // IO started, and we have to wait for its completion. + err = nil + default: + return 0, err + } + // Wait for our request to complete. + err = fd.pd.wait(int(o.mode), fd.isFile) + if err == nil { + // All is good. Extract our IO results and return. + if o.errno != 0 { + err = syscall.Errno(o.errno) + // More data available. Return back the size of received data. + if err == syscall.ERROR_MORE_DATA || err == windows.WSAEMSGSIZE { + return int(o.qty), err + } + return 0, err + } + return int(o.qty), nil + } + // IO is interrupted by "close" or "timeout" + netpollErr := err + switch netpollErr { + case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded: + // will deal with those. + default: + panic("unexpected runtime.netpoll error: " + netpollErr.Error()) + } + // Cancel our request. + err = syscall.CancelIoEx(fd.Sysfd, &o.o) + // Assuming ERROR_NOT_FOUND is returned, if IO is completed. + if err != nil && err != syscall.ERROR_NOT_FOUND { + // TODO(brainman): maybe do something else, but panic. + panic(err) + } + // Wait for cancellation to complete. + fd.pd.waitCanceled(int(o.mode)) + if o.errno != 0 { + err = syscall.Errno(o.errno) + if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled + err = netpollErr + } + return 0, err + } + // We issued a cancellation request. But, it seems, IO operation succeeded + // before the cancellation request run. We need to treat the IO operation as + // succeeded (the bytes are actually sent/recv from network). + return int(o.qty), nil +} + +// FD is a file descriptor. The net and os packages embed this type in +// a larger type representing a network connection or OS file. +type FD struct { + // Lock sysfd and serialize access to Read and Write methods. + fdmu fdMutex + + // System file descriptor. Immutable until Close. + Sysfd syscall.Handle + + // Read operation. + rop operation + // Write operation. + wop operation + + // I/O poller. + pd pollDesc + + // Used to implement pread/pwrite. + l sync.Mutex + + // For console I/O. + lastbits []byte // first few bytes of the last incomplete rune in last write + readuint16 []uint16 // buffer to hold uint16s obtained with ReadConsole + readbyte []byte // buffer to hold decoding of readuint16 from utf16 to utf8 + readbyteOffset int // readbyte[readOffset:] is yet to be consumed with file.Read + + // Semaphore signaled when file is closed. + csema uint32 + + skipSyncNotif bool + + // Whether this is a streaming descriptor, as opposed to a + // packet-based descriptor like a UDP socket. + IsStream bool + + // Whether a zero byte read indicates EOF. This is false for a + // message based socket connection. + ZeroReadIsEOF bool + + // Whether this is a file rather than a network socket. + isFile bool + + // The kind of this file. + kind fileKind +} + +// fileKind describes the kind of file. +type fileKind byte + +const ( + kindNet fileKind = iota + kindFile + kindConsole + kindPipe +) + +// logInitFD is set by tests to enable file descriptor initialization logging. +var logInitFD func(net string, fd *FD, err error) + +// Init initializes the FD. The Sysfd field should already be set. +// This can be called multiple times on a single FD. +// The net argument is a network name from the net package (e.g., "tcp"), +// or "file" or "console" or "dir". +// Set pollable to true if fd should be managed by runtime netpoll. +func (fd *FD) Init(net string, pollable bool) (string, error) { + if initErr != nil { + return "", initErr + } + + switch net { + case "file", "dir": + fd.kind = kindFile + case "console": + fd.kind = kindConsole + case "pipe": + fd.kind = kindPipe + case "tcp", "tcp4", "tcp6", + "udp", "udp4", "udp6", + "ip", "ip4", "ip6", + "unix", "unixgram", "unixpacket": + fd.kind = kindNet + default: + return "", errors.New("internal error: unknown network type " + net) + } + fd.isFile = fd.kind != kindNet + + var err error + if pollable { + // Only call init for a network socket. + // This means that we don't add files to the runtime poller. + // Adding files to the runtime poller can confuse matters + // if the user is doing their own overlapped I/O. + // See issue #21172. + // + // In general the code below avoids calling the execIO + // function for non-network sockets. If some method does + // somehow call execIO, then execIO, and therefore the + // calling method, will return an error, because + // fd.pd.runtimeCtx will be 0. + err = fd.pd.init(fd) + } + if logInitFD != nil { + logInitFD(net, fd, err) + } + if err != nil { + return "", err + } + if pollable && useSetFileCompletionNotificationModes { + // We do not use events, so we can skip them always. + flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE) + switch net { + case "tcp", "tcp4", "tcp6", + "udp", "udp4", "udp6": + flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS + } + err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags) + if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 { + fd.skipSyncNotif = true + } + } + // Disable SIO_UDP_CONNRESET behavior. + // http://support.microsoft.com/kb/263823 + switch net { + case "udp", "udp4", "udp6": + ret := uint32(0) + flag := uint32(0) + size := uint32(unsafe.Sizeof(flag)) + err := syscall.WSAIoctl(fd.Sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0) + if err != nil { + return "wsaioctl", err + } + } + fd.rop.mode = 'r' + fd.wop.mode = 'w' + fd.rop.fd = fd + fd.wop.fd = fd + fd.rop.runtimeCtx = fd.pd.runtimeCtx + fd.wop.runtimeCtx = fd.pd.runtimeCtx + return "", nil +} + +func (fd *FD) destroy() error { + if fd.Sysfd == syscall.InvalidHandle { + return syscall.EINVAL + } + // Poller may want to unregister fd in readiness notification mechanism, + // so this must be executed before fd.CloseFunc. + fd.pd.close() + var err error + switch fd.kind { + case kindNet: + // The net package uses the CloseFunc variable for testing. + err = CloseFunc(fd.Sysfd) + default: + err = syscall.CloseHandle(fd.Sysfd) + } + fd.Sysfd = syscall.InvalidHandle + runtime_Semrelease(&fd.csema) + return err +} + +// Close closes the FD. The underlying file descriptor is closed by +// the destroy method when there are no remaining references. +func (fd *FD) Close() error { + if !fd.fdmu.increfAndClose() { + return errClosing(fd.isFile) + } + if fd.kind == kindPipe { + syscall.CancelIoEx(fd.Sysfd, nil) + } + // unblock pending reader and writer + fd.pd.evict() + err := fd.decref() + // Wait until the descriptor is closed. If this was the only + // reference, it is already closed. + runtime_Semacquire(&fd.csema) + return err +} + +// Windows ReadFile and WSARecv use DWORD (uint32) parameter to pass buffer length. +// This prevents us reading blocks larger than 4GB. +// See golang.org/issue/26923. +const maxRW = 1 << 30 // 1GB is large enough and keeps subsequent reads aligned + +// Read implements io.Reader. +func (fd *FD) Read(buf []byte) (int, error) { + if err := fd.readLock(); err != nil { + return 0, err + } + defer fd.readUnlock() + + if len(buf) > maxRW { + buf = buf[:maxRW] + } + + var n int + var err error + if fd.isFile { + fd.l.Lock() + defer fd.l.Unlock() + switch fd.kind { + case kindConsole: + n, err = fd.readConsole(buf) + default: + n, err = syscall.Read(fd.Sysfd, buf) + if fd.kind == kindPipe && err == syscall.ERROR_OPERATION_ABORTED { + // Close uses CancelIoEx to interrupt concurrent I/O for pipes. + // If the fd is a pipe and the Read was interrupted by CancelIoEx, + // we assume it is interrupted by Close. + err = ErrFileClosing + } + } + if err != nil { + n = 0 + } + } else { + o := &fd.rop + o.InitBuf(buf) + n, err = execIO(o, func(o *operation) error { + return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) + }) + if race.Enabled { + race.Acquire(unsafe.Pointer(&ioSync)) + } + } + if len(buf) != 0 { + err = fd.eofError(n, err) + } + return n, err +} + +var ReadConsole = syscall.ReadConsole // changed for testing + +// readConsole reads utf16 characters from console File, +// encodes them into utf8 and stores them in buffer b. +// It returns the number of utf8 bytes read and an error, if any. +func (fd *FD) readConsole(b []byte) (int, error) { + if len(b) == 0 { + return 0, nil + } + + if fd.readuint16 == nil { + // Note: syscall.ReadConsole fails for very large buffers. + // The limit is somewhere around (but not exactly) 16384. + // Stay well below. + fd.readuint16 = make([]uint16, 0, 10000) + fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16)) + } + + for fd.readbyteOffset >= len(fd.readbyte) { + n := cap(fd.readuint16) - len(fd.readuint16) + if n > len(b) { + n = len(b) + } + var nw uint32 + err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil) + if err != nil { + return 0, err + } + uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)] + fd.readuint16 = fd.readuint16[:0] + buf := fd.readbyte[:0] + for i := 0; i < len(uint16s); i++ { + r := rune(uint16s[i]) + if utf16.IsSurrogate(r) { + if i+1 == len(uint16s) { + if nw > 0 { + // Save half surrogate pair for next time. + fd.readuint16 = fd.readuint16[:1] + fd.readuint16[0] = uint16(r) + break + } + r = utf8.RuneError + } else { + r = utf16.DecodeRune(r, rune(uint16s[i+1])) + if r != utf8.RuneError { + i++ + } + } + } + buf = utf8.AppendRune(buf, r) + } + fd.readbyte = buf + fd.readbyteOffset = 0 + if nw == 0 { + break + } + } + + src := fd.readbyte[fd.readbyteOffset:] + var i int + for i = 0; i < len(src) && i < len(b); i++ { + x := src[i] + if x == 0x1A { // Ctrl-Z + if i == 0 { + fd.readbyteOffset++ + } + break + } + b[i] = x + } + fd.readbyteOffset += i + return i, nil +} + +// Pread emulates the Unix pread system call. +func (fd *FD) Pread(b []byte, off int64) (int, error) { + if fd.kind == kindPipe { + // Pread does not work with pipes + return 0, syscall.ESPIPE + } + // Call incref, not readLock, because since pread specifies the + // offset it is independent from other reads. + if err := fd.incref(); err != nil { + return 0, err + } + defer fd.decref() + + if len(b) > maxRW { + b = b[:maxRW] + } + + fd.l.Lock() + defer fd.l.Unlock() + curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) + if e != nil { + return 0, e + } + defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) + o := syscall.Overlapped{ + OffsetHigh: uint32(off >> 32), + Offset: uint32(off), + } + var done uint32 + e = syscall.ReadFile(fd.Sysfd, b, &done, &o) + if e != nil { + done = 0 + if e == syscall.ERROR_HANDLE_EOF { + e = io.EOF + } + } + if len(b) != 0 { + e = fd.eofError(int(done), e) + } + return int(done), e +} + +// ReadFrom wraps the recvfrom network call. +func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) { + if len(buf) == 0 { + return 0, nil, nil + } + if len(buf) > maxRW { + buf = buf[:maxRW] + } + if err := fd.readLock(); err != nil { + return 0, nil, err + } + defer fd.readUnlock() + o := &fd.rop + o.InitBuf(buf) + n, err := execIO(o, func(o *operation) error { + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + o.rsan = int32(unsafe.Sizeof(*o.rsa)) + return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) + }) + err = fd.eofError(n, err) + if err != nil { + return n, nil, err + } + sa, _ := o.rsa.Sockaddr() + return n, sa, nil +} + +// ReadFromInet4 wraps the recvfrom network call for IPv4. +func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) { + if len(buf) == 0 { + return 0, nil + } + if len(buf) > maxRW { + buf = buf[:maxRW] + } + if err := fd.readLock(); err != nil { + return 0, err + } + defer fd.readUnlock() + o := &fd.rop + o.InitBuf(buf) + n, err := execIO(o, func(o *operation) error { + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + o.rsan = int32(unsafe.Sizeof(*o.rsa)) + return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) + }) + err = fd.eofError(n, err) + if err != nil { + return n, err + } + rawToSockaddrInet4(o.rsa, sa4) + return n, err +} + +// ReadFromInet6 wraps the recvfrom network call for IPv6. +func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) { + if len(buf) == 0 { + return 0, nil + } + if len(buf) > maxRW { + buf = buf[:maxRW] + } + if err := fd.readLock(); err != nil { + return 0, err + } + defer fd.readUnlock() + o := &fd.rop + o.InitBuf(buf) + n, err := execIO(o, func(o *operation) error { + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + o.rsan = int32(unsafe.Sizeof(*o.rsa)) + return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) + }) + err = fd.eofError(n, err) + if err != nil { + return n, err + } + rawToSockaddrInet6(o.rsa, sa6) + return n, err +} + +// Write implements io.Writer. +func (fd *FD) Write(buf []byte) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + if fd.isFile { + fd.l.Lock() + defer fd.l.Unlock() + } + + ntotal := 0 + for len(buf) > 0 { + b := buf + if len(b) > maxRW { + b = b[:maxRW] + } + var n int + var err error + if fd.isFile { + switch fd.kind { + case kindConsole: + n, err = fd.writeConsole(b) + default: + n, err = syscall.Write(fd.Sysfd, b) + if fd.kind == kindPipe && err == syscall.ERROR_OPERATION_ABORTED { + // Close uses CancelIoEx to interrupt concurrent I/O for pipes. + // If the fd is a pipe and the Write was interrupted by CancelIoEx, + // we assume it is interrupted by Close. + err = ErrFileClosing + } + } + if err != nil { + n = 0 + } + } else { + if race.Enabled { + race.ReleaseMerge(unsafe.Pointer(&ioSync)) + } + o := &fd.wop + o.InitBuf(b) + n, err = execIO(o, func(o *operation) error { + return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) + }) + } + ntotal += n + if err != nil { + return ntotal, err + } + buf = buf[n:] + } + return ntotal, nil +} + +// writeConsole writes len(b) bytes to the console File. +// It returns the number of bytes written and an error, if any. +func (fd *FD) writeConsole(b []byte) (int, error) { + n := len(b) + runes := make([]rune, 0, 256) + if len(fd.lastbits) > 0 { + b = append(fd.lastbits, b...) + fd.lastbits = nil + + } + for len(b) >= utf8.UTFMax || utf8.FullRune(b) { + r, l := utf8.DecodeRune(b) + runes = append(runes, r) + b = b[l:] + } + if len(b) > 0 { + fd.lastbits = make([]byte, len(b)) + copy(fd.lastbits, b) + } + // syscall.WriteConsole seems to fail, if given large buffer. + // So limit the buffer to 16000 characters. This number was + // discovered by experimenting with syscall.WriteConsole. + const maxWrite = 16000 + for len(runes) > 0 { + m := len(runes) + if m > maxWrite { + m = maxWrite + } + chunk := runes[:m] + runes = runes[m:] + uint16s := utf16.Encode(chunk) + for len(uint16s) > 0 { + var written uint32 + err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil) + if err != nil { + return 0, err + } + uint16s = uint16s[written:] + } + } + return n, nil +} + +// Pwrite emulates the Unix pwrite system call. +func (fd *FD) Pwrite(buf []byte, off int64) (int, error) { + if fd.kind == kindPipe { + // Pwrite does not work with pipes + return 0, syscall.ESPIPE + } + // Call incref, not writeLock, because since pwrite specifies the + // offset it is independent from other writes. + if err := fd.incref(); err != nil { + return 0, err + } + defer fd.decref() + + fd.l.Lock() + defer fd.l.Unlock() + curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) + if e != nil { + return 0, e + } + defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) + + ntotal := 0 + for len(buf) > 0 { + b := buf + if len(b) > maxRW { + b = b[:maxRW] + } + var n uint32 + o := syscall.Overlapped{ + OffsetHigh: uint32(off >> 32), + Offset: uint32(off), + } + e = syscall.WriteFile(fd.Sysfd, b, &n, &o) + ntotal += int(n) + if e != nil { + return ntotal, e + } + buf = buf[n:] + off += int64(n) + } + return ntotal, nil +} + +// Writev emulates the Unix writev system call. +func (fd *FD) Writev(buf *[][]byte) (int64, error) { + if len(*buf) == 0 { + return 0, nil + } + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + if race.Enabled { + race.ReleaseMerge(unsafe.Pointer(&ioSync)) + } + o := &fd.wop + o.InitBufs(buf) + n, err := execIO(o, func(o *operation) error { + return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil) + }) + o.ClearBufs() + TestHookDidWritev(n) + consume(buf, int64(n)) + return int64(n), err +} + +// WriteTo wraps the sendto network call. +func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + + if len(buf) == 0 { + // handle zero-byte payload + o := &fd.wop + o.InitBuf(buf) + o.sa = sa + n, err := execIO(o, func(o *operation) error { + return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) + }) + return n, err + } + + ntotal := 0 + for len(buf) > 0 { + b := buf + if len(b) > maxRW { + b = b[:maxRW] + } + o := &fd.wop + o.InitBuf(b) + o.sa = sa + n, err := execIO(o, func(o *operation) error { + return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) + }) + ntotal += int(n) + if err != nil { + return ntotal, err + } + buf = buf[n:] + } + return ntotal, nil +} + +// WriteToInet4 is WriteTo, specialized for syscall.SockaddrInet4. +func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + + if len(buf) == 0 { + // handle zero-byte payload + o := &fd.wop + o.InitBuf(buf) + n, err := execIO(o, func(o *operation) error { + return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil) + }) + return n, err + } + + ntotal := 0 + for len(buf) > 0 { + b := buf + if len(b) > maxRW { + b = b[:maxRW] + } + o := &fd.wop + o.InitBuf(b) + n, err := execIO(o, func(o *operation) error { + return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil) + }) + ntotal += int(n) + if err != nil { + return ntotal, err + } + buf = buf[n:] + } + return ntotal, nil +} + +// WriteToInet6 is WriteTo, specialized for syscall.SockaddrInet6. +func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + + if len(buf) == 0 { + // handle zero-byte payload + o := &fd.wop + o.InitBuf(buf) + n, err := execIO(o, func(o *operation) error { + return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil) + }) + return n, err + } + + ntotal := 0 + for len(buf) > 0 { + b := buf + if len(b) > maxRW { + b = b[:maxRW] + } + o := &fd.wop + o.InitBuf(b) + n, err := execIO(o, func(o *operation) error { + return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil) + }) + ntotal += int(n) + if err != nil { + return ntotal, err + } + buf = buf[n:] + } + return ntotal, nil +} + +// Call ConnectEx. This doesn't need any locking, since it is only +// called when the descriptor is first created. This is here rather +// than in the net package so that it can use fd.wop. +func (fd *FD) ConnectEx(ra syscall.Sockaddr) error { + o := &fd.wop + o.sa = ra + _, err := execIO(o, func(o *operation) error { + return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o) + }) + return err +} + +func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) { + // Submit accept request. + o.handle = s + o.rsan = int32(unsafe.Sizeof(rawsa[0])) + _, err := execIO(o, func(o *operation) error { + return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o) + }) + if err != nil { + CloseFunc(s) + return "acceptex", err + } + + // Inherit properties of the listening socket. + err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd))) + if err != nil { + CloseFunc(s) + return "setsockopt", err + } + + return "", nil +} + +// Accept handles accepting a socket. The sysSocket parameter is used +// to allocate the net socket. +func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) { + if err := fd.readLock(); err != nil { + return syscall.InvalidHandle, nil, 0, "", err + } + defer fd.readUnlock() + + o := &fd.rop + var rawsa [2]syscall.RawSockaddrAny + for { + s, err := sysSocket() + if err != nil { + return syscall.InvalidHandle, nil, 0, "", err + } + + errcall, err := fd.acceptOne(s, rawsa[:], o) + if err == nil { + return s, rawsa[:], uint32(o.rsan), "", nil + } + + // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is + // returned here. These happen if connection reset is received + // before AcceptEx could complete. These errors relate to new + // connection, not to AcceptEx, so ignore broken connection and + // try AcceptEx again for more connections. + errno, ok := err.(syscall.Errno) + if !ok { + return syscall.InvalidHandle, nil, 0, errcall, err + } + switch errno { + case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET: + // ignore these and try again + default: + return syscall.InvalidHandle, nil, 0, errcall, err + } + } +} + +// Seek wraps syscall.Seek. +func (fd *FD) Seek(offset int64, whence int) (int64, error) { + if fd.kind == kindPipe { + return 0, syscall.ESPIPE + } + if err := fd.incref(); err != nil { + return 0, err + } + defer fd.decref() + + fd.l.Lock() + defer fd.l.Unlock() + + return syscall.Seek(fd.Sysfd, offset, whence) +} + +// Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed. +func (fd *FD) Fchmod(mode uint32) error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + + var d syscall.ByHandleFileInformation + if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil { + return err + } + attrs := d.FileAttributes + if mode&syscall.S_IWRITE != 0 { + attrs &^= syscall.FILE_ATTRIBUTE_READONLY + } else { + attrs |= syscall.FILE_ATTRIBUTE_READONLY + } + if attrs == d.FileAttributes { + return nil + } + + var du windows.FILE_BASIC_INFO + du.FileAttributes = attrs + return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, unsafe.Pointer(&du), uint32(unsafe.Sizeof(du))) +} + +// Fchdir wraps syscall.Fchdir. +func (fd *FD) Fchdir() error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + return syscall.Fchdir(fd.Sysfd) +} + +// GetFileType wraps syscall.GetFileType. +func (fd *FD) GetFileType() (uint32, error) { + if err := fd.incref(); err != nil { + return 0, err + } + defer fd.decref() + return syscall.GetFileType(fd.Sysfd) +} + +// GetFileInformationByHandle wraps GetFileInformationByHandle. +func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + return syscall.GetFileInformationByHandle(fd.Sysfd, data) +} + +// RawRead invokes the user-defined function f for a read operation. +func (fd *FD) RawRead(f func(uintptr) bool) error { + if err := fd.readLock(); err != nil { + return err + } + defer fd.readUnlock() + for { + if f(uintptr(fd.Sysfd)) { + return nil + } + + // Use a zero-byte read as a way to get notified when this + // socket is readable. h/t https://stackoverflow.com/a/42019668/332798 + o := &fd.rop + o.InitBuf(nil) + if !fd.IsStream { + o.flags |= windows.MSG_PEEK + } + _, err := execIO(o, func(o *operation) error { + return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) + }) + if err == windows.WSAEMSGSIZE { + // expected with a 0-byte peek, ignore. + } else if err != nil { + return err + } + } +} + +// RawWrite invokes the user-defined function f for a write operation. +func (fd *FD) RawWrite(f func(uintptr) bool) error { + if err := fd.writeLock(); err != nil { + return err + } + defer fd.writeUnlock() + + if f(uintptr(fd.Sysfd)) { + return nil + } + + // TODO(tmm1): find a way to detect socket writability + return syscall.EWINDOWS +} + +func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 { + *rsa = syscall.RawSockaddrAny{} + raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa)) + raw.Family = syscall.AF_INET + p := (*[2]byte)(unsafe.Pointer(&raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + raw.Addr = sa.Addr + return int32(unsafe.Sizeof(*raw)) +} + +func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 { + *rsa = syscall.RawSockaddrAny{} + raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa)) + raw.Family = syscall.AF_INET6 + p := (*[2]byte)(unsafe.Pointer(&raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + raw.Scope_id = sa.ZoneId + raw.Addr = sa.Addr + return int32(unsafe.Sizeof(*raw)) +} + +func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) { + pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa)) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + sa.Addr = pp.Addr +} + +func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) { + pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa)) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + sa.ZoneId = pp.Scope_id + sa.Addr = pp.Addr +} + +func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) { + switch sa := sa.(type) { + case *syscall.SockaddrInet4: + sz := sockaddrInet4ToRaw(rsa, sa) + return sz, nil + case *syscall.SockaddrInet6: + sz := sockaddrInet6ToRaw(rsa, sa) + return sz, nil + default: + return 0, syscall.EWINDOWS + } +} + +// ReadMsg wraps the WSARecvMsg network call. +func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) { + if err := fd.readLock(); err != nil { + return 0, 0, 0, nil, err + } + defer fd.readUnlock() + + if len(p) > maxRW { + p = p[:maxRW] + } + + o := &fd.rop + o.InitMsg(p, oob) + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) + o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) + o.msg.Flags = uint32(flags) + n, err := execIO(o, func(o *operation) error { + return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil) + }) + err = fd.eofError(n, err) + var sa syscall.Sockaddr + if err == nil { + sa, err = o.rsa.Sockaddr() + } + return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err +} + +// ReadMsgInet4 is ReadMsg, but specialized to return a syscall.SockaddrInet4. +func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) { + if err := fd.readLock(); err != nil { + return 0, 0, 0, err + } + defer fd.readUnlock() + + if len(p) > maxRW { + p = p[:maxRW] + } + + o := &fd.rop + o.InitMsg(p, oob) + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) + o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) + o.msg.Flags = uint32(flags) + n, err := execIO(o, func(o *operation) error { + return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil) + }) + err = fd.eofError(n, err) + if err == nil { + rawToSockaddrInet4(o.rsa, sa4) + } + return n, int(o.msg.Control.Len), int(o.msg.Flags), err +} + +// ReadMsgInet6 is ReadMsg, but specialized to return a syscall.SockaddrInet6. +func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) { + if err := fd.readLock(); err != nil { + return 0, 0, 0, err + } + defer fd.readUnlock() + + if len(p) > maxRW { + p = p[:maxRW] + } + + o := &fd.rop + o.InitMsg(p, oob) + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) + o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) + o.msg.Flags = uint32(flags) + n, err := execIO(o, func(o *operation) error { + return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil) + }) + err = fd.eofError(n, err) + if err == nil { + rawToSockaddrInet6(o.rsa, sa6) + } + return n, int(o.msg.Control.Len), int(o.msg.Flags), err +} + +// WriteMsg wraps the WSASendMsg network call. +func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { + if len(p) > maxRW { + return 0, 0, errors.New("packet is too large (only 1GB is allowed)") + } + + if err := fd.writeLock(); err != nil { + return 0, 0, err + } + defer fd.writeUnlock() + + o := &fd.wop + o.InitMsg(p, oob) + if sa != nil { + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + len, err := sockaddrToRaw(o.rsa, sa) + if err != nil { + return 0, 0, err + } + o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) + o.msg.Namelen = len + } + n, err := execIO(o, func(o *operation) error { + return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) + }) + return n, int(o.msg.Control.Len), err +} + +// WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4. +func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) { + if len(p) > maxRW { + return 0, 0, errors.New("packet is too large (only 1GB is allowed)") + } + + if err := fd.writeLock(); err != nil { + return 0, 0, err + } + defer fd.writeUnlock() + + o := &fd.wop + o.InitMsg(p, oob) + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + len := sockaddrInet4ToRaw(o.rsa, sa) + o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) + o.msg.Namelen = len + n, err := execIO(o, func(o *operation) error { + return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) + }) + return n, int(o.msg.Control.Len), err +} + +// WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6. +func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) { + if len(p) > maxRW { + return 0, 0, errors.New("packet is too large (only 1GB is allowed)") + } + + if err := fd.writeLock(); err != nil { + return 0, 0, err + } + defer fd.writeUnlock() + + o := &fd.wop + o.InitMsg(p, oob) + if o.rsa == nil { + o.rsa = new(syscall.RawSockaddrAny) + } + len := sockaddrInet6ToRaw(o.rsa, sa) + o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) + o.msg.Namelen = len + n, err := execIO(o, func(o *operation) error { + return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) + }) + return n, int(o.msg.Control.Len), err +} diff --git a/contrib/go/_std_1.22/src/internal/poll/file_plan9.go b/contrib/go/_std_1.22/src/internal/poll/file_plan9.go new file mode 100644 index 00000000000..57dc0c668f1 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/file_plan9.go @@ -0,0 +1,42 @@ +// Copyright 2022 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 poll + +// Expose fdMutex for use by the os package on Plan 9. +// On Plan 9 we don't want to use async I/O for file operations, +// but we still want the locking semantics that fdMutex provides. + +// FDMutex is an exported fdMutex, only for Plan 9. +type FDMutex struct { + fdmu fdMutex +} + +func (fdmu *FDMutex) Incref() bool { + return fdmu.fdmu.incref() +} + +func (fdmu *FDMutex) Decref() bool { + return fdmu.fdmu.decref() +} + +func (fdmu *FDMutex) IncrefAndClose() bool { + return fdmu.fdmu.increfAndClose() +} + +func (fdmu *FDMutex) ReadLock() bool { + return fdmu.fdmu.rwlock(true) +} + +func (fdmu *FDMutex) ReadUnlock() bool { + return fdmu.fdmu.rwunlock(true) +} + +func (fdmu *FDMutex) WriteLock() bool { + return fdmu.fdmu.rwlock(false) +} + +func (fdmu *FDMutex) WriteUnlock() bool { + return fdmu.fdmu.rwunlock(false) +} diff --git a/contrib/go/_std_1.22/src/internal/poll/hook_windows.go b/contrib/go/_std_1.22/src/internal/poll/hook_windows.go new file mode 100644 index 00000000000..0bd950ebe46 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/hook_windows.go @@ -0,0 +1,16 @@ +// Copyright 2017 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 poll + +import "syscall" + +// CloseFunc is used to hook the close call. +var CloseFunc func(syscall.Handle) error = syscall.Closesocket + +// AcceptFunc is used to hook the accept call. +var AcceptFunc func(syscall.Handle, syscall.Handle, *byte, uint32, uint32, uint32, *uint32, *syscall.Overlapped) error = syscall.AcceptEx + +// ConnectExFunc is used to hook the ConnectEx call. +var ConnectExFunc func(syscall.Handle, syscall.Sockaddr, *byte, uint32, *uint32, *syscall.Overlapped) error = syscall.ConnectEx diff --git a/contrib/go/_std_1.22/src/internal/poll/iovec_solaris.go b/contrib/go/_std_1.22/src/internal/poll/iovec_solaris.go new file mode 100644 index 00000000000..e68f833d2d5 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/iovec_solaris.go @@ -0,0 +1,14 @@ +// Copyright 2020 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 poll + +import ( + "syscall" + "unsafe" +) + +func newIovecWithBase(base *byte) syscall.Iovec { + return syscall.Iovec{Base: (*int8)(unsafe.Pointer(base))} +} diff --git a/contrib/go/_std_1.22/src/internal/poll/sendfile_solaris.go b/contrib/go/_std_1.22/src/internal/poll/sendfile_solaris.go new file mode 100644 index 00000000000..f9f685c64a6 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/sendfile_solaris.go @@ -0,0 +1,70 @@ +// Copyright 2015 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 poll + +import "syscall" + +// Not strictly needed, but very helpful for debugging, see issue #10221. +// +//go:cgo_import_dynamic _ _ "libsendfile.so" +//go:cgo_import_dynamic _ _ "libsocket.so" + +// maxSendfileSize is the largest chunk size we ask the kernel to copy +// at a time. +const maxSendfileSize int = 4 << 20 + +// SendFile wraps the sendfile system call. +func SendFile(dstFD *FD, src int, pos, remain int64) (int64, error, bool) { + if err := dstFD.writeLock(); err != nil { + return 0, err, false + } + defer dstFD.writeUnlock() + if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil { + return 0, err, false + } + + dst := dstFD.Sysfd + var ( + written int64 + err error + handled = true + ) + for remain > 0 { + n := maxSendfileSize + if int64(n) > remain { + n = int(remain) + } + pos1 := pos + n, err1 := syscall.Sendfile(dst, src, &pos1, n) + if err1 == syscall.EAGAIN || err1 == syscall.EINTR { + // partial write may have occurred + n = int(pos1 - pos) + } + if n > 0 { + pos += int64(n) + written += int64(n) + remain -= int64(n) + } else if n == 0 && err1 == nil { + break + } + if err1 == syscall.EAGAIN { + if err1 = dstFD.pd.waitWrite(dstFD.isFile); err1 == nil { + continue + } + } + if err1 == syscall.EINTR { + continue + } + if err1 != nil { + // This includes syscall.ENOSYS (no kernel + // support) and syscall.EINVAL (fd types which + // don't implement sendfile) + err = err1 + handled = false + break + } + } + return written, err, handled +} diff --git a/contrib/go/_std_1.22/src/internal/poll/sendfile_windows.go b/contrib/go/_std_1.22/src/internal/poll/sendfile_windows.go new file mode 100644 index 00000000000..8c3353bc6ff --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/sendfile_windows.go @@ -0,0 +1,84 @@ +// Copyright 2011 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 poll + +import ( + "io" + "syscall" +) + +// SendFile wraps the TransmitFile call. +func SendFile(fd *FD, src syscall.Handle, n int64) (written int64, err error) { + if fd.kind == kindPipe { + // TransmitFile does not work with pipes + return 0, syscall.ESPIPE + } + if ft, _ := syscall.GetFileType(src); ft == syscall.FILE_TYPE_PIPE { + return 0, syscall.ESPIPE + } + + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + + o := &fd.wop + o.handle = src + + // TODO(brainman): skip calling syscall.Seek if OS allows it + curpos, err := syscall.Seek(o.handle, 0, io.SeekCurrent) + if err != nil { + return 0, err + } + + if n <= 0 { // We don't know the size of the file so infer it. + // Find the number of bytes offset from curpos until the end of the file. + n, err = syscall.Seek(o.handle, -curpos, io.SeekEnd) + if err != nil { + return + } + // Now seek back to the original position. + if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil { + return + } + } + + // TransmitFile can be invoked in one call with at most + // 2,147,483,646 bytes: the maximum value for a 32-bit integer minus 1. + // See https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile + const maxChunkSizePerCall = int64(0x7fffffff - 1) + + for n > 0 { + chunkSize := maxChunkSizePerCall + if chunkSize > n { + chunkSize = n + } + + o.qty = uint32(chunkSize) + o.o.Offset = uint32(curpos) + o.o.OffsetHigh = uint32(curpos >> 32) + + nw, err := execIO(o, func(o *operation) error { + return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND) + }) + if err != nil { + return written, err + } + + curpos += int64(nw) + + // Some versions of Windows (Windows 10 1803) do not set + // file position after TransmitFile completes. + // So just use Seek to set file position. + if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil { + return written, err + } + + n -= int64(nw) + written += int64(nw) + } + + return +} diff --git a/contrib/go/_std_1.22/src/internal/poll/sock_cloexec_accept.go b/contrib/go/_std_1.22/src/internal/poll/sock_cloexec_accept.go new file mode 100644 index 00000000000..4b86de59e09 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/sock_cloexec_accept.go @@ -0,0 +1,51 @@ +// Copyright 2013 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. + +// This file implements accept for platforms that provide a fast path for +// setting SetNonblock and CloseOnExec, but don't necessarily have accept4. +// This is the code we used for accept in Go 1.17 and earlier. +// On Linux the accept4 system call was introduced in 2.6.28 kernel, +// and our minimum requirement is 2.6.32, so we simplified the function. +// Unfortunately, on ARM accept4 wasn't added until 2.6.36, so for ARM +// only we continue using the older code. + +//go:build linux && arm + +package poll + +import "syscall" + +// Wrapper around the accept system call that marks the returned file +// descriptor as nonblocking and close-on-exec. +func accept(s int) (int, syscall.Sockaddr, string, error) { + ns, sa, err := Accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC) + switch err { + case nil: + return ns, sa, "", nil + default: // errors other than the ones listed + return -1, sa, "accept4", err + case syscall.ENOSYS: // syscall missing + case syscall.EINVAL: // some Linux use this instead of ENOSYS + case syscall.EACCES: // some Linux use this instead of ENOSYS + case syscall.EFAULT: // some Linux use this instead of ENOSYS + } + + // See ../syscall/exec_unix.go for description of ForkLock. + // It is probably okay to hold the lock across syscall.Accept + // because we have put fd.sysfd into non-blocking mode. + // However, a call to the File method will put it back into + // blocking mode. We can't take that risk, so no use of ForkLock here. + ns, sa, err = AcceptFunc(s) + if err == nil { + syscall.CloseOnExec(ns) + } + if err != nil { + return -1, nil, "accept", err + } + if err = syscall.SetNonblock(ns, true); err != nil { + CloseFunc(ns) + return -1, nil, "setnonblock", err + } + return ns, sa, "", nil +} diff --git a/contrib/go/_std_1.22/src/internal/poll/sockopt_windows.go b/contrib/go/_std_1.22/src/internal/poll/sockopt_windows.go new file mode 100644 index 00000000000..f32bca4f0fe --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/sockopt_windows.go @@ -0,0 +1,16 @@ +// 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. + +package poll + +import "syscall" + +// WSAIoctl wraps the WSAIoctl network call. +func (fd *FD) WSAIoctl(iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *syscall.Overlapped, completionRoutine uintptr) error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + return syscall.WSAIoctl(fd.Sysfd, iocc, inbuf, cbif, outbuf, cbob, cbbr, overlapped, completionRoutine) +} diff --git a/contrib/go/_std_1.22/src/internal/poll/strconv.go b/contrib/go/_std_1.22/src/internal/poll/strconv.go new file mode 100644 index 00000000000..2b052fa1747 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/poll/strconv.go @@ -0,0 +1,13 @@ +// 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. + +//go:build plan9 + +package poll + +// stringsHasSuffix is strings.HasSuffix. It reports whether s ends in +// suffix. +func stringsHasSuffix(s, suffix string) bool { + return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix +} diff --git a/contrib/go/_std_1.22/src/internal/race/race.go b/contrib/go/_std_1.22/src/internal/race/race.go new file mode 100644 index 00000000000..d2c7e53e418 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/race/race.go @@ -0,0 +1,54 @@ +// Copyright 2015 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. + +//go:build race + +package race + +import ( + "runtime" + "unsafe" +) + +const Enabled = true + +func Acquire(addr unsafe.Pointer) { + runtime.RaceAcquire(addr) +} + +func Release(addr unsafe.Pointer) { + runtime.RaceRelease(addr) +} + +func ReleaseMerge(addr unsafe.Pointer) { + runtime.RaceReleaseMerge(addr) +} + +func Disable() { + runtime.RaceDisable() +} + +func Enable() { + runtime.RaceEnable() +} + +func Read(addr unsafe.Pointer) { + runtime.RaceRead(addr) +} + +func Write(addr unsafe.Pointer) { + runtime.RaceWrite(addr) +} + +func ReadRange(addr unsafe.Pointer, len int) { + runtime.RaceReadRange(addr, len) +} + +func WriteRange(addr unsafe.Pointer, len int) { + runtime.RaceWriteRange(addr, len) +} + +func Errors() int { + return runtime.RaceErrors() +} diff --git a/contrib/go/_std_1.22/src/internal/safefilepath/path_windows.go b/contrib/go/_std_1.22/src/internal/safefilepath/path_windows.go new file mode 100644 index 00000000000..7cfd6ce2eac --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/safefilepath/path_windows.go @@ -0,0 +1,141 @@ +// Copyright 2022 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 safefilepath + +import ( + "syscall" + "unicode/utf8" +) + +func fromFS(path string) (string, error) { + if !utf8.ValidString(path) { + return "", errInvalidPath + } + for len(path) > 1 && path[0] == '/' && path[1] == '/' { + path = path[1:] + } + containsSlash := false + for p := path; p != ""; { + // Find the next path element. + i := 0 + for i < len(p) && p[i] != '/' { + switch p[i] { + case 0, '\\', ':': + return "", errInvalidPath + } + i++ + } + part := p[:i] + if i < len(p) { + containsSlash = true + p = p[i+1:] + } else { + p = "" + } + if IsReservedName(part) { + return "", errInvalidPath + } + } + if containsSlash { + // We can't depend on strings, so substitute \ for / manually. + buf := []byte(path) + for i, b := range buf { + if b == '/' { + buf[i] = '\\' + } + } + path = string(buf) + } + return path, nil +} + +// IsReservedName reports if name is a Windows reserved device name. +// It does not detect names with an extension, which are also reserved on some Windows versions. +// +// For details, search for PRN in +// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file. +func IsReservedName(name string) bool { + // Device names can have arbitrary trailing characters following a dot or colon. + base := name + for i := 0; i < len(base); i++ { + switch base[i] { + case ':', '.': + base = base[:i] + } + } + // Trailing spaces in the last path element are ignored. + for len(base) > 0 && base[len(base)-1] == ' ' { + base = base[:len(base)-1] + } + if !isReservedBaseName(base) { + return false + } + if len(base) == len(name) { + return true + } + // The path element is a reserved name with an extension. + // Some Windows versions consider this a reserved name, + // while others do not. Use FullPath to see if the name is + // reserved. + if p, _ := syscall.FullPath(name); len(p) >= 4 && p[:4] == `\\.\` { + return true + } + return false +} + +func isReservedBaseName(name string) bool { + if len(name) == 3 { + switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) { + case "CON", "PRN", "AUX", "NUL": + return true + } + } + if len(name) >= 4 { + switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) { + case "COM", "LPT": + if len(name) == 4 && '1' <= name[3] && name[3] <= '9' { + return true + } + // Superscript ¹, ², and ³ are considered numbers as well. + switch name[3:] { + case "\u00b2", "\u00b3", "\u00b9": + return true + } + return false + } + } + + // Passing CONIN$ or CONOUT$ to CreateFile opens a console handle. + // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles + // + // While CONIN$ and CONOUT$ aren't documented as being files, + // they behave the same as CON. For example, ./CONIN$ also opens the console input. + if len(name) == 6 && name[5] == '$' && equalFold(name, "CONIN$") { + return true + } + if len(name) == 7 && name[6] == '$' && equalFold(name, "CONOUT$") { + return true + } + return false +} + +func equalFold(a, b string) bool { + if len(a) != len(b) { + return false + } + for i := 0; i < len(a); i++ { + if toUpper(a[i]) != toUpper(b[i]) { + return false + } + } + return true +} + +func toUpper(c byte) byte { + if 'a' <= c && c <= 'z' { + return c - ('a' - 'A') + } + return c +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/execenv/execenv_windows.go b/contrib/go/_std_1.22/src/internal/syscall/execenv/execenv_windows.go new file mode 100644 index 00000000000..2a89ed1f58f --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/execenv/execenv_windows.go @@ -0,0 +1,47 @@ +// Copyright 2020 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. + +//go:build windows + +package execenv + +import ( + "internal/syscall/windows" + "syscall" + "unsafe" +) + +// Default will return the default environment +// variables based on the process attributes +// provided. +// +// If the process attributes contain a token, then +// the environment variables will be sourced from +// the defaults for that user token, otherwise they +// will be sourced from syscall.Environ(). +func Default(sys *syscall.SysProcAttr) (env []string, err error) { + if sys == nil || sys.Token == 0 { + return syscall.Environ(), nil + } + var blockp *uint16 + err = windows.CreateEnvironmentBlock(&blockp, sys.Token, false) + if err != nil { + return nil, err + } + defer windows.DestroyEnvironmentBlock(blockp) + + const size = unsafe.Sizeof(*blockp) + for *blockp != 0 { // environment block ends with empty string + // find NUL terminator + end := unsafe.Add(unsafe.Pointer(blockp), size) + for *(*uint16)(end) != 0 { + end = unsafe.Add(end, size) + } + + entry := unsafe.Slice(blockp, (uintptr(end)-uintptr(unsafe.Pointer(blockp)))/2) + env = append(env, syscall.UTF16ToString(entry)) + blockp = (*uint16)(unsafe.Add(end, size)) + } + return +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/asm_aix_ppc64.s b/contrib/go/_std_1.22/src/internal/syscall/unix/asm_aix_ppc64.s new file mode 100644 index 00000000000..9e82e3eb88b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/asm_aix_ppc64.s @@ -0,0 +1,12 @@ +// Copyright 2018 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 "textflag.h" + +// +// System calls for aix/ppc64 are implemented in syscall/syscall_aix.go +// + +TEXT ·syscall6(SB),NOSPLIT,$0 + JMP syscall·syscall6(SB) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/asm_solaris.s b/contrib/go/_std_1.22/src/internal/syscall/unix/asm_solaris.s new file mode 100644 index 00000000000..20573383158 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/asm_solaris.s @@ -0,0 +1,10 @@ +// Copyright 2018 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 "textflag.h" + +// System calls for Solaris are implemented in runtime/syscall_solaris.go + +TEXT ·syscall6(SB),NOSPLIT,$0-88 + JMP syscall·sysvicall6(SB) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_aix.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_aix.go new file mode 100644 index 00000000000..3fe3285ce21 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_aix.go @@ -0,0 +1,15 @@ +// Copyright 2018 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 unix + +//go:cgo_import_dynamic libc_fstatat fstatat "libc.a/shr_64.o" +//go:cgo_import_dynamic libc_openat openat "libc.a/shr_64.o" +//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.a/shr_64.o" + +const ( + AT_REMOVEDIR = 0x1 + AT_SYMLINK_NOFOLLOW = 0x1 + UTIME_OMIT = -0x3 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_fstatat2.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_fstatat2.go new file mode 100644 index 00000000000..8d20e1a885b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_fstatat2.go @@ -0,0 +1,13 @@ +// Copyright 2022 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. + +//go:build freebsd || (linux && loong64) + +package unix + +import "syscall" + +func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error { + return syscall.Fstatat(dirfd, path, stat, flags) +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_js.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_js.go new file mode 100644 index 00000000000..d05ccce8957 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_js.go @@ -0,0 +1,13 @@ +// Copyright 2020 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 unix + +const ( + // UTIME_OMIT is the sentinel value to indicate that a time value should not + // be changed. It is useful for example to indicate for example with UtimesNano + // to avoid changing AccessTime or ModifiedTime. + // Its value must match syscall/fs_js.go + UTIME_OMIT = -0x2 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_libc.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_libc.go new file mode 100644 index 00000000000..f48d3791e37 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_libc.go @@ -0,0 +1,64 @@ +// Copyright 2018 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. + +//go:build aix || solaris + +package unix + +import ( + "syscall" + "unsafe" +) + +//go:linkname procFstatat libc_fstatat +//go:linkname procOpenat libc_openat +//go:linkname procUnlinkat libc_unlinkat + +var ( + procFstatat, + procOpenat, + procUnlinkat uintptr +) + +func Unlinkat(dirfd int, path string, flags int) error { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + + _, _, errno := syscall6(uintptr(unsafe.Pointer(&procUnlinkat)), 3, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0) + if errno != 0 { + return errno + } + + return nil +} + +func Openat(dirfd int, path string, flags int, perm uint32) (int, error) { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return 0, err + } + + fd, _, errno := syscall6(uintptr(unsafe.Pointer(&procOpenat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags), uintptr(perm), 0, 0) + if errno != 0 { + return 0, errno + } + + return int(fd), nil +} + +func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + + _, _, errno := syscall6(uintptr(unsafe.Pointer(&procFstatat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if errno != 0 { + return errno + } + + return nil +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_solaris.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_solaris.go new file mode 100644 index 00000000000..4ab224d670b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_solaris.go @@ -0,0 +1,21 @@ +// Copyright 2018 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 unix + +import "syscall" + +// Implemented as sysvicall6 in runtime/syscall_solaris.go. +func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) + +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" +//go:cgo_import_dynamic libc_openat openat "libc.so" +//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so" + +const ( + AT_REMOVEDIR = 0x1 + AT_SYMLINK_NOFOLLOW = 0x1000 + + UTIME_OMIT = -0x2 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_dragonfly.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_dragonfly.go new file mode 100644 index 00000000000..9ac1f919f14 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_dragonfly.go @@ -0,0 +1,20 @@ +// Copyright 2018 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 unix + +import "syscall" + +const unlinkatTrap uintptr = syscall.SYS_UNLINKAT +const openatTrap uintptr = syscall.SYS_OPENAT +const fstatatTrap uintptr = syscall.SYS_FSTATAT + +const ( + AT_EACCESS = 0x4 + AT_FDCWD = 0xfffafdcd + AT_REMOVEDIR = 0x2 + AT_SYMLINK_NOFOLLOW = 0x1 + + UTIME_OMIT = -0x1 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_freebsd.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_freebsd.go new file mode 100644 index 00000000000..f74961d5086 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_freebsd.go @@ -0,0 +1,20 @@ +// Copyright 2018 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 unix + +import "syscall" + +const ( + AT_EACCESS = 0x100 + AT_FDCWD = -0x64 + AT_REMOVEDIR = 0x800 + AT_SYMLINK_NOFOLLOW = 0x200 + + UTIME_OMIT = -0x2 + + unlinkatTrap uintptr = syscall.SYS_UNLINKAT + openatTrap uintptr = syscall.SYS_OPENAT + posixFallocateTrap uintptr = syscall.SYS_POSIX_FALLOCATE +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go new file mode 100644 index 00000000000..445b0c38546 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go @@ -0,0 +1,11 @@ +// Copyright 2018 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. + +//go:build arm || mips || mipsle || 386 + +package unix + +import "syscall" + +const fstatatTrap uintptr = syscall.SYS_FSTATAT64 diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_netbsd.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_netbsd.go new file mode 100644 index 00000000000..ffb1d2eaf8b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_netbsd.go @@ -0,0 +1,20 @@ +// Copyright 2018 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 unix + +import "syscall" + +const unlinkatTrap uintptr = syscall.SYS_UNLINKAT +const openatTrap uintptr = syscall.SYS_OPENAT +const fstatatTrap uintptr = syscall.SYS_FSTATAT + +const ( + AT_EACCESS = 0x100 + AT_FDCWD = -0x64 + AT_REMOVEDIR = 0x800 + AT_SYMLINK_NOFOLLOW = 0x200 + + UTIME_OMIT = (1 << 30) - 2 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_openbsd.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_openbsd.go new file mode 100644 index 00000000000..fd389477ec3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_sysnum_openbsd.go @@ -0,0 +1,16 @@ +// Copyright 2018 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 unix + +import "syscall" + +const unlinkatTrap uintptr = syscall.SYS_UNLINKAT +const openatTrap uintptr = syscall.SYS_OPENAT +const fstatatTrap uintptr = syscall.SYS_FSTATAT + +const AT_REMOVEDIR = 0x08 +const AT_SYMLINK_NOFOLLOW = 0x02 + +const UTIME_OMIT = -0x1 diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/at_wasip1.go b/contrib/go/_std_1.22/src/internal/syscall/unix/at_wasip1.go new file mode 100644 index 00000000000..3d47d7ebe0b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/at_wasip1.go @@ -0,0 +1,13 @@ +// Copyright 2020 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 unix + +const ( + // UTIME_OMIT is the sentinel value to indicate that a time value should not + // be changed. It is useful for example to indicate for example with UtimesNano + // to avoid changing AccessTime or ModifiedTime. + // Its value must match syscall/fs_wasip1.go + UTIME_OMIT = -0x2 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/eaccess_bsd.go b/contrib/go/_std_1.22/src/internal/syscall/unix/eaccess_bsd.go new file mode 100644 index 00000000000..3411e3ac40c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/eaccess_bsd.go @@ -0,0 +1,28 @@ +// Copyright 2023 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. + +//go:build dragonfly || freebsd || netbsd + +package unix + +import ( + "syscall" + "unsafe" +) + +func faccessat(dirfd int, path string, mode uint32, flags int) error { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + _, _, errno := syscall.Syscall6(syscall.SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(mode), uintptr(flags), 0, 0) + if errno != 0 { + return errno + } + return err +} + +func Eaccess(path string, mode uint32) error { + return faccessat(AT_FDCWD, path, mode, AT_EACCESS) +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_386.go b/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_386.go new file mode 100644 index 00000000000..535b23dbc5b --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_386.go @@ -0,0 +1,17 @@ +// Copyright 2023 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 unix + +import "syscall" + +func PosixFallocate(fd int, off int64, size int64) error { + // If successful, posix_fallocate() returns zero. It returns an error on failure, without + // setting errno. See https://man.freebsd.org/cgi/man.cgi?query=posix_fallocate&sektion=2&n=1 + r1, _, _ := syscall.Syscall6(posixFallocateTrap, uintptr(fd), uintptr(off), uintptr(off>>32), uintptr(size), uintptr(size>>32), 0) + if r1 != 0 { + return syscall.Errno(r1) + } + return nil +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_64bit.go b/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_64bit.go new file mode 100644 index 00000000000..a9d52283f06 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_64bit.go @@ -0,0 +1,19 @@ +// Copyright 2023 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. + +//go:build freebsd && (amd64 || arm64 || riscv64) + +package unix + +import "syscall" + +func PosixFallocate(fd int, off int64, size int64) error { + // If successful, posix_fallocate() returns zero. It returns an error on failure, without + // setting errno. See https://man.freebsd.org/cgi/man.cgi?query=posix_fallocate&sektion=2&n=1 + r1, _, _ := syscall.Syscall(posixFallocateTrap, uintptr(fd), uintptr(off), uintptr(size)) + if r1 != 0 { + return syscall.Errno(r1) + } + return nil +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_arm.go b/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_arm.go new file mode 100644 index 00000000000..1ded50f3b9a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/fallocate_freebsd_arm.go @@ -0,0 +1,22 @@ +// Copyright 2023 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 unix + +import "syscall" + +func PosixFallocate(fd int, off int64, size int64) error { + // If successful, posix_fallocate() returns zero. It returns an error on failure, without + // setting errno. See https://man.freebsd.org/cgi/man.cgi?query=posix_fallocate&sektion=2&n=1 + // + // The padding 0 argument is needed because the ARM calling convention requires that if an + // argument (off in this case) needs double-word alignment (8-byte), the NCRN (next core + // register number) is rounded up to the next even register number. + // See https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aapcs32/aapcs32.rst#parameter-passing + r1, _, _ := syscall.Syscall6(posixFallocateTrap, uintptr(fd), 0, uintptr(off), uintptr(off>>32), uintptr(size), uintptr(size>>32)) + if r1 != 0 { + return syscall.Errno(r1) + } + return nil +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/fcntl_js.go b/contrib/go/_std_1.22/src/internal/syscall/unix/fcntl_js.go new file mode 100644 index 00000000000..bdfb8e046d3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/fcntl_js.go @@ -0,0 +1,13 @@ +// Copyright 2023 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. + +//go:build js && wasm + +package unix + +import "syscall" + +func Fcntl(fd int, cmd int, arg int) (int, error) { + return 0, syscall.ENOSYS +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/fcntl_wasip1.go b/contrib/go/_std_1.22/src/internal/syscall/unix/fcntl_wasip1.go new file mode 100644 index 00000000000..e70cd74b49c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/fcntl_wasip1.go @@ -0,0 +1,17 @@ +// Copyright 2023 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. + +//go:build wasip1 + +package unix + +import "syscall" + +func Fcntl(fd int, cmd int, arg int) (int, error) { + if cmd == syscall.F_GETFL { + flags, err := fd_fdstat_get_flags(fd) + return int(flags), err + } + return 0, syscall.ENOSYS +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_netbsd.go b/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_netbsd.go new file mode 100644 index 00000000000..02bac1be00c --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_netbsd.go @@ -0,0 +1,38 @@ +// Copyright 2023 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. + +//go:build netbsd + +package unix + +import ( + "syscall" + "unsafe" +) + +const ( + _CTL_KERN = 1 + + _KERN_ARND = 81 +) + +func GetEntropy(p []byte) error { + mib := [2]uint32{_CTL_KERN, _KERN_ARND} + n := uintptr(len(p)) + _, _, errno := syscall.Syscall6( + syscall.SYS___SYSCTL, + uintptr(unsafe.Pointer(&mib[0])), + uintptr(len(mib)), + uintptr(unsafe.Pointer(&p[0])), // olddata + uintptr(unsafe.Pointer(&n)), // &oldlen + uintptr(unsafe.Pointer(nil)), // newdata + 0) // newlen + if errno != 0 { + return syscall.Errno(errno) + } + if n != uintptr(len(p)) { + return syscall.EINVAL + } + return nil +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_openbsd.go b/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_openbsd.go new file mode 100644 index 00000000000..ad0914da903 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_openbsd.go @@ -0,0 +1,17 @@ +// Copyright 2022 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. + +//go:build openbsd && !mips64 + +package unix + +import _ "unsafe" // for linkname + +// GetEntropy calls the OpenBSD getentropy system call. +func GetEntropy(p []byte) error { + return getentropy(p) +} + +//go:linkname getentropy syscall.getentropy +func getentropy(p []byte) error diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_openbsd_mips64.go b/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_openbsd_mips64.go new file mode 100644 index 00000000000..d5caa8095a6 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/getentropy_openbsd_mips64.go @@ -0,0 +1,25 @@ +// Copyright 2016 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 unix + +import ( + "syscall" + "unsafe" +) + +// getentropy(2)'s syscall number, from /usr/src/sys/kern/syscalls.master +const entropyTrap uintptr = 7 + +// GetEntropy calls the OpenBSD getentropy system call. +func GetEntropy(p []byte) error { + _, _, errno := syscall.Syscall(entropyTrap, + uintptr(unsafe.Pointer(&p[0])), + uintptr(len(p)), + 0) + if errno != 0 { + return errno + } + return nil +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_dragonfly.go b/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_dragonfly.go new file mode 100644 index 00000000000..fbf78f9de80 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_dragonfly.go @@ -0,0 +1,16 @@ +// Copyright 2021 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 unix + +// DragonFlyBSD getrandom system call number. +const getrandomTrap uintptr = 550 + +const ( + // GRND_RANDOM is only set for portability purpose, no-op on DragonFlyBSD. + GRND_RANDOM GetRandomFlag = 0x0001 + + // GRND_NONBLOCK means return EAGAIN rather than blocking. + GRND_NONBLOCK GetRandomFlag = 0x0002 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_freebsd.go b/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_freebsd.go new file mode 100644 index 00000000000..8c4f3dff823 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_freebsd.go @@ -0,0 +1,16 @@ +// Copyright 2018 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 unix + +// FreeBSD getrandom system call number. +const getrandomTrap uintptr = 563 + +const ( + // GRND_NONBLOCK means return EAGAIN rather than blocking. + GRND_NONBLOCK GetRandomFlag = 0x0001 + + // GRND_RANDOM is only set for portability purpose, no-op on FreeBSD. + GRND_RANDOM GetRandomFlag = 0x0002 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_solaris.go b/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_solaris.go new file mode 100644 index 00000000000..cf4f35a4198 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/getrandom_solaris.go @@ -0,0 +1,53 @@ +// Copyright 2021 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 unix + +import ( + "sync/atomic" + "syscall" + "unsafe" +) + +//go:cgo_import_dynamic libc_getrandom getrandom "libc.so" + +//go:linkname procGetrandom libc_getrandom + +var procGetrandom uintptr + +var getrandomUnsupported atomic.Bool + +// GetRandomFlag is a flag supported by the getrandom system call. +type GetRandomFlag uintptr + +const ( + // GRND_NONBLOCK means return EAGAIN rather than blocking. + GRND_NONBLOCK GetRandomFlag = 0x0001 + + // GRND_RANDOM means use the /dev/random pool instead of /dev/urandom. + GRND_RANDOM GetRandomFlag = 0x0002 +) + +// GetRandom calls the getrandom system call. +func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + if getrandomUnsupported.Load() { + return 0, syscall.ENOSYS + } + r1, _, errno := syscall6(uintptr(unsafe.Pointer(&procGetrandom)), + 3, + uintptr(unsafe.Pointer(&p[0])), + uintptr(len(p)), + uintptr(flags), + 0, 0, 0) + if errno != 0 { + if errno == syscall.ENOSYS { + getrandomUnsupported.Store(true) + } + return 0, errno + } + return int(r1), nil +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/ioctl_aix.go b/contrib/go/_std_1.22/src/internal/syscall/unix/ioctl_aix.go new file mode 100644 index 00000000000..d361533b5c4 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/ioctl_aix.go @@ -0,0 +1,25 @@ +// Copyright 2018 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 unix + +import ( + "syscall" + "unsafe" +) + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.a/shr_64.o" +//go:linkname libc_ioctl libc_ioctl +var libc_ioctl uintptr + +// Implemented in syscall/syscall_aix.go. +func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) + +func Ioctl(fd int, cmd int, args unsafe.Pointer) (err error) { + _, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_ioctl)), 3, uintptr(fd), uintptr(cmd), uintptr(args), 0, 0, 0) + if e1 != 0 { + err = e1 + } + return +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/net_js.go b/contrib/go/_std_1.22/src/internal/syscall/unix/net_js.go new file mode 100644 index 00000000000..622fc8eb14a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/net_js.go @@ -0,0 +1,44 @@ +// Copyright 2021 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. + +//go:build js + +package unix + +import ( + "syscall" + _ "unsafe" +) + +func RecvfromInet4(fd int, p []byte, flags int, from *syscall.SockaddrInet4) (int, error) { + return 0, syscall.ENOSYS +} + +func RecvfromInet6(fd int, p []byte, flags int, from *syscall.SockaddrInet6) (n int, err error) { + return 0, syscall.ENOSYS +} + +func SendtoInet4(fd int, p []byte, flags int, to *syscall.SockaddrInet4) (err error) { + return syscall.ENOSYS +} + +func SendtoInet6(fd int, p []byte, flags int, to *syscall.SockaddrInet6) (err error) { + return syscall.ENOSYS +} + +func SendmsgNInet4(fd int, p, oob []byte, to *syscall.SockaddrInet4, flags int) (n int, err error) { + return 0, syscall.ENOSYS +} + +func SendmsgNInet6(fd int, p, oob []byte, to *syscall.SockaddrInet6, flags int) (n int, err error) { + return 0, syscall.ENOSYS +} + +func RecvmsgInet4(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet4) (n, oobn int, recvflags int, err error) { + return 0, 0, 0, syscall.ENOSYS +} + +func RecvmsgInet6(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet6) (n, oobn int, recvflags int, err error) { + return 0, 0, 0, syscall.ENOSYS +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/net_wasip1.go b/contrib/go/_std_1.22/src/internal/syscall/unix/net_wasip1.go new file mode 100644 index 00000000000..8a60e8f7a1a --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/net_wasip1.go @@ -0,0 +1,44 @@ +// Copyright 2023 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. + +//go:build wasip1 + +package unix + +import ( + "syscall" + _ "unsafe" +) + +func RecvfromInet4(fd int, p []byte, flags int, from *syscall.SockaddrInet4) (int, error) { + return 0, syscall.ENOSYS +} + +func RecvfromInet6(fd int, p []byte, flags int, from *syscall.SockaddrInet6) (n int, err error) { + return 0, syscall.ENOSYS +} + +func SendtoInet4(fd int, p []byte, flags int, to *syscall.SockaddrInet4) (err error) { + return syscall.ENOSYS +} + +func SendtoInet6(fd int, p []byte, flags int, to *syscall.SockaddrInet6) (err error) { + return syscall.ENOSYS +} + +func SendmsgNInet4(fd int, p, oob []byte, to *syscall.SockaddrInet4, flags int) (n int, err error) { + return 0, syscall.ENOSYS +} + +func SendmsgNInet6(fd int, p, oob []byte, to *syscall.SockaddrInet6, flags int) (n int, err error) { + return 0, syscall.ENOSYS +} + +func RecvmsgInet4(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet4) (n, oobn int, recvflags int, err error) { + return 0, 0, 0, syscall.ENOSYS +} + +func RecvmsgInet6(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet6) (n, oobn int, recvflags int, err error) { + return 0, 0, 0, syscall.ENOSYS +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/nonblocking_js.go b/contrib/go/_std_1.22/src/internal/syscall/unix/nonblocking_js.go new file mode 100644 index 00000000000..cfe78c58d8d --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/nonblocking_js.go @@ -0,0 +1,15 @@ +// Copyright 2018 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. + +//go:build js && wasm + +package unix + +func IsNonblock(fd int) (nonblocking bool, err error) { + return false, nil +} + +func HasNonblockFlag(flag int) bool { + return false +} diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/nonblocking_wasip1.go b/contrib/go/_std_1.22/src/internal/syscall/unix/nonblocking_wasip1.go new file mode 100644 index 00000000000..5b2b53bf5c3 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/nonblocking_wasip1.go @@ -0,0 +1,31 @@ +// Copyright 2023 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. + +//go:build wasip1 + +package unix + +import ( + "syscall" + _ "unsafe" // for go:linkname +) + +func IsNonblock(fd int) (nonblocking bool, err error) { + flags, e1 := fd_fdstat_get_flags(fd) + if e1 != nil { + return false, e1 + } + return flags&syscall.FDFLAG_NONBLOCK != 0, nil +} + +func HasNonblockFlag(flag int) bool { + return flag&syscall.FDFLAG_NONBLOCK != 0 +} + +// This helper is implemented in the syscall package. It means we don't have +// to redefine the fd_fdstat_get host import or the fdstat struct it +// populates. +// +//go:linkname fd_fdstat_get_flags syscall.fd_fdstat_get_flags +func fd_fdstat_get_flags(fd int) (uint32, error) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_386.go b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_386.go new file mode 100644 index 00000000000..9f750a1c03e --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_386.go @@ -0,0 +1,11 @@ +// 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 unix + +const ( + getrandomTrap uintptr = 355 + copyFileRangeTrap uintptr = 377 + pidfdSendSignalTrap uintptr = 424 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_arm.go b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_arm.go new file mode 100644 index 00000000000..c00644b5528 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_arm.go @@ -0,0 +1,11 @@ +// 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 unix + +const ( + getrandomTrap uintptr = 384 + copyFileRangeTrap uintptr = 391 + pidfdSendSignalTrap uintptr = 424 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_mips64x.go b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_mips64x.go new file mode 100644 index 00000000000..6a9e238ce3d --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_mips64x.go @@ -0,0 +1,13 @@ +// Copyright 2015 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. + +//go:build mips64 || mips64le + +package unix + +const ( + getrandomTrap uintptr = 5313 + copyFileRangeTrap uintptr = 5320 + pidfdSendSignalTrap uintptr = 5424 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_mipsx.go b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_mipsx.go new file mode 100644 index 00000000000..22d38f148ed --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_mipsx.go @@ -0,0 +1,13 @@ +// Copyright 2016 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. + +//go:build mips || mipsle + +package unix + +const ( + getrandomTrap uintptr = 4353 + copyFileRangeTrap uintptr = 4360 + pidfdSendSignalTrap uintptr = 4424 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_ppc64x.go b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_ppc64x.go new file mode 100644 index 00000000000..945ec28c2a0 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_ppc64x.go @@ -0,0 +1,13 @@ +// 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. + +//go:build ppc64 || ppc64le + +package unix + +const ( + getrandomTrap uintptr = 359 + copyFileRangeTrap uintptr = 379 + pidfdSendSignalTrap uintptr = 424 +) diff --git a/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_s390x.go b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_s390x.go new file mode 100644 index 00000000000..2c743438201 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/syscall/unix/sysnum_linux_s390x.go @@ -0,0 +1,11 @@ +// Copyright 2016 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 unix + +const ( + getrandomTrap uintptr = 349 + copyFileRangeTrap uintptr = 375 + pidfdSendSignalTrap uintptr = 424 +) diff --git a/contrib/go/_std_1.22/src/internal/types/errors/generrordocs.go b/contrib/go/_std_1.22/src/internal/types/errors/generrordocs.go new file mode 100644 index 00000000000..46343be3ef0 --- /dev/null +++ b/contrib/go/_std_1.22/src/internal/types/errors/generrordocs.go @@ -0,0 +1,117 @@ +//go:build ignore + +// Copyright 2023 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. + +// generrordocs creates a Markdown file for each (compiler) error code +// and its associated documentation. +// Note: this program must be run in this directory. +// go run generrordocs.go <dir> + +//go:generate go run generrordocs.go errors_markdown + +package main + +import ( + "bytes" + "fmt" + "go/ast" + "go/importer" + "go/parser" + "go/token" + "log" + "os" + "path" + "strings" + "text/template" + + . "go/types" +) + +func main() { + if len(os.Args) != 2 { + log.Fatal("missing argument: generrordocs <dir>") + } + outDir := os.Args[1] + if err := os.MkdirAll(outDir, 0755); err != nil { + log.Fatal("unable to create output directory: %s", err) + } + walkCodes(func(name string, vs *ast.ValueSpec) { + // ignore unused errors + if name == "_" { + return + } + // Ensure that < are represented correctly when its included in code + // blocks. The goldmark Markdown parser converts them to &lt; + // when not escaped. It is the only known string with this issue. + desc := strings.ReplaceAll(vs.Doc.Text(), "<", `{{raw "<"}}`) + e := struct { + Name string + Description string + }{ + Name: name, + Description: fmt.Sprintf("```\n%s```\n", desyc), + } + var buf bytes.Buffer + err := template.Must(template.New("eachError").Parse(markdownTemplate)).Execute(&buf, e) + if err != nil { + log.Fatalf("template.Must: %s", err) + } + if err := os.WriteFile(path.Join(outDir, name+".md"), buf.Bytes(), 0660); err != nil { + log.Fatalf("os.WriteFile: %s\n", err) + } + }) + log.Printf("output directory: %s\n", outDir) +} + +func walkCodes(f func(string, *ast.ValueSpec)) { + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, "codes.go", nil, parser.ParseComments) + if err != nil { + log.Fatalf("ParseFile failed: %s", err) + } + conf := Config{Importer: importer.Default()} + info := &Info{ + Types: make(map[ast.Expr]TypeAndValue), + Defs: make(map[*ast.Ident]Object), + Uses: make(map[*ast.Ident]Object), + } + _, err = conf.Check("types", fset, []*ast.File{file}, info) + if err != nil { + log.Fatalf("Check failed: %s", err) + } + for _, decl := range file.Decls { + decl, ok := decl.(*ast.GenDecl) + if !ok || decl.Tok != token.CONST { + continue + } + for _, spec := range decl.Specs { + spec, ok := spec.(*ast.ValueSpec) + if !ok || len(spec.Names) == 0 { + continue + } + obj := info.ObjectOf(spec.Names[0]) + if named, ok := obj.Type().(*Named); ok && named.Obj().Name() == "Code" { + if len(spec.Names) != 1 { + log.Fatalf("bad Code declaration for %q: got %d names, want exactly 1", spec.Names[0].Name, len(spec.Names)) + } + codename := spec.Names[0].Name + f(codename, spec) + } + } + } +} + +const markdownTemplate = `--- +title: {{.Name}} +layout: article +--- +<!-- Copyright 2023 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. --> + +<!-- Code generated by generrordocs.go; DO NOT EDIT. --> + +{{.Description}} +` |
